From eb01b17b06eb35542bb80ff7456043b0ed5572ba Mon Sep 17 00:00:00 2001 From: Jakub Bukaj Date: Sun, 9 Nov 2014 16:14:15 +0100 Subject: [PATCH] Complete the removal of ty_nil, ast::LitNil, ast::TyBot and ast::TyUniq [breaking-change] This will break any uses of macros that assumed () being a valid literal. --- src/librustc/diagnostics.rs | 1 - src/librustc/lint/builtin.rs | 5 +- src/librustc/middle/check_match.rs | 8 +- src/librustc/middle/const_eval.rs | 5 +- src/librustc/middle/resolve.rs | 8 +- src/librustc/middle/save/mod.rs | 21 ++- src/librustc/middle/trans/consts.rs | 1 - src/librustc/middle/trans/context.rs | 4 +- src/librustc/middle/trans/debuginfo.rs | 20 ++- src/librustc/middle/ty.rs | 80 ++++----- src/librustc/middle/typeck/astconv.rs | 87 ++++------ src/librustc/middle/typeck/check/mod.rs | 5 +- src/librustc/middle/typeck/collect.rs | 8 +- src/librustc/middle/typeck/infer/combine.rs | 4 +- .../middle/typeck/infer/error_reporting.rs | 18 +- src/librustdoc/clean/mod.rs | 42 ++--- src/librustdoc/html/format.rs | 34 ++-- src/libsyntax/ast.rs | 25 +-- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/build.rs | 21 +-- src/libsyntax/ext/concat.rs | 1 - src/libsyntax/ext/deriving/encodable.rs | 6 +- src/libsyntax/ext/deriving/generic/mod.rs | 2 +- src/libsyntax/ext/deriving/generic/ty.rs | 11 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/format.rs | 2 +- src/libsyntax/fold.rs | 19 ++- src/libsyntax/lib.rs | 2 +- src/libsyntax/parse/mod.rs | 7 +- src/libsyntax/parse/obsolete.rs | 6 +- src/libsyntax/parse/parser.rs | 156 +++++++----------- src/libsyntax/print/pprust.rs | 102 ++++++------ src/libsyntax/test.rs | 18 +- src/libsyntax/visit.rs | 20 ++- 34 files changed, 348 insertions(+), 405 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index d5e9c1ef99f..1792599783b 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -66,7 +66,6 @@ register_diagnostics!( E0055, E0056, E0057, - E0058, E0059, E0060, E0061, diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index a5187283de1..83194efc554 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -447,7 +447,9 @@ impl LintPass for ImproperCTypes { 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 @@ impl LintPass for UnusedResults { 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, _) => { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a23889d9cab..3968e6b6534 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -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 { 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(), diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index fdda5f1a860..1fd5b81f499 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -311,8 +311,7 @@ pub enum const_val { const_uint(u64), const_str(InternedString), const_binary(Rc >), - const_bool(bool), - const_nil + const_bool(bool) } pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P { @@ -589,7 +588,6 @@ pub fn lit_to_const(lit: &Lit) -> const_val { LitFloatUnsuffixed(ref n) => { const_float(from_str::(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 { (&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 } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 62d1e13d41f..2cfaf8438ae 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4285,7 +4285,9 @@ impl<'a> Resolver<'a> { _ => {} } - 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 @@ impl<'a> Resolver<'a> { debug!("(resolving function) recorded argument"); } - this.resolve_type(&*declaration.output); + if let ast::Return(ref ret_ty) = declaration.output { + this.resolve_type(&**ret_ty); + } } } diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs index 59fbcde85e8..367fe2845dd 100644 --- a/src/librustc/middle/save/mod.rs +++ b/src/librustc/middle/save/mod.rs @@ -383,7 +383,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { 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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { 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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { 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)); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 409809e0cb3..330959d6871 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -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()), } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index be712087e0b..42da0573460 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -718,7 +718,9 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option $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); } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index be342c8afe9..f11ca1eec5a 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -1374,10 +1374,9 @@ pub fn create_function_debug_context(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) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 1e5b3c9ea7a..97160e7a6d1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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 @@ pub fn normalize_ty(cx: &ctxt, t: t) -> t { // 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 + 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()); } - const_eval::const_str(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count, found string"); - 0 + 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()); } - 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 - } } + 0 } // Iterate over a type parameter's bounded traits and any supertraits diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 9358904a78c..8df4d59a292 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -385,7 +385,7 @@ fn ast_path_substs<'tcx,AC,RS>( 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 { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index bb20475c0cf..37fb368b54b 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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 @@ pub fn instantiate_path(fcx: &FnCtxt, 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); diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 6685bb9be77..eed574a1a1d 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -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( diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index df25e5009c3..078a2c10bcb 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -539,9 +539,11 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres>() .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))) } } diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index 80b4948f6fb..e12019a1530 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -973,8 +973,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { &anon_nums, ®ion_names); inputs = self.rebuild_args_ty(inputs.as_slice(), lifetime, &anon_nums, ®ion_names); - output = self.rebuild_arg_ty_or_output(&*output, lifetime, - &anon_nums, ®ion_names); + output = self.rebuild_output(&output, lifetime, &anon_nums, ®ion_names); ty_params = self.rebuild_ty_params(ty_params, lifetime, ®ion_names); } @@ -989,7 +988,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { new_inputs } + fn rebuild_output(&self, ty: &ast::FunctionRetTy, + lifetime: ast::Lifetime, + anon_nums: &HashSet, + region_names: &HashSet) -> 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 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { }) } 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) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 38e0c4fe040..a608fba80e3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -710,8 +710,7 @@ impl Clean for ast::Method { 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 @@ impl Clean for ast::TypeMethod { 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 @@ impl Clean for ast::ClosureTy { #[deriving(Clone, Encodable, Decodable, PartialEq)] pub struct FnDecl { pub inputs: Arguments, - pub output: Type, - pub cf: RetStyle, + pub output: FunctionRetTy, pub attrs: Vec, } @@ -857,7 +854,6 @@ impl Clean for ast::FnDecl { values: self.inputs.clean(cx), }, output: self.output.clean(cx), - cf: self.cf.clean(cx), attrs: Vec::new() } } @@ -884,8 +880,7 @@ impl<'a> Clean for (ast::DefId, &'a ty::FnSig) { 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 @@ impl Clean for ast::Arg { } #[deriving(Clone, Encodable, Decodable, PartialEq)] -pub enum RetStyle { - NoReturn, - Return +pub enum FunctionRetTy { + Return(Type), + NoReturn } -impl Clean for ast::RetStyle { - fn clean(&self, _: &DocContext) -> RetStyle { +impl Clean 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 @@ impl 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 @@ impl PrimitiveType { 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 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 @@ impl Clean for ast::Ty { 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 @@ impl Clean for ast::Ty { impl Clean 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 @@ impl Clean for ty::t { } } - 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(), } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fe96c9b3a9f..a7f33151547 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -393,10 +393,7 @@ impl fmt::Show for clean::Type { format!("<{:#}>", decl.lifetimes) }, args = decl.decl.inputs, - arrow = match decl.decl.output { - clean::Primitive(clean::Unit) => "".to_string(), - _ => format!(" -> {}", decl.decl.output), - }, + arrow = decl.decl.output, bounds = { let mut ret = String::new(); for bound in decl.bounds.iter() { @@ -435,10 +432,7 @@ impl fmt::Show for clean::Type { ": {}", m.collect::>().connect(" + ")) }, - arrow = match decl.decl.output { - clean::Primitive(clean::Unit) => "".to_string(), - _ => format!(" -> {}", decl.decl.output) - }) + arrow = decl.decl.output) } clean::BareFunction(ref decl) => { write!(f, "{}{}fn{}{}", @@ -514,14 +508,19 @@ impl fmt::Show for clean::Arguments { } } +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, " -> {}", ty), + clean::NoReturn => write!(f, " -> !") + } + } +} + 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!(" -> {}", self.output), - }) + write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output) } } @@ -551,12 +550,7 @@ impl<'a> fmt::Show for Method<'a> { } 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!(" -> {}", d.output), - }) + write!(f, "({args}){arrow}", args = args, arrow = d.output) } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7c5de627d08..0e1921a0773 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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), - /// An array (`[T]`) TyVec(P), /// A fixed length array (`[T, ..n]`) TyFixedLengthVec(P, P), @@ -1175,8 +1168,7 @@ impl Arg { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct FnDecl { pub inputs: Vec, - pub output: P, - pub cf: RetStyle, + pub output: FunctionRetTy, pub variadic: bool } @@ -1198,12 +1190,21 @@ impl fmt::Show for FnStyle { } #[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), +} + +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 diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 1e2d935af00..0c7a3cf4a6c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -248,7 +248,7 @@ impl DummyResult { pub fn raw_expr(sp: Span) -> P { 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, }) } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 862cbf3d7ca..ffc42b67033 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -54,11 +54,9 @@ pub trait AstBuilder { fn ty_ptr(&self, span: Span, ty: P, mutbl: ast::Mutability) -> P; - fn ty_uniq(&self, span: Span, ty: P) -> P; fn ty_option(&self, ty: P) -> P; fn ty_infer(&self, sp: Span) -> P; - fn ty_nil(&self) -> P; fn ty_vars(&self, ty_params: &OwnedSlice) -> Vec> ; fn ty_vars_global(&self, ty_params: &OwnedSlice) -> Vec> ; @@ -377,9 +375,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.ty(span, ast::TyPtr(self.ty_mt(ty, mutbl))) } - fn ty_uniq(&self, span: Span, ty: P) -> P { - self.ty(span, ast::TyUniq(ty)) - } fn ty_option(&self, ty: P) -> P { self.ty_path( @@ -406,14 +401,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.ty(span, ast::TyInfer) } - fn ty_nil(&self) -> P { - 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 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.pat(span, pat) } fn pat_tuple(&self, span: Span, pats: Vec>) -> P { - let pat = ast::PatTup(pats); - self.pat(span, pat) + self.pat(span, ast::PatTup(pats)) } fn pat_some(&self, span: Span, pat: P) -> P { @@ -931,11 +917,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // FIXME unused self - fn fn_decl(&self, inputs: Vec , output: P) -> P { + fn fn_decl(&self, inputs: Vec, output: P) -> P { P(ast::FnDecl { inputs: inputs, - output: output, - cf: ast::Return, + output: ast::Return(output), variadic: false }) } diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs index af7cd4157ec..e2867c2fbab 100644 --- a/src/libsyntax/ext/concat.rs +++ b/src/libsyntax/ext/concat.rs @@ -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()); } diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 69eb260b8c4..62f3b5d01b4 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -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)); } diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 7c32b845508..4be299994fd 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -922,7 +922,7 @@ impl<'a> MethodDef<'a> { } // 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 diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs index 1ec1e3b1224..8b46769d633 100644 --- a/src/libsyntax/ext/deriving/generic/ty.rs +++ b/src/libsyntax/ext/deriving/generic/ty.rs @@ -152,14 +152,9 @@ impl<'a> Ty<'a> { 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) } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 87406081aae..fa69495fa42 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -159,7 +159,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // `_ => [ | ()]` 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) }; diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index a28f24e7663..a816b479630 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -654,7 +654,7 @@ impl<'a, 'b> Context<'a, 'b> { // // 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)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d7c3ca8efc4..56d91282437 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -391,8 +391,7 @@ pub fn noop_fold_ty(t: P, fld: &mut T) -> P { 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(nt: token::Nonterminal, fld: &mut T) } pub fn noop_fold_fn_decl(decl: P, fld: &mut T) -> P { - 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(ni: P, 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)) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 4881be8996a..fa10cb90f83 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -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; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 51738ece80f..2810db4eadd 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1037,10 +1037,9 @@ mod test { }), 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, diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 73787763c8b..1b2ab3c235d 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -17,8 +17,8 @@ Obsolete syntax that becomes too hard to parse can be 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 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { /// a placeholder expression fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P { 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, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index db10dc1bc90..4f487a10e98 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -30,13 +30,13 @@ use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; 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}; @@ -44,18 +44,18 @@ use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { } /// Parse optional return type [ -> TY ] in function decl - pub fn parse_ret_ty(&mut self) -> (RetStyle, P) { - 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { // 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 @@ impl<'a> Parser<'a> { pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { (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 @@ impl<'a> Parser<'a> { (P(FnDecl { inputs: inputs_captures, output: output, - cf: style, variadic: false }), optional_unboxed_closure_kind) } @@ -4394,10 +4359,10 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { P(FnDecl { inputs: inputs, output: output, - cf: style, variadic: false }) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c1515a36bec..7025555ab40 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -645,12 +645,6 @@ impl<'a> State<'a> { 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 @@ impl<'a> State<'a> { } 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 @@ impl<'a> State<'a> { 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 @@ impl<'a> State<'a> { 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 @@ impl<'a> State<'a> { } 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 @@ impl<'a> State<'a> { 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 @@ impl<'a> State<'a> { 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 @@ mod test { 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(); diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 29637e88dd5..8b6d752d484 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -289,9 +289,12 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { 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 is_bench_fn(cx: &TestCtxt, 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 diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1b1d1e9cace..f30a4325eb8 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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); }