about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-01-19 08:22:58 +0000
committerbors <bors@rust-lang.org>2015-01-19 08:22:58 +0000
commit135cac852822afe822cc1e4eb9546b96eb2cb35d (patch)
treecc6382f0c7d92c7755151887657ad80a53dd8694
parentbd8a43c668ba93d29e9671c0c8dc6b67428bf492 (diff)
parent3f0cc8011aef3f530663302d525bd2d8cb493db5 (diff)
downloadrust-135cac852822afe822cc1e4eb9546b96eb2cb35d.tar.gz
rust-135cac852822afe822cc1e4eb9546b96eb2cb35d.zip
Auto merge of #21099 - sanxiyn:opt-return-ty, r=alexcrichton
This avoids having ast::Ty nodes which have no counterpart in the source.
-rw-r--r--src/librustc/middle/infer/error_reporting.rs1
-rw-r--r--src/librustc_trans/trans/debuginfo.rs21
-rw-r--r--src/librustc_trans/trans/foreign.rs5
-rw-r--r--src/librustc_typeck/astconv.rs18
-rw-r--r--src/librustc_typeck/collect.rs4
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/html/format.rs1
-rw-r--r--src/libsyntax/ast.rs5
-rw-r--r--src/libsyntax/fold.rs10
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs29
-rw-r--r--src/libsyntax/print/pprust.rs28
-rw-r--r--src/libsyntax/test.rs14
-rw-r--r--src/test/pretty/fn-return.rs17
14 files changed, 76 insertions, 85 deletions
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index bbd12c9671d..1b9d6ec6c33 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -1177,6 +1177,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
             ast::Return(ref ret_ty) => ast::Return(
                 self.rebuild_arg_ty_or_output(&**ret_ty, lifetime, anon_nums, region_names)
             ),
+            ast::DefaultReturn(span) => ast::DefaultReturn(span),
             ast::NoReturn(span) => ast::NoReturn(span)
         }
     }
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index a03a5090c05..ea66b97bbf9 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -1450,18 +1450,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
 
         // Return type -- llvm::DIBuilder wants this at index 0
-        match fn_decl.output {
-            ast::Return(ref ret_ty) if ret_ty.node == ast::TyTup(vec![]) =>
-                signature.push(ptr::null_mut()),
-            _ => {
-                assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
-
-                let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
-                let return_type = monomorphize::apply_param_substs(cx.tcx(),
-                                                                   param_substs,
-                                                                   &return_type);
-                signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
-            }
+        assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
+        let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
+        let return_type = monomorphize::apply_param_substs(cx.tcx(),
+                                                           param_substs,
+                                                           &return_type);
+        if ty::type_is_nil(return_type) {
+            signature.push(ptr::null_mut())
+        } else {
+            signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
         }
 
         // Arguments types
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index abb961d87de..c989d2311be 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -445,9 +445,8 @@ fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) {
         for (input, ty) in decl.inputs.iter().zip(sig.inputs.iter()) {
             check(&*input.ty, *ty)
         }
-        match decl.output {
-            ast::NoReturn(_) => {}
-            ast::Return(ref ty) => check(&**ty, sig.output.unwrap())
+        if let ast::Return(ref ty) = decl.output {
+            check(&**ty, sig.output.unwrap())
         }
     }
 }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index f2927dfd843..c2b34acc6c8 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1359,7 +1359,8 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
                                                               implied_output_region,
                                                               lifetimes_for_params,
                                                               &**output)),
-        ast::NoReturn(_) => ty::FnDiverging
+        ast::DefaultReturn(..) => ty::FnConverging(ty::mk_nil(this.tcx())),
+        ast::NoReturn(..) => ty::FnDiverging
     };
 
     (ty::BareFnTy {
@@ -1486,14 +1487,21 @@ pub fn ty_of_closure<'tcx>(
 
     let expected_ret_ty = expected_sig.map(|e| e.output);
 
+    let is_infer = match decl.output {
+        ast::Return(ref output) if output.node == ast::TyInfer => true,
+        ast::DefaultReturn(..) => true,
+        _ => false
+    };
+
     let output_ty = match decl.output {
-        ast::Return(ref output) if output.node == ast::TyInfer && expected_ret_ty.is_some() =>
+        _ if is_infer && expected_ret_ty.is_some() =>
             expected_ret_ty.unwrap(),
-        ast::Return(ref output) if output.node == ast::TyInfer =>
-            ty::FnConverging(this.ty_infer(output.span)),
+        _ if is_infer =>
+            ty::FnConverging(this.ty_infer(decl.output.span())),
         ast::Return(ref output) =>
             ty::FnConverging(ast_ty_to_ty(this, &rb, &**output)),
-        ast::NoReturn(_) => ty::FnDiverging
+        ast::DefaultReturn(..) => unreachable!(),
+        ast::NoReturn(..) => ty::FnDiverging
     };
 
     debug!("ty_of_closure: input_tys={}", input_tys.repr(this.tcx()));
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index c56952abc44..25ba7ccdbc4 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1488,7 +1488,9 @@ fn ty_of_foreign_fn_decl<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     let output = match decl.output {
         ast::Return(ref ty) =>
             ty::FnConverging(ast_ty_to_ty(ccx, &rb, &**ty)),
-        ast::NoReturn(_) =>
+        ast::DefaultReturn(..) =>
+            ty::FnConverging(ty::mk_nil(ccx.tcx)),
+        ast::NoReturn(..) =>
             ty::FnDiverging
     };
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8dc3adad3b2..7342c9f3e81 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1141,6 +1141,7 @@ impl Clean<Argument> for ast::Arg {
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Show)]
 pub enum FunctionRetTy {
     Return(Type),
+    DefaultReturn,
     NoReturn
 }
 
@@ -1148,7 +1149,8 @@ impl Clean<FunctionRetTy> for ast::FunctionRetTy {
     fn clean(&self, cx: &DocContext) -> FunctionRetTy {
         match *self {
             ast::Return(ref typ) => Return(typ.clean(cx)),
-            ast::NoReturn(_) => NoReturn
+            ast::DefaultReturn(..) => DefaultReturn,
+            ast::NoReturn(..) => NoReturn
         }
     }
 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d13936b2168..57b8d666c95 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -557,6 +557,7 @@ impl fmt::String for clean::FunctionRetTy {
         match *self {
             clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()),
             clean::Return(ref ty) => write!(f, " -&gt; {}", ty),
+            clean::DefaultReturn => Ok(()),
             clean::NoReturn => write!(f, " -&gt; !")
         }
     }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0ea429116b0..fcf80410da2 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1390,6 +1390,10 @@ pub enum FunctionRetTy {
     /// Functions with return type ! that always
     /// raise an error or exit (i.e. never return to the caller)
     NoReturn(Span),
+    /// Return type is not specified. Functions default to () and
+    /// closures default to inference. Span points to where return
+    /// type would be inserted.
+    DefaultReturn(Span),
     /// Everything else
     Return(P<Ty>),
 }
@@ -1398,6 +1402,7 @@ impl FunctionRetTy {
     pub fn span(&self) -> Span {
         match *self {
             NoReturn(span) => span,
+            DefaultReturn(span) => span,
             Return(ref ty) => ty.span
         }
     }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 16c29c9b5eb..f484650ad5b 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -726,6 +726,7 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
         inputs: inputs.move_map(|x| fld.fold_arg(x)),
         output: match output {
             Return(ty) => Return(fld.fold_ty(ty)),
+            DefaultReturn(span) => DefaultReturn(span),
             NoReturn(span) => NoReturn(span)
         },
         variadic: variadic
@@ -1189,14 +1190,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
         attrs: attrs.move_map(|x| folder.fold_attribute(x)),
         node: match node {
             ForeignItemFn(fdec, generics) => {
-                ForeignItemFn(fdec.map(|FnDecl {inputs, output, variadic}| FnDecl {
-                    inputs: inputs.move_map(|a| folder.fold_arg(a)),
-                    output: match output {
-                        Return(ty) => Return(folder.fold_ty(ty)),
-                        NoReturn(span) => NoReturn(span)
-                    },
-                    variadic: variadic
-                }), folder.fold_generics(generics))
+                ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics))
             }
             ForeignItemStatic(t, m) => {
                 ForeignItemStatic(folder.fold_ty(t), m)
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index f1f547ba0c7..90e236dfde3 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -1066,9 +1066,7 @@ mod test {
                                     }),
                                         id: ast::DUMMY_NODE_ID
                                     }),
-                                output: ast::Return(P(ast::Ty{id: ast::DUMMY_NODE_ID,
-                                                  node: ast::TyTup(vec![]),
-                                                  span:sp(15,15)})), // not sure
+                                output: ast::DefaultReturn(sp(15, 15)),
                                 variadic: false
                             }),
                                     ast::Unsafety::Normal,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 130972b4582..b2f6938f513 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -19,7 +19,8 @@ use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
 use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
 use ast::{Crate, CrateConfig, Decl, DeclItem};
-use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
+use ast::{DeclLocal, DefaultBlock, DefaultReturn};
+use ast::{UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
@@ -1426,11 +1427,7 @@ impl<'a> Parser<'a> {
             }
         } else {
             let pos = self.span.lo;
-            Return(P(Ty {
-                id: ast::DUMMY_NODE_ID,
-                node: TyTup(vec![]),
-                span: mk_sp(pos, pos),
-            }))
+            DefaultReturn(mk_sp(pos, pos))
         }
     }
 
@@ -4550,15 +4547,7 @@ impl<'a> Parser<'a> {
                 (optional_unboxed_closure_kind, args)
             }
         };
-        let output = if self.check(&token::RArrow) {
-            self.parse_ret_ty()
-        } else {
-            Return(P(Ty {
-                id: ast::DUMMY_NODE_ID,
-                node: TyInfer,
-                span: self.span,
-            }))
-        };
+        let output = self.parse_ret_ty();
 
         (P(FnDecl {
             inputs: inputs_captures,
@@ -4575,15 +4564,7 @@ impl<'a> Parser<'a> {
                                      seq_sep_trailing_allowed(token::Comma),
                                      |p| p.parse_fn_block_arg());
 
-        let output = if self.check(&token::RArrow) {
-            self.parse_ret_ty()
-        } else {
-            Return(P(Ty {
-                id: ast::DUMMY_NODE_ID,
-                node: TyInfer,
-                span: self.span,
-            }))
-        };
+        let output = self.parse_ret_ty();
 
         P(FnDecl {
             inputs: inputs,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 5d76dc71006..b59e770c6ba 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2351,10 +2351,8 @@ impl<'a> State<'a> {
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, "|"));
 
-        if let ast::Return(ref ty) = decl.output {
-            if ty.node == ast::TyInfer {
-                return self.maybe_print_comment(ty.span.lo);
-            }
+        if let ast::DefaultReturn(..) = decl.output {
+            return Ok(());
         }
 
         try!(self.space_if_not_bol());
@@ -2364,6 +2362,7 @@ impl<'a> State<'a> {
                 try!(self.print_type(&**ty));
                 self.maybe_print_comment(ty.span.lo)
             }
+            ast::DefaultReturn(..) => unreachable!(),
             ast::NoReturn(span) => {
                 try!(self.word_nbsp("!"));
                 self.maybe_print_comment(span.lo)
@@ -2385,10 +2384,8 @@ impl<'a> State<'a> {
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, ")"));
 
-        if let ast::Return(ref ty) = decl.output {
-            if ty.node == ast::TyInfer {
-                return self.maybe_print_comment(ty.span.lo);
-            }
+        if let ast::DefaultReturn(..) = decl.output {
+            return Ok(());
         }
 
         try!(self.space_if_not_bol());
@@ -2398,6 +2395,7 @@ impl<'a> State<'a> {
                 try!(self.print_type(&**ty));
                 self.maybe_print_comment(ty.span.lo)
             }
+            ast::DefaultReturn(..) => unreachable!(),
             ast::NoReturn(span) => {
                 try!(self.word_nbsp("!"));
                 self.maybe_print_comment(span.lo)
@@ -2684,13 +2682,8 @@ impl<'a> State<'a> {
     }
 
     pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
-        if let ast::Return(ref ty) = decl.output {
-            match ty.node {
-                ast::TyTup(ref tys) if tys.is_empty() => {
-                    return self.maybe_print_comment(ty.span.lo);
-                }
-                _ => ()
-            }
+        if let ast::DefaultReturn(..) = decl.output {
+            return Ok(());
         }
 
         try!(self.space_if_not_bol());
@@ -2699,6 +2692,7 @@ impl<'a> State<'a> {
         match decl.output {
             ast::NoReturn(_) =>
                 try!(self.word_nbsp("!")),
+            ast::DefaultReturn(..) => unreachable!(),
             ast::Return(ref ty) =>
                 try!(self.print_type(&**ty))
         }
@@ -3071,9 +3065,7 @@ mod test {
 
         let decl = ast::FnDecl {
             inputs: Vec::new(),
-            output: ast::Return(P(ast::Ty {id: 0,
-                               node: ast::TyTup(vec![]),
-                               span: codemap::DUMMY_SP})),
+            output: ast::DefaultReturn(codemap::DUMMY_SP),
             variadic: false
         };
         let generics = ast_util::empty_generics();
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 895268f96c8..5f869d5093f 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -297,11 +297,8 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
         match &i.node {
           &ast::ItemFn(ref decl, _, _, ref generics, _) => {
             let no_output = match decl.output {
-                ast::Return(ref ret_ty) => match ret_ty.node {
-                    ast::TyTup(ref tys) if tys.is_empty() => true,
-                    _ => false,
-                },
-                ast::NoReturn(_) => false
+                ast::DefaultReturn(..) => true,
+                _ => false
             };
             if decl.inputs.is_empty()
                    && no_output
@@ -336,11 +333,8 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
             ast::ItemFn(ref decl, _, _, ref generics, _) => {
                 let input_cnt = decl.inputs.len();
                 let no_output = match decl.output {
-                    ast::Return(ref ret_ty) => match ret_ty.node {
-                        ast::TyTup(ref tys) if tys.is_empty() => true,
-                        _ => false,
-                    },
-                    ast::NoReturn(_) => false
+                    ast::DefaultReturn(..) => true,
+                    _ => false
                 };
                 let tparm_cnt = generics.ty_params.len();
                 // NB: inadequate check, but we're running
diff --git a/src/test/pretty/fn-return.rs b/src/test/pretty/fn-return.rs
new file mode 100644
index 00000000000..8a223296e54
--- /dev/null
+++ b/src/test/pretty/fn-return.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// pp-exact
+
+// Check that `fn f() -> () { }` does not print as `fn f() { }`.
+
+fn f() -> () { }
+
+fn main() { }