]> git.lizzy.rs Git - rust.git/commitdiff
Complete the removal of ty_nil, ast::LitNil, ast::TyBot and ast::TyUniq
authorJakub Bukaj <jakub@jakub.cc>
Sun, 9 Nov 2014 15:14:15 +0000 (16:14 +0100)
committerJakub Bukaj <jakub@jakub.cc>
Sun, 16 Nov 2014 13:23:15 +0000 (14:23 +0100)
[breaking-change]

This will break any uses of macros that assumed () being a valid literal.

34 files changed:
src/librustc/diagnostics.rs
src/librustc/lint/builtin.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/resolve.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/concat.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/generic/ty.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/test.rs
src/libsyntax/visit.rs

index d5e9c1ef99f111f160310b936b5713de02a886d0..1792599783b2cacfcab0bce2ef2ecea112c9e584 100644 (file)
@@ -66,7 +66,6 @@
     E0055,
     E0056,
     E0057,
-    E0058,
     E0059,
     E0060,
     E0061,
index a5187283de18b1f7026d3348a2ab078bdabcd39a..83194efc554b7143796141b25157cf79f468bb7c 100644 (file)
@@ -447,7 +447,9 @@ fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
             for input in decl.inputs.iter() {
                 check_ty(cx, &*input.ty);
             }
-            check_ty(cx, &*decl.output)
+            if let ast::Return(ref ret_ty) = decl.output {
+                check_ty(cx, &**ret_ty);
+            }
         }
 
         match it.node {
@@ -735,6 +737,7 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
         let t = ty::expr_ty(cx.tcx, expr);
         let mut warned = false;
         match ty::get(t).sty {
+            ty::ty_tup(ref tys) if tys.is_empty() => return,
             ty::ty_bool => return,
             ty::ty_struct(did, _) |
             ty::ty_enum(did, _) => {
index a23889d9cab4e2249fadc876f753b4394b3556e3..3968e6b653429c30c66be9e806dc518d514c1219 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::const_eval::{compare_const_vals, const_bool, const_float, const_nil, const_val};
+use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val};
 use middle::const_eval::{const_expr_to_pat, eval_const_expr, lookup_const_by_id};
 use middle::def::*;
 use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
@@ -332,7 +332,6 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
 fn const_val_to_expr(value: &const_val) -> P<Expr> {
     let node = match value {
         &const_bool(b) => LitBool(b),
-        &const_nil => LitNil,
         _ => unreachable!()
     };
     P(Expr {
@@ -402,7 +401,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
     let pats_len = pats.len();
     let mut pats = pats.into_iter().map(|p| P((*p).clone()));
     let pat = match ty::get(left_ty).sty {
-        ty::ty_tup(ref tys) if !tys.is_empty() => PatTup(pats.collect()),
+        ty::ty_tup(_) => PatTup(pats.collect()),
 
         ty::ty_enum(cid, _) | ty::ty_struct(cid, _)  => {
             let (vid, is_structure) = match ctor {
@@ -497,9 +496,6 @@ fn all_constructors(cx: &MatchCheckCtxt, left_ty: ty::t,
         ty::ty_bool =>
             [true, false].iter().map(|b| ConstantValue(const_bool(*b))).collect(),
 
-        ty::ty_tup(ref tys) if tys.is_empty() =>
-            vec!(ConstantValue(const_nil)),
-
         ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
             ty::ty_vec(_, None) =>
                 range_inclusive(0, max_slice_length).map(|length| Slice(length)).collect(),
index fdda5f1a860e6dce1248bec81427880393582d8a..1fd5b81f49924e1307bf04572007c129a85222e8 100644 (file)
@@ -311,8 +311,7 @@ pub enum const_val {
     const_uint(u64),
     const_str(InternedString),
     const_binary(Rc<Vec<u8> >),
-    const_bool(bool),
-    const_nil
+    const_bool(bool)
 }
 
 pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<Pat> {
@@ -589,7 +588,6 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
         LitFloatUnsuffixed(ref n) => {
             const_float(from_str::<f64>(n.get()).unwrap() as f64)
         }
-        LitNil => const_nil,
         LitBool(b) => const_bool(b)
     }
 }
@@ -605,7 +603,6 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<int> {
         (&const_str(ref a), &const_str(ref b)) => compare_vals(a, b),
         (&const_bool(a), &const_bool(b)) => compare_vals(a, b),
         (&const_binary(ref a), &const_binary(ref b)) => compare_vals(a, b),
-        (&const_nil, &const_nil) => compare_vals((), ()),
         _ => None
     }
 }
index 62d1e13d41f0665071e370fe0490b0291b4b907b..2cfaf8438ae1b776ef86c8a8c2e545a43598c957 100644 (file)
@@ -4285,7 +4285,9 @@ fn resolve_item(&mut self, item: &Item) {
                                     _ => {}
                                 }
 
-                                this.resolve_type(&*ty_m.decl.output);
+                                if let ast::Return(ref ret_ty) = ty_m.decl.output {
+                                    this.resolve_type(&**ret_ty);
+                                }
                             });
                           }
                           ast::ProvidedMethod(ref m) => {
@@ -4467,7 +4469,9 @@ fn resolve_function(&mut self,
                         debug!("(resolving function) recorded argument");
                     }
 
-                    this.resolve_type(&*declaration.output);
+                    if let ast::Return(ref ret_ty) = declaration.output {
+                        this.resolve_type(&**ret_ty);
+                    }
                 }
             }
 
index 59fbcde85e883087fe7643ef211bfcdb9b942923..367fe2845dd14a1cab1266ed1ac4623d16c951fc 100644 (file)
@@ -383,7 +383,11 @@ fn process_method(&mut self, method: &ast::Method) {
         for arg in method.pe_fn_decl().inputs.iter() {
             self.visit_ty(&*arg.ty);
         }
-        self.visit_ty(&*method.pe_fn_decl().output);
+
+        if let ast::Return(ref ret_ty) = method.pe_fn_decl().output {
+            self.visit_ty(&**ret_ty);
+        }
+
         // walk the fn body
         self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
 
@@ -491,7 +495,10 @@ fn process_fn(&mut self,
         for arg in decl.inputs.iter() {
             self.visit_ty(&*arg.ty);
         }
-        self.visit_ty(&*decl.output);
+
+        if let ast::Return(ref ret_ty) = decl.output {
+            self.visit_ty(&**ret_ty);
+        }
 
         // walk the body
         self.nest(item.id, |v| v.visit_block(&*body));
@@ -1136,7 +1143,10 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
                 for arg in method_type.decl.inputs.iter() {
                     self.visit_ty(&*arg.ty);
                 }
-                self.visit_ty(&*method_type.decl.output);
+
+                if let ast::Return(ref ret_ty) = method_type.decl.output {
+                    self.visit_ty(&**ret_ty);
+                }
 
                 self.process_generic_params(&method_type.generics,
                                             method_type.span,
@@ -1352,7 +1362,10 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                 for arg in decl.inputs.iter() {
                     self.visit_ty(&*arg.ty);
                 }
-                self.visit_ty(&*decl.output);
+
+                if let ast::Return(ref ret_ty) = decl.output {
+                    self.visit_ty(&**ret_ty);
+                }
 
                 // walk the body
                 self.nest(ex.id, |v| v.visit_block(&**body));
index 409809e0cb33b006324e2ec9683c7b385c822ff3..330959d687155c3eef301833cb067032eff24a9d 100644 (file)
@@ -81,7 +81,6 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
             }
         }
         ast::LitBool(b) => C_bool(cx, b),
-        ast::LitNil => C_nil(cx),
         ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
         ast::LitBinary(ref data) => C_binary_slice(cx, data.as_slice()),
     }
index be712087e0b658639ca2179d6688e4fe802f29df..42da0573460be72b41580df43366902aeab9bd1b 100644 (file)
@@ -718,7 +718,9 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
     macro_rules! ifn (
         ($name:expr fn() -> $ret:expr) => (
             if *key == $name {
-                let f = base::decl_cdecl_fn(ccx, $name, Type::func([], &$ret), ty::mk_nil(ccx.tcx()));
+                let f = base::decl_cdecl_fn(
+                    ccx, $name, Type::func([], &$ret),
+                    ty::mk_nil(ccx.tcx()));
                 ccx.intrinsics().borrow_mut().insert($name, f.clone());
                 return Some(f);
             }
index be342c8afe9b79a40d66c49c6fd5af34657646e3..f11ca1eec5a2696f17f352817493b8ab5eba7be9 100644 (file)
@@ -1374,10 +1374,9 @@ fn get_function_signature(cx: &CrateContext,
         let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
 
         // Return type -- llvm::DIBuilder wants this at index 0
-        match fn_decl.output.node {
-            ast::TyNil => {
-                signature.push(ptr::null_mut());
-            }
+        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);
 
@@ -1738,6 +1737,8 @@ fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
     debug!("basic_type_metadata: {}", ty::get(t));
 
     let (name, encoding) = match ty::get(t).sty {
+        ty::ty_tup(ref elements) if elements.is_empty() =>
+            ("()".to_string(), DW_ATE_unsigned),
         ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
         ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
         ty::ty_int(int_ty) => match int_ty {
@@ -2888,6 +2889,9 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_float(_) => {
             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
         }
+        ty::ty_tup(ref elements) if elements.is_empty() => {
+            MetadataCreationResult::new(basic_type_metadata(cx, t), false)
+        }
         ty::ty_enum(def_id, _) => {
             prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
         }
@@ -3669,7 +3673,7 @@ fn compute_debuginfo_type_name(cx: &CrateContext,
 fn push_debuginfo_type_name(cx: &CrateContext,
                             t: ty::t,
                             qualified: bool,
-                            output:&mut String) {
+                            output: &mut String) {
     match ty::get(t).sty {
         ty::ty_bool              => output.push_str("bool"),
         ty::ty_char              => output.push_str("char"),
@@ -3697,8 +3701,10 @@ fn push_debuginfo_type_name(cx: &CrateContext,
                 push_debuginfo_type_name(cx, component_type, true, output);
                 output.push_str(", ");
             }
-            output.pop();
-            output.pop();
+            if !component_types.is_empty() {
+                output.pop();
+                output.pop();
+            }
             output.push(')');
         },
         ty::ty_uniq(inner_type) => {
index 1e5b3c9ea7a19f6d1f6d3fe7b632c37c9fb87ca0..97160e7a6d16c2be42fa74d664a09440ffba1418 100644 (file)
@@ -2131,6 +2131,7 @@ pub fn type_is_scalar(ty: t) -> bool {
       ty_bool | ty_char | ty_int(_) | ty_float(_) | ty_uint(_) |
       ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) |
       ty_bare_fn(..) | ty_ptr(_) => true,
+      ty_tup(ref tys) if tys.is_empty() => true,
       _ => false
     }
 }
@@ -3777,6 +3778,7 @@ pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
         ty_uint(_) | ty_float(_) | ty_str => {
             ::util::ppaux::ty_to_string(cx, t)
         }
+        ty_tup(ref tys) if tys.is_empty() => ::util::ppaux::ty_to_string(cx, t),
 
         ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
         ty_uniq(_) => "box".to_string(),
@@ -4771,54 +4773,42 @@ fn fold_sig(&mut self,
 // Returns the repeat count for a repeating vector expression.
 pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
     match const_eval::eval_const_expr_partial(tcx, count_expr) {
-      Ok(ref const_val) => match *const_val {
-        const_eval::const_int(count) => if count < 0 {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count, found negative integer");
-            0
-        } else {
-            count as uint
-        },
-        const_eval::const_uint(count) => count as uint,
-        const_eval::const_float(count) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count, found float");
-            count as uint
-        }
-        const_eval::const_str(_) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count, found string");
-            0
-        }
-        const_eval::const_bool(_) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count, found boolean");
-            0
-        }
-        const_eval::const_binary(_) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count, found binary array");
-            0
-        }
-        const_eval::const_nil => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count, found ()");
-            0
-        }
-      },
-      Err(..) => {
-        tcx.sess.span_err(count_expr.span,
-                          "expected constant integer for repeat count, \
-                           found variable");
-        0
-      }
+        Ok(val) => {
+            let found = match val {
+                const_eval::const_uint(count) => return count as uint,
+                const_eval::const_int(count) if count >= 0 => return count as uint,
+                const_eval::const_int(_) =>
+                    "negative integer",
+                const_eval::const_float(_) =>
+                    "float",
+                const_eval::const_str(_) =>
+                    "string",
+                const_eval::const_bool(_) =>
+                    "boolean",
+                const_eval::const_binary(_) =>
+                    "binary array"
+            };
+            tcx.sess.span_err(count_expr.span, format!(
+                "expected positive integer for repeat count, found {}",
+                found).as_slice());
+        }
+        Err(_) => {
+            let found = match count_expr.node {
+                ast::ExprPath(ast::Path {
+                    global: false,
+                    ref segments,
+                    ..
+                }) if segments.len() == 1 =>
+                    "variable",
+                _ =>
+                    "non-constant expression"
+            };
+            tcx.sess.span_err(count_expr.span, format!(
+                "expected constant integer for repeat count, found {}",
+                found).as_slice());
+        }
     }
+    0
 }
 
 // Iterate over a type parameter's bounded traits and any supertraits
index 9358904a78ce61030b29a4845d75a48c844a765e..8df4d59a292bf7ab1cebeb5dda0a619719feaabe 100644 (file)
@@ -385,7 +385,7 @@ fn parenthesized_parameters<'tcx,AC>(this: &AC,
         let inputs = data.inputs.iter()
                                 .map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
                                 .collect();
-        let input_ty = ty::mk_tup_or_nil(this.tcx(), inputs);
+        let input_ty = ty::mk_tup(this.tcx(), inputs);
 
         let output = match data.output {
             Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty),
@@ -652,12 +652,6 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
     }
 }
 
-#[deriving(Show)]
-enum PointerTy {
-    RPtr(ty::Region),
-    Uniq
-}
-
 // Handle `~`, `Box`, and `&` being able to mean strs and vecs.
 // If a_seq_ty is a str or a vec, make it a str/vec.
 // Also handle first-class trait types.
@@ -666,14 +660,14 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
         rscope: &RS,
         a_seq_mutbl: ast::Mutability,
         a_seq_ty: &ast::Ty,
-        ptr_ty: PointerTy,
+        region: ty::Region,
         constr: |ty::t| -> ty::t)
         -> ty::t
 {
     let tcx = this.tcx();
 
-    debug!("mk_pointer(ptr_ty={}, a_seq_ty={})",
-           ptr_ty,
+    debug!("mk_pointer(region={}, a_seq_ty={})",
+           region,
            a_seq_ty.repr(tcx));
 
     match a_seq_ty.node {
@@ -688,14 +682,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
             match tcx.def_map.borrow().get(&id) {
                 Some(&def::DefPrimTy(ast::TyStr)) => {
                     check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                    match ptr_ty {
-                        Uniq => {
-                            return constr(ty::mk_str(tcx));
-                        }
-                        RPtr(r) => {
-                            return ty::mk_str_slice(tcx, r, a_seq_mutbl);
-                        }
-                    }
+                    return ty::mk_str_slice(tcx, region, a_seq_mutbl);
                 }
                 Some(&def::DefTrait(trait_def_id)) => {
                     let result = ast_path_to_trait_ref(this,
@@ -716,14 +703,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
                     let tr = ty::mk_trait(tcx,
                                           result,
                                           existential_bounds);
-                    return match ptr_ty {
-                        Uniq => {
-                            return ty::mk_uniq(tcx, tr);
-                        }
-                        RPtr(r) => {
-                            return ty::mk_rptr(tcx, r, ty::mt{mutbl: a_seq_mutbl, ty: tr});
-                        }
-                    };
+                    return ty::mk_rptr(tcx, region, ty::mt{mutbl: a_seq_mutbl, ty: tr});
                 }
                 _ => {}
             }
@@ -824,12 +804,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
 
     let typ = ast_ty_to_builtin_ty(this, rscope, ast_ty).unwrap_or_else(|| {
         match ast_ty.node {
-            ast::TyNil => ty::mk_nil(this.tcx()),
-            ast::TyBot => unreachable!(),
-            ast::TyUniq(ref ty) => {
-                mk_pointer(this, rscope, ast::MutImmutable, &**ty, Uniq,
-                           |ty| ty::mk_uniq(tcx, ty))
-            }
             ast::TyVec(ref ty) => {
                 ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None)
             }
@@ -842,7 +816,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
             ast::TyRptr(ref region, ref mt) => {
                 let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
                 debug!("ty_rptr r={}", r.repr(this.tcx()));
-                mk_pointer(this, rscope, mt.mutbl, &*mt.ty, RPtr(r),
+                mk_pointer(this, rscope, mt.mutbl, &*mt.ty, r,
                            |ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl}))
             }
             ast::TyTup(ref fields) => {
@@ -1208,22 +1182,24 @@ fn ty_of_method_or_bare_fn<'tcx, AC: AstConv<'tcx>>(
                                                                    .filter(|&(_, l)| l != 0)
                                                                    .collect();
 
-    let output_ty = match decl.output.node {
-        ast::TyBot => ty::FnDiverging,
-        ast::TyInfer => ty::FnConverging(this.ty_infer(decl.output.span)),
-        _ => ty::FnConverging(match implied_output_region {
-            Some(implied_output_region) => {
-                let rb = SpecificRscope::new(implied_output_region);
-                ast_ty_to_ty(this, &rb, &*decl.output)
-            }
-            None => {
-                // All regions must be explicitly specified in the output
-                // if the lifetime elision rules do not apply. This saves
-                // the user from potentially-confusing errors.
-                let rb = UnelidableRscope::new(param_lifetimes);
-                ast_ty_to_ty(this, &rb, &*decl.output)
-            }
-        })
+    let output_ty = match decl.output {
+        ast::Return(ref output) if output.node == ast::TyInfer =>
+            ty::FnConverging(this.ty_infer(output.span)),
+        ast::Return(ref output) =>
+            ty::FnConverging(match implied_output_region {
+                Some(implied_output_region) => {
+                    let rb = SpecificRscope::new(implied_output_region);
+                    ast_ty_to_ty(this, &rb, &**output)
+                }
+                None => {
+                    // All regions must be explicitly specified in the output
+                    // if the lifetime elision rules do not apply. This saves
+                    // the user from potentially-confusing errors.
+                    let rb = UnelidableRscope::new(param_lifetimes);
+                    ast_ty_to_ty(this, &rb, &**output)
+                }
+            }),
+        ast::NoReturn(_) => ty::FnDiverging
     };
 
     (ty::BareFnTy {
@@ -1346,11 +1322,14 @@ pub fn ty_of_closure<'tcx, AC: AstConv<'tcx>>(
 
     let expected_ret_ty = expected_sig.map(|e| e.output);
 
-    let output_ty = match decl.output.node {
-        ast::TyBot => ty::FnDiverging,
-        ast::TyInfer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(),
-        ast::TyInfer => ty::FnConverging(this.ty_infer(decl.output.span)),
-        _ => ty::FnConverging(ast_ty_to_ty(this, &rb, &*decl.output))
+    let output_ty = match decl.output {
+        ast::Return(ref output) if output.node == ast::TyInfer && 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)),
+        ast::Return(ref output) =>
+            ty::FnConverging(ast_ty_to_ty(this, &rb, &**output)),
+        ast::NoReturn(_) => ty::FnDiverging
     };
 
     ty::ClosureTy {
index bb20475c0cf8bad86dac430cbd55648692e023c8..37fb368b54b4a300bbd79918c4901c8c2833289d 100644 (file)
@@ -556,7 +556,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
         .collect();
 
     if let ty::FnConverging(ret_ty) = ret_ty {
-        fcx.require_type_is_sized(ret_ty, decl.output.span, traits::ReturnType);
+        fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
         fn_sig_tys.push(ret_ty);
     }
 
@@ -2854,7 +2854,6 @@ fn check_lit(fcx: &FnCtxt,
             opt_ty.unwrap_or_else(
                 || ty::mk_float_var(tcx, fcx.infcx().next_float_var_id()))
         }
-        ast::LitNil => ty::mk_nil(tcx),
         ast::LitBool(_) => ty::mk_bool()
     }
 }
@@ -5486,7 +5485,7 @@ fn push_explicit_parenthesized_parameters_from_segment_to_substs(
             data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
 
         let tuple_ty =
-            ty::mk_tup_or_nil(fcx.tcx(), input_tys);
+            ty::mk_tup(fcx.tcx(), input_tys);
 
         if type_count >= 1 {
             substs.types.push(space, tuple_ty);
index 6685bb9be77792aee616f8b2a162adc4c04b71b8..eed574a1a1d7d297378038c85851be635efaa421 100644 (file)
@@ -2096,9 +2096,11 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
                         .map(|a| ty_of_arg(ccx, &rb, a, None))
                         .collect();
 
-    let output = match decl.output.node {
-        ast::TyBot => ty::FnDiverging,
-        _ => ty::FnConverging(ast_ty_to_ty(ccx, &rb, &*decl.output))
+    let output = match decl.output {
+        ast::Return(ref ty) =>
+            ty::FnConverging(ast_ty_to_ty(ccx, &rb, &**ty)),
+        ast::NoReturn(_) =>
+            ty::FnDiverging
     };
 
     let t_fn = ty::mk_bare_fn(
index df25e5009c3e1af64f0e707362590858449b2b1d..078a2c10bcb3514b8adb7c87c8046b32f1bd3c21 100644 (file)
@@ -539,9 +539,11 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres<t
                .map(|(a, b)| this.tys(*a, *b))
                .collect::<Result<_, _>>()
                .map(|ts| ty::mk_tup(tcx, ts))
-        } else {
+        } else if as_.len() != 0 && bs.len() != 0 {
             Err(ty::terr_tuple_size(
                 expected_found(this, as_.len(), bs.len())))
+        } else {
+            Err(ty::terr_sorts(expected_found(this, a, b)))
         }
       }
 
index 80b4948f6fbf26bbc0e48ce3ba6380b67ca1a0a7..e12019a15302ceb545ab543b5cc9faa340d352e1 100644 (file)
@@ -973,8 +973,7 @@ fn rebuild(&self)
                                                    &anon_nums, &region_names);
             inputs = self.rebuild_args_ty(inputs.as_slice(), lifetime,
                                           &anon_nums, &region_names);
-            output = self.rebuild_arg_ty_or_output(&*output, lifetime,
-                                                   &anon_nums, &region_names);
+            output = self.rebuild_output(&output, lifetime, &anon_nums, &region_names);
             ty_params = self.rebuild_ty_params(ty_params, lifetime,
                                                &region_names);
         }
@@ -989,7 +988,6 @@ fn rebuild(&self)
         let new_fn_decl = ast::FnDecl {
             inputs: inputs,
             output: output,
-            cf: self.fn_decl.cf,
             variadic: self.fn_decl.variadic
         };
         (new_fn_decl, expl_self_opt, generics)
@@ -1206,6 +1204,18 @@ fn rebuild_args_ty(&self,
         new_inputs
     }
 
+    fn rebuild_output(&self, ty: &ast::FunctionRetTy,
+                      lifetime: ast::Lifetime,
+                      anon_nums: &HashSet<uint>,
+                      region_names: &HashSet<ast::Name>) -> ast::FunctionRetTy {
+        match *ty {
+            ast::Return(ref ret_ty) => ast::Return(
+                self.rebuild_arg_ty_or_output(&**ret_ty, lifetime, anon_nums, region_names)
+            ),
+            ast::NoReturn(span) => ast::NoReturn(span)
+        }
+    }
+
     fn rebuild_arg_ty_or_output(&self,
                                 ty: &ast::Ty,
                                 lifetime: ast::Lifetime,
@@ -1301,7 +1311,6 @@ fn rebuild_arg_ty_or_output(&self,
                     ty_queue.push(&*mut_ty.ty);
                 }
                 ast::TyVec(ref ty) |
-                ast::TyUniq(ref ty) |
                 ast::TyFixedLengthVec(ref ty, _) => {
                     ty_queue.push(&**ty);
                 }
@@ -1338,7 +1347,6 @@ fn build_to(from: P<ast::Ty>,
                         })
                     }
                     ast::TyVec(ty) => ast::TyVec(build_to(ty, to)),
-                    ast::TyUniq(ty) => ast::TyUniq(build_to(ty, to)),
                     ast::TyFixedLengthVec(ty, e) => {
                         ast::TyFixedLengthVec(build_to(ty, to), e)
                     }
index 38e0c4fe040bdd042422e2fe72c162892217f59f..a608fba80e3098666b712aaa05e3e7497162bc63 100644 (file)
@@ -710,8 +710,7 @@ fn clean(&self, cx: &DocContext) -> Item {
             inputs: Arguments {
                 values: inputs.iter().map(|x| x.clean(cx)).collect(),
             },
-            output: (self.pe_fn_decl().output.clean(cx)),
-            cf: self.pe_fn_decl().cf.clean(cx),
+            output: self.pe_fn_decl().output.clean(cx),
             attrs: Vec::new()
         };
         Item {
@@ -749,8 +748,7 @@ fn clean(&self, cx: &DocContext) -> Item {
             inputs: Arguments {
                 values: inputs.iter().map(|x| x.clean(cx)).collect(),
             },
-            output: (self.decl.output.clean(cx)),
-            cf: self.decl.cf.clean(cx),
+            output: self.decl.output.clean(cx),
             attrs: Vec::new()
         };
         Item {
@@ -840,8 +838,7 @@ fn clean(&self, cx: &DocContext) -> ClosureDecl {
 #[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct FnDecl {
     pub inputs: Arguments,
-    pub output: Type,
-    pub cf: RetStyle,
+    pub output: FunctionRetTy,
     pub attrs: Vec<Attribute>,
 }
 
@@ -857,7 +854,6 @@ fn clean(&self, cx: &DocContext) -> FnDecl {
                 values: self.inputs.clean(cx),
             },
             output: self.output.clean(cx),
-            cf: self.cf.clean(cx),
             attrs: Vec::new()
         }
     }
@@ -884,8 +880,7 @@ fn clean(&self, cx: &DocContext) -> FnDecl {
             let _ = names.next();
         }
         FnDecl {
-            output: sig.output.clean(cx),
-            cf: Return,
+            output: Return(sig.output.clean(cx)),
             attrs: Vec::new(),
             inputs: Arguments {
                 values: sig.inputs.iter().map(|t| {
@@ -918,16 +913,16 @@ fn clean(&self, cx: &DocContext) -> Argument {
 }
 
 #[deriving(Clone, Encodable, Decodable, PartialEq)]
-pub enum RetStyle {
-    NoReturn,
-    Return
+pub enum FunctionRetTy {
+    Return(Type),
+    NoReturn
 }
 
-impl Clean<RetStyle> for ast::RetStyle {
-    fn clean(&self, _: &DocContext) -> RetStyle {
+impl Clean<FunctionRetTy> for ast::FunctionRetTy {
+    fn clean(&self, cx: &DocContext) -> FunctionRetTy {
         match *self {
-            ast::Return => Return,
-            ast::NoReturn => NoReturn
+            ast::Return(ref typ) => Return(typ.clean(cx)),
+            ast::NoReturn(_) => NoReturn
         }
     }
 }
@@ -1124,7 +1119,6 @@ pub enum PrimitiveType {
     F32, F64,
     Char,
     Bool,
-    Unit,
     Str,
     Slice,
     PrimitiveTuple,
@@ -1156,7 +1150,6 @@ fn from_str(s: &str) -> Option<PrimitiveType> {
             "u32" => Some(U32),
             "u64" => Some(U64),
             "bool" => Some(Bool),
-            "unit" => Some(Unit),
             "char" => Some(Char),
             "str" => Some(Str),
             "f32" => Some(F32),
@@ -1205,17 +1198,13 @@ pub fn to_string(&self) -> &'static str {
             Str => "str",
             Bool => "bool",
             Char => "char",
-            Unit => "()",
             Slice => "slice",
             PrimitiveTuple => "tuple",
         }
     }
 
     pub fn to_url_str(&self) -> &'static str {
-        match *self {
-            Unit => "unit",
-            other => other.to_string(),
-        }
+        self.to_string()
     }
 
     /// Creates a rustdoc-specific node id for primitive types.
@@ -1230,12 +1219,10 @@ impl Clean<Type> for ast::Ty {
     fn clean(&self, cx: &DocContext) -> Type {
         use syntax::ast::*;
         match self.node {
-            TyNil => Primitive(Unit),
             TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)),
             TyRptr(ref l, ref m) =>
                 BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
                              type_: box m.ty.clean(cx)},
-            TyUniq(ref ty) => Unique(box ty.clean(cx)),
             TyVec(ref ty) => Vector(box ty.clean(cx)),
             TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx),
                                                            e.span.to_src(cx)),
@@ -1247,7 +1234,6 @@ fn clean(&self, cx: &DocContext) -> Type {
             TyProc(ref c) => Proc(box c.clean(cx)),
             TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
             TyParen(ref ty) => ty.clean(cx),
-            TyBot => Bottom,
             ref x => panic!("Unimplemented type {}", x),
         }
     }
@@ -1256,7 +1242,6 @@ fn clean(&self, cx: &DocContext) -> Type {
 impl Clean<Type> for ty::t {
     fn clean(&self, cx: &DocContext) -> Type {
         match ty::get(*self).sty {
-            ty::ty_nil => Primitive(Unit),
             ty::ty_bool => Primitive(Bool),
             ty::ty_char => Primitive(Char),
             ty::ty_int(ast::TyI) => Primitive(Int),
@@ -1342,7 +1327,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                 }
             }
 
-            ty::ty_unboxed_closure(..) => Primitive(Unit), // FIXME(pcwalton)
+            ty::ty_unboxed_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
 
             ty::ty_infer(..) => panic!("ty_infer"),
             ty::ty_open(..) => panic!("ty_open"),
@@ -2041,7 +2026,6 @@ fn lit_to_string(lit: &ast::Lit) -> String {
         ast::LitFloat(ref f, _t) => f.get().to_string(),
         ast::LitFloatUnsuffixed(ref f) => f.get().to_string(),
         ast::LitBool(b) => b.to_string(),
-        ast::LitNil => "".to_string(),
     }
 }
 
index fe96c9b3a9f6a07b090d20a97d20fd0851c9d60b..a7f33151547564a342927aa4edcdabe386af0208 100644 (file)
@@ -393,10 +393,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                            format!("&lt;{:#}&gt;", decl.lifetimes)
                        },
                        args = decl.decl.inputs,
-                       arrow = match decl.decl.output {
-                           clean::Primitive(clean::Unit) => "".to_string(),
-                           _ => format!(" -&gt; {}", decl.decl.output),
-                       },
+                       arrow = decl.decl.output,
                        bounds = {
                            let mut ret = String::new();
                            for bound in decl.bounds.iter() {
@@ -435,10 +432,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                                ": {}",
                                m.collect::<Vec<String>>().connect(" + "))
                        },
-                       arrow = match decl.decl.output {
-                           clean::Primitive(clean::Unit) => "".to_string(),
-                           _ => format!(" -&gt; {}", decl.decl.output)
-                       })
+                       arrow = decl.decl.output)
             }
             clean::BareFunction(ref decl) => {
                 write!(f, "{}{}fn{}{}",
@@ -514,14 +508,19 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl fmt::Show for clean::FunctionRetTy {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()),
+            clean::Return(ref ty) => write!(f, " -&gt; {}", ty),
+            clean::NoReturn => write!(f, " -&gt; !")
+        }
+    }
+}
+
 impl fmt::Show for clean::FnDecl {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({args}){arrow}",
-               args = self.inputs,
-               arrow = match self.output {
-                   clean::Primitive(clean::Unit) => "".to_string(),
-                   _ => format!(" -&gt; {}", self.output),
-               })
+        write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output)
     }
 }
 
@@ -551,12 +550,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
             args.push_str(format!("{}", input.type_).as_slice());
         }
-        write!(f, "({args}){arrow}",
-               args = args,
-               arrow = match d.output {
-                   clean::Primitive(clean::Unit) => "".to_string(),
-                   _ => format!(" -&gt; {}", d.output),
-               })
+        write!(f, "({args}){arrow}", args = args, arrow = d.output)
     }
 }
 
index 7c5de627d0807ec139c306f8b986539268243556..0e1921a07734b4a960f87fba96c72618859d102e 100644 (file)
@@ -893,7 +893,6 @@ pub enum Lit_ {
     LitInt(u64, LitIntType),
     LitFloat(InternedString, FloatTy),
     LitFloatUnsuffixed(InternedString),
-    LitNil,
     LitBool(bool),
 }
 
@@ -1086,12 +1085,6 @@ pub struct BareFnTy {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 /// The different kinds of types recognized by the compiler
 pub enum Ty_ {
-    /// The unit type (`()`)
-    TyNil,
-    /// The bottom type (`!`)
-    TyBot,
-    TyUniq(P<Ty>),
-    /// An array (`[T]`)
     TyVec(P<Ty>),
     /// A fixed length array (`[T, ..n]`)
     TyFixedLengthVec(P<Ty>, P<Expr>),
@@ -1175,8 +1168,7 @@ pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct FnDecl {
     pub inputs: Vec<Arg>,
-    pub output: P<Ty>,
-    pub cf: RetStyle,
+    pub output: FunctionRetTy,
     pub variadic: bool
 }
 
@@ -1198,12 +1190,21 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
-pub enum RetStyle {
+pub enum FunctionRetTy {
     /// Functions with return type ! that always
     /// raise an error or exit (i.e. never return to the caller)
-    NoReturn,
+    NoReturn(Span),
     /// Everything else
-    Return,
+    Return(P<Ty>),
+}
+
+impl FunctionRetTy {
+    pub fn span(&self) -> Span {
+        match *self {
+            NoReturn(span) => span,
+            Return(ref ty) => ty.span
+        }
+    }
 }
 
 /// Represents the kind of 'self' associated with a method
index 1e2d935af00684986de2ad45a2f52abdf2944253..0c7a3cf4a6ce3f4b2efe92e62c07058073ca9f63 100644 (file)
@@ -248,7 +248,7 @@ pub fn expr(sp: Span) -> Box<MacResult+'static> {
     pub fn raw_expr(sp: Span) -> P<ast::Expr> {
         P(ast::Expr {
             id: ast::DUMMY_NODE_ID,
-            node: ast::ExprLit(P(codemap::respan(sp, ast::LitNil))),
+            node: ast::ExprLit(P(codemap::respan(sp, ast::LitBool(false)))),
             span: sp,
         })
     }
index 862cbf3d7ca06f3506bf0f33602e8e3055f24048..ffc42b6703384667e032ed6efe1400e74eb46f9a 100644 (file)
@@ -54,11 +54,9 @@ fn ty_rptr(&self, span: Span,
     fn ty_ptr(&self, span: Span,
               ty: P<ast::Ty>,
               mutbl: ast::Mutability) -> P<ast::Ty>;
-    fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>;
 
     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
-    fn ty_nil(&self) -> P<ast::Ty>;
 
     fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
     fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
@@ -377,9 +375,6 @@ fn ty_ptr(&self,
         self.ty(span,
                 ast::TyPtr(self.ty_mt(ty, mutbl)))
     }
-    fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> {
-        self.ty(span, ast::TyUniq(ty))
-    }
 
     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
         self.ty_path(
@@ -406,14 +401,6 @@ fn ty_infer(&self, span: Span) -> P<ast::Ty> {
         self.ty(span, ast::TyInfer)
     }
 
-    fn ty_nil(&self) -> P<ast::Ty> {
-        P(ast::Ty {
-            id: ast::DUMMY_NODE_ID,
-            node: ast::TyNil,
-            span: DUMMY_SP,
-        })
-    }
-
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
@@ -809,8 +796,7 @@ fn pat_struct(&self, span: Span,
         self.pat(span, pat)
     }
     fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
-        let pat = ast::PatTup(pats);
-        self.pat(span, pat)
+        self.pat(span, ast::PatTup(pats))
     }
 
     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
@@ -931,11 +917,10 @@ fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
     }
 
     // FIXME unused self
-    fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl> {
+    fn fn_decl(&self, inputs: Vec<ast::Arg>, output: P<ast::Ty>) -> P<ast::FnDecl> {
         P(ast::FnDecl {
             inputs: inputs,
-            output: output,
-            cf: ast::Return,
+            output: ast::Return(output),
             variadic: false
         })
     }
index af7cd4157ecbc75fe67a037a182cdc916a8bfba2..e2867c2fbabfa9fb67d2531727120940fb6e5365 100644 (file)
@@ -46,7 +46,6 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
                     ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
                         accumulator.push_str(format!("-{}", i).as_slice());
                     }
-                    ast::LitNil => {}
                     ast::LitBool(b) => {
                         accumulator.push_str(format!("{}", b).as_slice());
                     }
index 69eb260b8c4cc0626ca8518d1180cb9e0e7ddc81..62f3b5d01b41a2053da0a00e03364025571de532 100644 (file)
@@ -88,7 +88,7 @@
 //! }
 //! ```
 
-use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
+use ast::{MetaItem, Item, Expr, ExprRet, MutMutable};
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -186,7 +186,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             if stmts.is_empty() {
                 let ret_ok = cx.expr(trait_span,
                                      ExprRet(Some(cx.expr_ok(trait_span,
-                                                             cx.expr_lit(trait_span, LitNil)))));
+                                                             cx.expr_tuple(trait_span, vec![])))));
                 stmts.push(cx.stmt_expr(ret_ok));
             }
 
@@ -231,7 +231,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             if stmts.len() == 0 {
                 let ret_ok = cx.expr(trait_span,
                                      ExprRet(Some(cx.expr_ok(trait_span,
-                                                             cx.expr_lit(trait_span, LitNil)))));
+                                                             cx.expr_tuple(trait_span, vec![])))));
                 stmts.push(cx.stmt_expr(ret_ok));
             }
 
index 7c32b84550893a5813916a555a97539d00409ab2..4be299994fd2110d5f7aacf1f63f7363fdac49bc 100644 (file)
@@ -922,7 +922,7 @@ fn build_enum_match_tuple(
                 }
 
                 // Here is the pat = `(&VariantK, &VariantK, ...)`
-                let single_pat = cx.pat(sp, ast::PatTup(subpats));
+                let single_pat = cx.pat_tuple(sp, subpats);
 
                 // For the BodyK, we need to delegate to our caller,
                 // passing it an EnumMatching to indicate which case
index 1ec1e3b1224c4d3d7cad2637d7445bb9adf8a160..8b46769d633f3c05c745418cdf38ae5f7e8f6eed 100644 (file)
@@ -152,14 +152,9 @@ pub fn to_ty(&self,
                 cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
             }
             Tuple(ref fields) => {
-                let ty = if fields.is_empty() {
-                    ast::TyNil
-                } else {
-                    ast::TyTup(fields.iter()
-                                     .map(|f| f.to_ty(cx, span, self_ty, self_generics))
-                                     .collect())
-                };
-
+                let ty = ast::TyTup(fields.iter()
+                    .map(|f| f.to_ty(cx, span, self_ty, self_generics))
+                    .collect());
                 cx.ty(span, ty)
             }
         }
index 87406081aae97123dce8c23eaecb69404cac1007..fa69495fa42aae0b2dca2e89e0be529114b76da5 100644 (file)
@@ -159,7 +159,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             // `_ => [<elseopt> | ()]`
             let else_arm = {
                 let pat_under = fld.cx.pat_wild(span);
-                let else_expr = elseopt.unwrap_or_else(|| fld.cx.expr_lit(span, ast::LitNil));
+                let else_expr = elseopt.unwrap_or_else(|| fld.cx.expr_tuple(span, vec![]));
                 fld.cx.arm(span, vec![pat_under], else_expr)
             };
 
index a28f24e76635d283235d3de2f4b30f52fd70b6db..a816b4796304646a1a653564185a8cdd8d4913e4 100644 (file)
@@ -654,7 +654,7 @@ fn to_expr(mut self, invocation: Invocation) -> P<ast::Expr> {
         //
         // But the nested match expression is proved to perform not as well
         // as series of let's; the first approach does.
-        let pat = self.ecx.pat(self.fmtsp, ast::PatTup(pats));
+        let pat = self.ecx.pat_tuple(self.fmtsp, pats);
         let arm = self.ecx.arm(self.fmtsp, vec!(pat), body);
         let head = self.ecx.expr(self.fmtsp, ast::ExprTup(heads));
         self.ecx.expr_match(self.fmtsp, head, vec!(arm))
index d7c3ca8efc45702595ddc327ce53be86fa2b9dd6..56d912824374d7ae025fab3c1e42ea375d732755 100644 (file)
@@ -391,8 +391,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
     t.map(|Ty {id, node, span}| Ty {
         id: fld.new_id(id),
         node: match node {
-            TyNil | TyBot | TyInfer => node,
-            TyUniq(ty) => TyUniq(fld.fold_ty(ty)),
+            TyInfer => node,
             TyVec(ty) => TyVec(fld.fold_ty(ty)),
             TyPtr(mt) => TyPtr(fld.fold_mt(mt)),
             TyRptr(region, mt) => {
@@ -706,10 +705,12 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
 }
 
 pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
-    decl.map(|FnDecl {inputs, output, cf, variadic}| FnDecl {
+    decl.map(|FnDecl {inputs, output, variadic}| FnDecl {
         inputs: inputs.move_map(|x| fld.fold_arg(x)),
-        output: fld.fold_ty(output),
-        cf: cf,
+        output: match output {
+            Return(ty) => Return(fld.fold_ty(ty)),
+            NoReturn(span) => NoReturn(span)
+        },
         variadic: variadic
     })
 }
@@ -1146,10 +1147,12 @@ 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, cf, variadic}| FnDecl {
+                ForeignItemFn(fdec.map(|FnDecl {inputs, output, variadic}| FnDecl {
                     inputs: inputs.move_map(|a| folder.fold_arg(a)),
-                    output: folder.fold_ty(output),
-                    cf: cf,
+                    output: match output {
+                        Return(ty) => Return(folder.fold_ty(ty)),
+                        NoReturn(span) => NoReturn(span)
+                    },
                     variadic: variadic
                 }), folder.fold_generics(generics))
             }
index 4881be8996a8b5b8c892c465c48c3802c36d068b..fa10cb90f83a934be1f1bda24acb3cab646a0743 100644 (file)
@@ -24,7 +24,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![allow(unknown_features)]
-#![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)]
+#![feature(if_let, macro_rules, globs, default_type_params, phase, slicing_syntax)]
 #![feature(quote, struct_variant, unsafe_destructor, import_shadowing)]
 
 extern crate arena;
index 51738ece80f53a220ef1355b173bdaa551e639a2..2810db4eaddd8ee493793b05dab0aaacb45bb343 100644 (file)
@@ -1037,10 +1037,9 @@ fn parser_done(p: Parser){
                                     }),
                                         id: ast::DUMMY_NODE_ID
                                     }),
-                                output: P(ast::Ty{id: ast::DUMMY_NODE_ID,
-                                                  node: ast::TyNil,
-                                                  span:sp(15,15)}), // not sure
-                                cf: ast::Return,
+                                output: ast::Return(P(ast::Ty{id: ast::DUMMY_NODE_ID,
+                                                  node: ast::TyTup(vec![]),
+                                                  span:sp(15,15)})), // not sure
                                 variadic: false
                             }),
                                     ast::NormalFn,
index 73787763c8b58a7e9f8a1e153c60dbccf25de7e7..1b2ab3c235d5f59bdb17fdf697f1b9c09bde5fc9 100644 (file)
@@ -17,8 +17,8 @@
 removed.
 */
 
-use ast::{Expr, ExprLit, LitNil};
-use codemap::{Span, respan};
+use ast::{Expr, ExprTup};
+use codemap::Span;
 use parse::parser;
 use parse::token;
 use ptr::P;
@@ -96,7 +96,7 @@ fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
     /// a placeholder expression
     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr> {
         self.obsolete(sp, kind);
-        self.mk_expr(sp.lo, sp.hi, ExprLit(P(respan(sp, LitNil))))
+        self.mk_expr(sp.lo, sp.hi, ExprTup(vec![]))
     }
 
     fn report(&mut self,
index db10dc1bc90ca18501817e64ad59059344ee0444..4f487a10e9867c97baea0641faae98d028438abd 100644 (file)
 use ast::{Once, Many};
 use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
 use ast::{FnOnceUnboxedClosureKind};
-use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
+use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
 use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
-use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
+use ast::{LitStr, LitInt, Local, LocalLet};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchNormal};
 use ast::{Method, MutTy, BiMul, Mutability};
 use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
 use ast::{PolyTraitRef};
 use ast::{QPath, RequiredMethod};
-use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
+use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
 use ast::{TtDelimited, TtSequence, TtToken};
-use ast::{TupleVariantKind, Ty, Ty_, TyBot};
+use ast::{TupleVariantKind, Ty, Ty_};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
-use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
-use ast::{TyRptr, TyTup, TyU32, TyUniq, TyVec, UnUniq};
+use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
+use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
 use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
 use ast::{UnnamedField, UnsafeBlock};
 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
@@ -1066,11 +1066,10 @@ pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_
         self.expect_keyword(keywords::Fn);
         let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs);
         let (inputs, variadic) = self.parse_fn_args(false, true);
-        let (ret_style, ret_ty) = self.parse_ret_ty();
+        let ret_ty = self.parse_ret_ty();
         let decl = P(FnDecl {
             inputs: inputs,
             output: ret_ty,
-            cf: ret_style,
             variadic: variadic
         });
         TyBareFn(P(BareFnTy {
@@ -1100,11 +1099,10 @@ pub fn parse_proc_type(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_ {
         let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs);
         let (inputs, variadic) = self.parse_fn_args(false, false);
         let bounds = self.parse_colon_then_ty_param_bounds();
-        let (ret_style, ret_ty) = self.parse_ret_ty();
+        let ret_ty = self.parse_ret_ty();
         let decl = P(FnDecl {
             inputs: inputs,
             output: ret_ty,
-            cf: ret_style,
             variadic: variadic
         });
         TyProc(P(ClosureTy {
@@ -1200,11 +1198,10 @@ pub fn parse_ty_closure(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_
 
         let bounds = self.parse_colon_then_ty_param_bounds();
 
-        let (return_style, output) = self.parse_ret_ty();
+        let output = self.parse_ret_ty();
         let decl = P(FnDecl {
             inputs: inputs,
             output: output,
-            cf: return_style,
             variadic: false
         });
 
@@ -1384,31 +1381,20 @@ pub fn parse_ty_field(&mut self) -> TypeField {
     }
 
     /// Parse optional return type [ -> TY ] in function decl
-    pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
-        return if self.eat(&token::RArrow) {
-            let lo = self.span.lo;
+    pub fn parse_ret_ty(&mut self) -> FunctionRetTy {
+        if self.eat(&token::RArrow) {
             if self.eat(&token::Not) {
-                (
-                    NoReturn,
-                    P(Ty {
-                        id: ast::DUMMY_NODE_ID,
-                        node: TyBot,
-                        span: mk_sp(lo, self.last_span.hi)
-                    })
-                )
+                NoReturn(self.span)
             } else {
-                (Return, self.parse_ty(true))
+                Return(self.parse_ty(true))
             }
         } else {
             let pos = self.span.lo;
-            (
-                Return,
-                P(Ty {
-                    id: ast::DUMMY_NODE_ID,
-                    node: TyNil,
-                    span: mk_sp(pos, pos),
-                })
-            )
+            Return(P(Ty {
+                id: ast::DUMMY_NODE_ID,
+                node: TyTup(vec![]),
+                span: mk_sp(pos, pos),
+            }))
         }
     }
 
@@ -1423,34 +1409,29 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
 
         let t = if self.token == token::OpenDelim(token::Paren) {
             self.bump();
-            if self.token == token::CloseDelim(token::Paren) {
-                self.bump();
-                TyNil
-            } else {
-                // (t) is a parenthesized ty
-                // (t,) is the type of a tuple with only one field,
-                // of type t
-                let mut ts = vec!(self.parse_ty(true));
-                let mut one_tuple = false;
-                while self.token == token::Comma {
-                    self.bump();
-                    if self.token != token::CloseDelim(token::Paren) {
-                        ts.push(self.parse_ty(true));
-                    }
-                    else {
-                        one_tuple = true;
-                    }
-                }
 
-                if ts.len() == 1 && !one_tuple {
-                    self.expect(&token::CloseDelim(token::Paren));
-                    TyParen(ts.into_iter().nth(0).unwrap())
+            // (t) is a parenthesized ty
+            // (t,) is the type of a tuple with only one field,
+            // of type t
+            let mut ts = vec![];
+            let mut last_comma = false;
+            while self.token != token::CloseDelim(token::Paren) {
+                ts.push(self.parse_ty(true));
+                if self.token == token::Comma {
+                    last_comma = true;
+                    self.bump();
                 } else {
-                    let t = TyTup(ts);
-                    self.expect(&token::CloseDelim(token::Paren));
-                    t
+                    last_comma = false;
+                    break;
                 }
             }
+
+            self.expect(&token::CloseDelim(token::Paren));
+            if ts.len() == 1 && !last_comma {
+                TyParen(ts.into_iter().nth(0).unwrap())
+            } else {
+                TyTup(ts)
+            }
         } else if self.token == token::Tilde {
             // OWNED POINTER
             self.bump();
@@ -1459,7 +1440,7 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
                 token::OpenDelim(token::Bracket) => self.obsolete(last_span, ObsoleteOwnedVector),
                 _ => self.obsolete(last_span, ObsoleteOwnedType)
             }
-            TyUniq(self.parse_ty(false))
+            TyTup(vec![self.parse_ty(false)])
         } else if self.token == token::BinOp(token::Star) {
             // STAR POINTER (bare pointer?)
             self.bump();
@@ -1662,10 +1643,6 @@ pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
                 LitBinary(parse::binary_lit(i.as_str())),
             token::LitBinaryRaw(i, _) =>
                 LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
-            token::OpenDelim(token::Paren) => {
-                self.expect(&token::CloseDelim(token::Paren));
-                LitNil
-            },
             _ => { self.unexpected_last(tok); }
         }
     }
@@ -2126,33 +2103,29 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
         match self.token {
             token::OpenDelim(token::Paren) => {
                 self.bump();
+
                 // (e) is parenthesized e
                 // (e,) is a tuple with only one field, e
+                let mut es = vec![];
                 let mut trailing_comma = false;
-                if self.token == token::CloseDelim(token::Paren) {
-                    hi = self.span.hi;
-                    self.bump();
-                    let lit = P(spanned(lo, hi, LitNil));
-                    return self.mk_expr(lo, hi, ExprLit(lit));
-                }
-                let mut es = vec!(self.parse_expr());
-                self.commit_expr(&**es.last().unwrap(), &[],
-                                 &[token::Comma, token::CloseDelim(token::Paren)]);
-                while self.token == token::Comma {
-                    self.bump();
-                    if self.token != token::CloseDelim(token::Paren) {
-                        es.push(self.parse_expr());
-                        self.commit_expr(&**es.last().unwrap(), &[],
-                                         &[token::Comma, token::CloseDelim(token::Paren)]);
-                    } else {
+                while self.token != token::CloseDelim(token::Paren) {
+                    es.push(self.parse_expr());
+                    self.commit_expr(&**es.last().unwrap(), &[],
+                                     &[token::Comma, token::CloseDelim(token::Paren)]);
+                    if self.token == token::Comma {
                         trailing_comma = true;
+
+                        self.bump();
+                    } else {
+                        trailing_comma = false;
+                        break;
                     }
                 }
-                hi = self.span.hi;
-                self.commit_expr_expecting(&**es.last().unwrap(), token::CloseDelim(token::Paren));
+                self.bump();
 
+                hi = self.span.hi;
                 return if es.len() == 1 && !trailing_comma {
-                   self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap()))
+                    self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap()))
                 } else {
                     self.mk_expr(lo, hi, ExprTup(es))
                 }
@@ -3293,13 +3266,8 @@ pub fn parse_pat(&mut self) -> P<Pat> {
             // parse (pat,pat,pat,...) as tuple
             self.bump();
             if self.token == token::CloseDelim(token::Paren) {
-                hi = self.span.hi;
                 self.bump();
-                let lit = P(codemap::Spanned {
-                    node: LitNil,
-                    span: mk_sp(lo, hi)});
-                let expr = self.mk_expr(lo, hi, ExprLit(lit));
-                pat = PatLit(expr);
+                pat = PatTup(vec![]);
             } else {
                 let mut fields = vec!(self.parse_pat());
                 if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) {
@@ -4137,12 +4105,11 @@ fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
     pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
 
         let (args, variadic) = self.parse_fn_args(true, allow_variadic);
-        let (ret_style, ret_ty) = self.parse_ret_ty();
+        let ret_ty = self.parse_ret_ty();
 
         P(FnDecl {
             inputs: args,
             output: ret_ty,
-            cf: ret_style,
             variadic: variadic
         })
     }
@@ -4337,12 +4304,11 @@ macro_rules! parse_remaining_arguments {
 
         let hi = self.span.hi;
 
-        let (ret_style, ret_ty) = self.parse_ret_ty();
+        let ret_ty = self.parse_ret_ty();
 
         let fn_decl = P(FnDecl {
             inputs: fn_inputs,
             output: ret_ty,
-            cf: ret_style,
             variadic: false
         });
 
@@ -4368,10 +4334,10 @@ fn parse_fn_block_decl(&mut self)
                 (optional_unboxed_closure_kind, args)
             }
         };
-        let (style, output) = if self.token == token::RArrow {
+        let output = if self.token == token::RArrow {
             self.parse_ret_ty()
         } else {
-            (Return, P(Ty {
+            Return(P(Ty {
                 id: ast::DUMMY_NODE_ID,
                 node: TyInfer,
                 span: self.span,
@@ -4381,7 +4347,6 @@ fn parse_fn_block_decl(&mut self)
         (P(FnDecl {
             inputs: inputs_captures,
             output: output,
-            cf: style,
             variadic: false
         }), optional_unboxed_closure_kind)
     }
@@ -4394,10 +4359,10 @@ fn parse_proc_decl(&mut self) -> P<FnDecl> {
                                      seq_sep_trailing_allowed(token::Comma),
                                      |p| p.parse_fn_block_arg());
 
-        let (style, output) = if self.token == token::RArrow {
+        let output = if self.token == token::RArrow {
             self.parse_ret_ty()
         } else {
-            (Return, P(Ty {
+            Return(P(Ty {
                 id: ast::DUMMY_NODE_ID,
                 node: TyInfer,
                 span: self.span,
@@ -4407,7 +4372,6 @@ fn parse_proc_decl(&mut self) -> P<FnDecl> {
         P(FnDecl {
             inputs: inputs,
             output: output,
-            cf: style,
             variadic: false
         })
     }
index c1515a36bec6897a982445e5fbecee5ab4442952..7025555ab4006483c8abc397fbdc974a464a5fcc 100644 (file)
@@ -645,12 +645,6 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
         try!(self.maybe_print_comment(ty.span.lo));
         try!(self.ibox(0u));
         match ty.node {
-            ast::TyNil => try!(word(&mut self.s, "()")),
-            ast::TyBot => try!(word(&mut self.s, "!")),
-            ast::TyUniq(ref ty) => {
-                try!(word(&mut self.s, "~"));
-                try!(self.print_type(&**ty));
-            }
             ast::TyVec(ref ty) => {
                 try!(word(&mut self.s, "["));
                 try!(self.print_type(&**ty));
@@ -2307,15 +2301,7 @@ pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
         }
         try!(self.pclose());
 
-        try!(self.maybe_print_comment(decl.output.span.lo));
-        match decl.output.node {
-            ast::TyNil => Ok(()),
-            _ => {
-                try!(self.space_if_not_bol());
-                try!(self.word_space("->"));
-                self.print_type(&*decl.output)
-            }
-        }
+        self.print_fn_output(decl)
     }
 
     pub fn print_fn_block_args(
@@ -2333,16 +2319,24 @@ pub fn print_fn_block_args(
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, "|"));
 
-        match decl.output.node {
-            ast::TyInfer => {}
-            _ => {
-                try!(self.space_if_not_bol());
-                try!(self.word_space("->"));
-                try!(self.print_type(&*decl.output));
+        if let ast::Return(ref ty) = decl.output {
+            if ty.node == ast::TyInfer {
+                return self.maybe_print_comment(ty.span.lo);
             }
         }
 
-        self.maybe_print_comment(decl.output.span.lo)
+        try!(self.space_if_not_bol());
+        try!(self.word_space("->"));
+        match decl.output {
+            ast::Return(ref ty) => {
+                try!(self.print_type(&**ty));
+                self.maybe_print_comment(ty.span.lo)
+            }
+            ast::NoReturn(span) => {
+                try!(self.word_nbsp("!"));
+                self.maybe_print_comment(span.lo)
+            }
+        }
     }
 
     pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
@@ -2359,16 +2353,24 @@ pub fn print_proc_args(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, ")"));
 
-        match decl.output.node {
-            ast::TyInfer => {}
-            _ => {
-                try!(self.space_if_not_bol());
-                try!(self.word_space("->"));
-                try!(self.print_type(&*decl.output));
+        if let ast::Return(ref ty) = decl.output {
+            if ty.node == ast::TyInfer {
+                return self.maybe_print_comment(ty.span.lo);
             }
         }
 
-        self.maybe_print_comment(decl.output.span.lo)
+        try!(self.space_if_not_bol());
+        try!(self.word_space("->"));
+        match decl.output {
+            ast::Return(ref ty) => {
+                try!(self.print_type(&**ty));
+                self.maybe_print_comment(ty.span.lo)
+            }
+            ast::NoReturn(span) => {
+                try!(self.word_nbsp("!"));
+                self.maybe_print_comment(span.lo)
+            }
+        }
     }
 
     pub fn print_bounds(&mut self,
@@ -2627,20 +2629,30 @@ pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
     }
 
     pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
-        match decl.output.node {
-            ast::TyNil => Ok(()),
-            _ => {
-                try!(self.space_if_not_bol());
-                try!(self.ibox(indent_unit));
-                try!(self.word_space("->"));
-                if decl.cf == ast::NoReturn {
-                    try!(self.word_nbsp("!"));
-                } else {
-                    try!(self.print_type(&*decl.output));
+        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);
                 }
-                self.end()
+                _ => ()
             }
         }
+
+        try!(self.space_if_not_bol());
+        try!(self.ibox(indent_unit));
+        try!(self.word_space("->"));
+        match decl.output {
+            ast::NoReturn(_) =>
+                try!(self.word_nbsp("!")),
+            ast::Return(ref ty) =>
+                try!(self.print_type(&**ty))
+        }
+        try!(self.end());
+
+        match decl.output {
+            ast::Return(ref output) => self.maybe_print_comment(output.span.lo),
+            _ => Ok(())
+        }
     }
 
     pub fn print_ty_fn(&mut self,
@@ -2700,8 +2712,6 @@ pub fn print_ty_fn(&mut self,
 
         try!(self.print_bounds(":", bounds));
 
-        try!(self.maybe_print_comment(decl.output.span.lo));
-
         try!(self.print_fn_output(decl));
 
         match generics {
@@ -2807,7 +2817,6 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                          ast_util::float_ty_to_string(t).as_slice()).as_slice())
             }
             ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
-            ast::LitNil => word(&mut self.s, "()"),
             ast::LitBool(val) => {
                 if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") }
             }
@@ -3003,10 +3012,9 @@ fn test_fun_to_string() {
 
         let decl = ast::FnDecl {
             inputs: Vec::new(),
-            output: P(ast::Ty {id: 0,
-                               node: ast::TyNil,
-                               span: codemap::DUMMY_SP}),
-            cf: ast::Return,
+            output: ast::Return(P(ast::Ty {id: 0,
+                               node: ast::TyTup(vec![]),
+                               span: codemap::DUMMY_SP})),
             variadic: false
         };
         let generics = ast_util::empty_generics();
index 29637e88dd53d0a3a51e4d858137148bf89bb570..8b6d752d4848e83154109593479642c62fd87853 100644 (file)
@@ -289,9 +289,12 @@ enum HasTestSignature {
     fn has_test_signature(i: &ast::Item) -> HasTestSignature {
         match &i.node {
           &ast::ItemFn(ref decl, _, _, ref generics, _) => {
-            let no_output = match decl.output.node {
-                ast::TyNil => true,
-                _ => false,
+            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
             };
             if decl.inputs.is_empty()
                    && no_output
@@ -325,9 +328,12 @@ fn has_test_signature(i: &ast::Item) -> bool {
         match i.node {
             ast::ItemFn(ref decl, _, _, ref generics, _) => {
                 let input_cnt = decl.inputs.len();
-                let no_output = match decl.output.node {
-                    ast::TyNil => true,
-                    _ => false
+                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
                 };
                 let tparm_cnt = generics.ty_params.len();
                 // NB: inadequate check, but we're running
index 1b1d1e9cace1a8b8746ca95e324ab47413d78f1d..f30a4325eb8c0dd8a3f8965eee702af802ad8121 100644 (file)
@@ -341,7 +341,7 @@ pub fn skip_ty<'v, V: Visitor<'v>>(_: &mut V, _: &'v Ty) {
 
 pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
     match typ.node {
-        TyUniq(ref ty) | TyVec(ref ty) | TyParen(ref ty) => {
+        TyVec(ref ty) | TyParen(ref ty) => {
             visitor.visit_ty(&**ty)
         }
         TyPtr(ref mutable_type) => {
@@ -360,7 +360,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output);
+            walk_fn_ret_ty(visitor, &function_declaration.decl.output);
             walk_ty_param_bounds(visitor, &function_declaration.bounds);
             walk_lifetime_decls(visitor, &function_declaration.lifetimes);
         }
@@ -368,7 +368,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output);
+            walk_fn_ret_ty(visitor, &function_declaration.decl.output);
             walk_ty_param_bounds(visitor, &function_declaration.bounds);
             walk_lifetime_decls(visitor, &function_declaration.lifetimes);
         }
@@ -376,7 +376,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output);
+            walk_fn_ret_ty(visitor, &function_declaration.decl.output);
             walk_lifetime_decls(visitor, &function_declaration.lifetimes);
         }
         TyPath(ref path, ref opt_bounds, id) => {
@@ -403,7 +403,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
         TyTypeof(ref expression) => {
             visitor.visit_expr(&**expression)
         }
-        TyNil | TyBot | TyInfer => {}
+        TyInfer => {}
     }
 }
 
@@ -538,12 +538,18 @@ pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics
     }
 }
 
+pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
+    if let Return(ref output_ty) = *ret_ty {
+        visitor.visit_ty(&**output_ty)
+    }
+}
+
 pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
     for argument in function_declaration.inputs.iter() {
         visitor.visit_pat(&*argument.pat);
         visitor.visit_ty(&*argument.ty)
     }
-    visitor.visit_ty(&*function_declaration.output)
+    walk_fn_ret_ty(visitor, &function_declaration.output)
 }
 
 // Note: there is no visit_method() method in the visitor, instead override
@@ -601,7 +607,7 @@ pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v Type
         visitor.visit_ty(&*argument_type.ty)
     }
     visitor.visit_generics(&method_type.generics);
-    visitor.visit_ty(&*method_type.decl.output);
+    walk_fn_ret_ty(visitor, &method_type.decl.output);
     for attr in method_type.attrs.iter() {
         visitor.visit_attribute(attr);
     }