diff options
| author | Andrew Cann <shum@canndrew.org> | 2016-07-22 13:50:04 +0800 |
|---|---|---|
| committer | Andrew Cann <shum@canndrew.org> | 2016-08-13 21:37:09 +0800 |
| commit | 104963c539e538a89fff21c133692fc21dac3e64 (patch) | |
| tree | 47f0eb74a863f329732f74914c7951fecd0d1260 | |
| parent | 9f9f8567eb4effe1052b7458c7451f62d1dcc0b1 (diff) | |
| download | rust-104963c539e538a89fff21c133692fc21dac3e64.tar.gz rust-104963c539e538a89fff21c133692fc21dac3e64.zip | |
Switch on TyEmpty
Parse -> ! as FnConverging(!) Add AdjustEmptyToAny coercion to all ! expressions Some fixes
| -rw-r--r-- | src/librustc/cfg/construct.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/liveness.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 19 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/into.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/transform/type_check.rs | 8 | ||||
| -rw-r--r-- | src/librustc_trans/debuginfo/metadata.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/check/_match.rs | 6 | ||||
| -rw-r--r-- | src/librustc_typeck/check/intrinsic.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 84 | ||||
| -rw-r--r-- | src/librustc_typeck/check/op.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 6 |
11 files changed, 88 insertions, 54 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 601d3866b02..89964043819 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -379,7 +379,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); let ret = self.straightline(call_expr, func_or_rcvr_exit, args); - if fn_ty.fn_ret().diverges() { + if fn_ty.fn_ret().diverges(self.tcx) { self.add_unreachable_node() } else { ret diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index f62c9a5d882..3a293c304ee 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1112,7 +1112,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprCall(ref f, ref args) => { let diverges = !self.ir.tcx.is_method_call(expr.id) && - self.ir.tcx.expr_ty_adjusted(&f).fn_ret().diverges(); + self.ir.tcx.expr_ty_adjusted(&f).fn_ret().diverges(self.ir.tcx); let succ = if diverges { self.s.exit_ln } else { @@ -1125,7 +1125,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprMethodCall(_, _, ref args) => { let method_call = ty::MethodCall::expr(expr.id); let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty; - let succ = if method_ty.fn_ret().diverges() { + let succ = if method_ty.fn_ret().diverges(self.ir.tcx) { self.s.exit_ln } else { succ diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d693f7f0b83..6cc7eef1c6f 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -484,8 +484,11 @@ pub enum FnOutput<'tcx> { } impl<'tcx> FnOutput<'tcx> { - pub fn diverges(&self) -> bool { - *self == FnDiverging + pub fn diverges(&self, tcx: TyCtxt) -> bool { + match *self { + FnConverging(ref ty) => ty.is_empty(tcx), + FnDiverging => true, + } } pub fn unwrap(self) -> Ty<'tcx> { @@ -513,8 +516,8 @@ impl<'tcx> FnOutput<'tcx> { pub type PolyFnOutput<'tcx> = Binder<FnOutput<'tcx>>; impl<'tcx> PolyFnOutput<'tcx> { - pub fn diverges(&self) -> bool { - self.0.diverges() + pub fn diverges(&self, tcx: TyCtxt) -> bool { + self.0.diverges(tcx) } } @@ -936,11 +939,15 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } - pub fn is_empty(&self, _cx: TyCtxt) -> bool { + pub fn is_empty(&self, cx: TyCtxt) -> bool { // FIXME(#24885): be smarter here match self.sty { TyEnum(def, _) | TyStruct(def, _) => def.is_empty(), - _ => false + TyEmpty => true, + TyTuple(ref tys) => tys.iter().any(|ty| ty.is_empty(cx)), + // FIXME (canndrew): this line breaks core::fmt + //TyRef(_, ref tm) => tm.ty.is_empty(cx), + _ => false, } } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 5705798dab0..692f0d3e5ac 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -210,7 +210,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Call { ty, fun, args } => { let diverges = match ty.sty { ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => { - f.sig.0.output.diverges() + f.sig.0.output.diverges(this.hir.tcx()) } _ => false }; diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 934357c9e1d..53329a85036 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -504,9 +504,11 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } (&None, ty::FnDiverging) => {} - (&None, ty::FnConverging(..)) => { - span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); - } + (&None, ty::FnConverging(ref ty)) => { + if !ty.is_empty(tcx) { + span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); + } + } } } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index ee13af80b2b..4c58ce6b78c 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -171,6 +171,7 @@ impl<'tcx> TypeMap<'tcx> { unique_type_id.push('{'); match type_.sty { + ty::TyEmpty | ty::TyBool | ty::TyChar | ty::TyStr | @@ -704,6 +705,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let sty = &t.sty; let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty { + ty::TyEmpty | ty::TyBool | ty::TyChar | ty::TyInt(_) | @@ -931,6 +933,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, debug!("basic_type_metadata: {:?}", t); let (name, encoding) = match t.sty { + ty::TyEmpty => ("!", DW_ATE_unsigned), ty::TyTuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned), ty::TyBool => ("bool", DW_ATE_boolean), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 5f255cc1fb7..6b9917afdfb 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -473,7 +473,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; } - self.write_ty(expr.id, result_ty); + self.write_ty_expr(expr.id, result_ty); } } @@ -550,7 +550,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let scheme = tcx.lookup_item_type(def.def_id()); let predicates = tcx.lookup_predicates(def.def_id()); let pat_ty = self.instantiate_value_path(segments, scheme, &predicates, - opt_ty, def, pat.span, pat.id); + opt_ty, def, pat.span, pat.id, false); self.demand_suptype(pat.span, expected, pat_ty); } @@ -618,7 +618,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; let predicates = tcx.lookup_predicates(def.def_id()); let pat_ty = self.instantiate_value_path(segments, scheme, &predicates, - opt_ty, def, pat.span, pat.id); + opt_ty, def, pat.span, pat.id, false); self.demand_eqtype(pat.span, expected, pat_ty); // Type check subpatterns. diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 9051b1c8069..4788911662d 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -106,7 +106,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { }; (n_tps, inputs, ty::FnConverging(output)) } else if &name[..] == "abort" || &name[..] == "unreachable" { - (0, Vec::new(), ty::FnDiverging) + (0, Vec::new(), ty::FnConverging(tcx.mk_empty())) } else { let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), tcx.mk_nil()), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0c8e6d990a6..89a4bc4cac6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -93,7 +93,7 @@ use rustc::traits::{self, Reveal}; use rustc::ty::{GenericPredicates, TypeScheme}; use rustc::ty::{ParamTy, ParameterEnvironment}; use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue}; -use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility}; +use rustc::ty::{self, ToPolyTraitRef, Ty, TypeVariants, TyCtxt, Visibility}; use rustc::ty::{MethodCall, MethodCallee}; use rustc::ty::adjustment; use rustc::ty::fold::{BottomUpFolder, TypeFoldable}; @@ -1561,6 +1561,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tables.borrow_mut().node_types.insert(node_id, ty); } + #[inline] + pub fn write_ty_expr(&self, node_id: ast::NodeId, ty: Ty<'tcx>) { + self.write_ty(node_id, ty); + if let TypeVariants::TyEmpty = ty.sty { + self.write_adjustment(node_id, adjustment::AdjustEmptyToAny(self.next_diverging_ty_var())); + } + } + pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) { if !substs.substs.is_noop() { debug!("write_substs({}, {:?}) in fcx {}", @@ -1731,6 +1739,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn write_nil(&self, node_id: ast::NodeId) { self.write_ty(node_id, self.tcx.mk_nil()); } + + pub fn write_empty(&self, node_id: ast::NodeId) { + self.write_ty_expr(node_id, self.tcx.mk_empty()); + } + pub fn write_error(&self, node_id: ast::NodeId) { self.write_ty(node_id, self.tcx.types.err); } @@ -1788,6 +1801,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> { + if let Some(&adjustment::AdjustEmptyToAny(ref t)) + = self.tables.borrow().adjustments.get(&ex.id) { + return t; + } match self.tables.borrow().node_types.get(&ex.id) { Some(&t) => t, None => { @@ -1966,9 +1983,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for ty in &self.unsolved_variables() { let resolved = self.resolve_type_vars_if_possible(ty); if self.type_var_diverges(resolved) { - debug!("default_type_parameters: defaulting `{:?}` to `()` because it diverges", + debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges", resolved); - self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_nil()); + self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_empty()); } else { match self.type_is_unconstrained_numeric(resolved) { UnconstrainedInt => { @@ -2042,7 +2059,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for ty in &unsolved_variables { let resolved = self.resolve_type_vars_if_possible(ty); if self.type_var_diverges(resolved) { - self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_nil()); + self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_empty()); } else { match self.type_is_unconstrained_numeric(resolved) { UnconstrainedInt | UnconstrainedFloat => { @@ -2100,7 +2117,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| { for ty in &unbound_tyvars { if self.type_var_diverges(ty) { - self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_nil()); + self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_empty()); } else { match self.type_is_unconstrained_numeric(ty) { UnconstrainedInt => { @@ -2196,7 +2213,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // reporting for more then one conflict. for ty in &unbound_tyvars { if self.type_var_diverges(ty) { - self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_nil()); + self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.mk_empty()); } else { match self.type_is_unconstrained_numeric(ty) { UnconstrainedInt => { @@ -2601,7 +2618,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if let Some(&arg_ty) = self.tables.borrow().node_types.get(&arg.id) { - any_diverges = any_diverges || self.type_var_diverges(arg_ty); + any_diverges = any_diverges || + self.type_var_diverges(arg_ty) || + arg_ty.is_empty(self.tcx); } } if any_diverges && !warned { @@ -2670,7 +2689,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn write_call(&self, call_expr: &hir::Expr, output: ty::FnOutput<'tcx>) { - self.write_ty(call_expr.id, match output { + self.write_ty_expr(call_expr.id, match output { ty::FnConverging(output_ty) => output_ty, ty::FnDiverging => self.next_diverging_ty_var() }); @@ -2910,7 +2929,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // the type of the block, because old trans still uses it. let adj = self.tables.borrow().adjustments.get(&then.id).cloned(); if res.is_ok() && adj.is_some() { - self.write_ty(then_blk.id, self.adjust_expr_ty(then, adj.as_ref())); + self.write_ty_expr(then_blk.id, self.adjust_expr_ty(then, adj.as_ref())); } res @@ -2951,7 +2970,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - self.write_ty(id, if_ty); + self.write_ty_expr(id, if_ty); } // Check field access expressions @@ -2972,7 +2991,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let field_ty = self.field_ty(expr.span, field, substs); if field.vis.is_accessible_from(self.body_id, &self.tcx().map) { autoderef.finalize(lvalue_pref, Some(base)); - self.write_ty(expr.id, field_ty); + self.write_ty_expr(expr.id, field_ty); self.write_autoderef_adjustment(base.id, autoderefs); return; } @@ -2984,7 +3003,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some((did, field_ty)) = private_candidate { let struct_path = self.tcx().item_path_str(did); - self.write_ty(expr.id, field_ty); + self.write_ty_expr(expr.id, field_ty); let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path); let mut err = self.tcx().sess.struct_span_err(expr.span, &msg); // Also check if an accessible method exists, which is often what is meant. @@ -3079,7 +3098,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(field_ty) = field { autoderef.finalize(lvalue_pref, Some(base)); - self.write_ty(expr.id, field_ty); + self.write_ty_expr(expr.id, field_ty); self.write_autoderef_adjustment(base.id, autoderefs); return; } @@ -3090,7 +3109,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let struct_path = self.tcx().item_path_str(did); let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path); self.tcx().sess.span_err(expr.span, &msg); - self.write_ty(expr.id, field_ty); + self.write_ty_expr(expr.id, field_ty); return; } @@ -3343,7 +3362,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprLit(ref lit) => { let typ = self.check_lit(&lit, expected); - self.write_ty(id, typ); + self.write_ty_expr(id, typ); } hir::ExprBinary(op, ref lhs, ref rhs) => { self.check_binop(expr, op, lhs, rhs); @@ -3409,7 +3428,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - self.write_ty(id, oprnd_t); + self.write_ty_expr(id, oprnd_t); } hir::ExprAddrOf(mutbl, ref oprnd) => { let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { @@ -3460,7 +3479,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let (scheme, predicates) = self.type_scheme_and_predicates_for_def(expr.span, def); self.instantiate_value_path(segments, scheme, &predicates, - opt_ty, def, expr.span, id); + opt_ty, def, expr.span, id, true); } else { self.set_tainted_by_errors(); self.write_error(id); @@ -3481,8 +3500,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } self.write_nil(id); } - hir::ExprBreak(_) => { self.write_ty(id, self.next_diverging_ty_var()); } - hir::ExprAgain(_) => { self.write_ty(id, self.next_diverging_ty_var()); } + hir::ExprBreak(_) => { self.write_empty(id); } + hir::ExprAgain(_) => { self.write_empty(id); } hir::ExprRet(ref expr_opt) => { match self.ret_ty { ty::FnConverging(result_type) => { @@ -3513,7 +3532,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .emit(); } } - self.write_ty(id, self.next_diverging_ty_var()); + self.write_empty(id); } hir::ExprAssign(ref lhs, ref rhs) => { self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue); @@ -3555,7 +3574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprLoop(ref body, _) => { self.check_block_no_value(&body); if !may_break(tcx, expr.id, &body) { - self.write_ty(id, self.next_diverging_ty_var()); + self.write_empty(id); } else { self.write_nil(id); } @@ -3568,7 +3587,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } hir::ExprBlock(ref b) => { self.check_block_with_expected(&b, expected); - self.write_ty(id, self.node_ty(b.id)); + self.write_ty_expr(id, self.node_ty(b.id)); } hir::ExprCall(ref callee, ref args) => { self.check_call(expr, &callee, &args[..], expected); @@ -3604,7 +3623,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { // Write a type for the whole expression, assuming everything is going // to work out Ok. - self.write_ty(id, t_cast); + self.write_ty_expr(id, t_cast); // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); @@ -3621,7 +3640,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprType(ref e, ref t) => { let typ = self.to_ty(&t); self.check_expr_eq_type(&e, typ); - self.write_ty(id, typ); + self.write_ty_expr(id, typ); } hir::ExprVec(ref args) => { let uty = expected.to_option(self).and_then(|uty| { @@ -3755,7 +3774,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some((index_ty, element_ty)) => { let idx_expr_ty = self.expr_ty(idx); self.demand_eqtype(expr.span, index_ty, idx_expr_ty); - self.write_ty(id, element_ty); + self.write_ty_expr(id, element_ty); } None => { self.check_expr_has_type(&idx, self.tcx.types.err); @@ -4011,7 +4030,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "unreachable statement".to_string()); warned = true; } - any_diverges = any_diverges || self.type_var_diverges(s_ty); + any_diverges = any_diverges || + self.type_var_diverges(s_ty) || + s_ty.is_empty(self.tcx); any_err = any_err || s_ty.references_error(); } match blk.expr { @@ -4047,7 +4068,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if any_diverges { self.write_ty(blk.id, self.next_diverging_ty_var()); } else { - self.write_ty(blk.id, ety); + self.write_ty_expr(blk.id, ety); } } }; @@ -4096,7 +4117,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { opt_self_ty: Option<Ty<'tcx>>, def: Def, span: Span, - node_id: ast::NodeId) + node_id: ast::NodeId, + node_is_expr: bool) { -> Ty<'tcx> { debug!("instantiate_value_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})", segments, @@ -4360,7 +4382,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("instantiate_value_path: type of {:?} is {:?}", node_id, ty_substituted); - self.write_ty(node_id, ty_substituted); + if node_is_expr { + self.write_ty_expr(node_id, ty_substituted); + } else { + self.write_ty(node_id, ty_substituted); + } self.write_substs(node_id, ty::ItemSubsts { substs: substs }); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 63487683ec3..17da3cd3490 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -36,7 +36,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.enforce_builtin_binop_types(lhs_expr, lhs_ty, rhs_expr, rhs_ty, op); self.write_nil(expr.id); } else { - self.write_ty(expr.id, return_ty); + self.write_ty_expr(expr.id, return_ty); } let tcx = self.tcx; @@ -69,7 +69,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // && and || are a simple case. self.demand_suptype(lhs_expr.span, tcx.mk_bool(), lhs_ty); self.check_expr_coercable_to_type(rhs_expr, tcx.mk_bool()); - self.write_ty(expr.id, tcx.mk_bool()); + self.write_ty_expr(expr.id, tcx.mk_bool()); } _ => { // Otherwise, we always treat operators as if they are @@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.demand_suptype(expr.span, builtin_return_ty, return_ty); } - self.write_ty(expr.id, return_ty); + self.write_ty_expr(expr.id, return_ty); } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e3803591295..4f54f529322 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1332,11 +1332,7 @@ impl<'a> Parser<'a> { /// Parse optional return type [ -> TY ] in function decl pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> { if self.eat(&token::RArrow) { - if self.eat(&token::Not) { - Ok(FunctionRetTy::None(self.last_span)) - } else { - Ok(FunctionRetTy::Ty(self.parse_ty()?)) - } + Ok(FunctionRetTy::Ty(self.parse_ty()?)) } else { let pos = self.span.lo; Ok(FunctionRetTy::Default(mk_sp(pos, pos))) |
