diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 1b2976b7435d8..a2fc6e044e74c 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -311,11 +311,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } hir::ExprIndex(ref l, ref r) | - hir::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => { + hir::ExprBinary(_, ref l, ref r) if self.tcx.tables().is_method_call(expr.id) => { self.call(expr, pred, &l, Some(&**r).into_iter()) } - hir::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => { + hir::ExprUnary(_, ref e) if self.tcx.tables().is_method_call(expr.id) => { self.call(expr, pred, &e, None::.iter()) } @@ -372,9 +372,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { func_or_rcvr: &hir::Expr, args: I) -> CFGIndex { let method_call = ty::MethodCall::expr(call_expr.id); - let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) { + let fn_ty = match self.tcx.tables().method_map.get(&method_call) { Some(method) => method.ty, - None => self.tcx.expr_ty_adjusted(func_or_rcvr) + None => self.tcx.tables().expr_ty_adjusted(func_or_rcvr) }; let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index af994e884fe47..689f45cd709d5 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1256,26 +1256,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.region_vars.new_bound(debruijn) } - /// Apply `adjustment` to the type of `expr` - pub fn adjust_expr_ty(&self, - expr: &hir::Expr, - adjustment: Option<&adjustment::AutoAdjustment<'tcx>>) - -> Ty<'tcx> - { - let raw_ty = self.expr_ty(expr); - let raw_ty = self.shallow_resolve(raw_ty); - let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty); - raw_ty.adjust(self.tcx, - expr.span, - expr.id, - adjustment, - |method_call| self.tables - .borrow() - .method_map - .get(&method_call) - .map(|method| resolve_ty(method.ty))) - } - /// True if errors have been reported since this infcx was /// created. This is sometimes used as a heuristic to skip /// reporting errors that often occur as a result of earlier @@ -1612,7 +1592,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult> { - let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id)); + let ty = self.tables.borrow().expr_ty_adjusted(expr); self.resolve_type_vars_or_error(&ty) } @@ -1656,9 +1636,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .map(|method| method.def_id) } - pub fn adjustments(&self) -> Ref>> { + pub fn adjustments(&self) -> Ref>> { fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) - -> &'a NodeMap> { + -> &'a NodeMap> { &tables.adjustments } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index dc634b08784a4..4212b1fb05ee3 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { match def { Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_) if self.tcx.trait_of_item(def.def_id()).is_some() => { - if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) { + if let Some(substs) = self.tcx.tables().item_substs.get(&id) { if let ty::TyAdt(tyid, _) = substs.substs.type_at(0).sty { self.check_def_id(tyid.did); } @@ -123,12 +123,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn lookup_and_handle_method(&mut self, id: ast::NodeId) { let method_call = ty::MethodCall::expr(id); - let method = self.tcx.tables.borrow().method_map[&method_call]; + let method = self.tcx.tables().method_map[&method_call]; self.check_def_id(method.def_id); } fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) { - match self.tcx.expr_ty_adjusted(lhs).sty { + match self.tcx.tables().expr_ty_adjusted(lhs).sty { ty::TyAdt(def, _) => { self.insert_def_id(def.struct_variant().field_named(name).did); } @@ -137,7 +137,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) { - match self.tcx.expr_ty_adjusted(lhs).sty { + match self.tcx.tables().expr_ty_adjusted(lhs).sty { ty::TyAdt(def, _) => { self.insert_def_id(def.struct_variant().fields[idx].did); } @@ -148,7 +148,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, pats: &[codemap::Spanned]) { - let variant = match self.tcx.node_id_to_type(lhs.id).sty { + let variant = match self.tcx.tables().node_id_to_type(lhs.id).sty { ty::TyAdt(adt, _) => { adt.variant_of_def(self.tcx.expect_def(lhs.id)) } @@ -433,7 +433,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { } fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool { - let field_type = self.tcx.node_id_to_type(field.id); + let field_type = self.tcx.tables().node_id_to_type(field.id); let is_marker_field = match field_type.ty_to_def_id() { Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)), _ => false diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 2a75b6620fd61..8ca3c75eaa4b1 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -159,7 +159,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { match expr.node { hir::ExprMethodCall(..) => { let method_call = MethodCall::expr(expr.id); - let base_type = self.tcx.tables.borrow().method_map[&method_call].ty; + let base_type = self.tcx.tables().method_map[&method_call].ty; debug!("effect: method call case, base type is {:?}", base_type); if type_is_unsafe_function(base_type) { @@ -168,7 +168,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { } } hir::ExprCall(ref base, _) => { - let base_type = self.tcx.expr_ty_adjusted(base); + let base_type = self.tcx.tables().expr_ty_adjusted(base); debug!("effect: call case, base type is {:?}", base_type); if type_is_unsafe_function(base_type) { @@ -176,7 +176,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { } } hir::ExprUnary(hir::UnDeref, ref base) => { - let base_type = self.tcx.expr_ty_adjusted(base); + let base_type = self.tcx.tables().expr_ty_adjusted(base); debug!("effect: unary case, base type is {:?}", base_type); if let ty::TyRawPtr(_) = base_type.sty { @@ -200,7 +200,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { } } hir::ExprField(ref base_expr, field) => { - if let ty::TyAdt(adt, ..) = self.tcx.expr_ty_adjusted(base_expr).sty { + if let ty::TyAdt(adt, ..) = self.tcx.tables().expr_ty_adjusted(base_expr).sty { if adt.is_union() { self.require_unsafe(field.span, "access to union field"); } @@ -214,7 +214,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { fn visit_pat(&mut self, pat: &hir::Pat) { if let PatKind::Struct(_, ref fields, _) = pat.node { - if let ty::TyAdt(adt, ..) = self.tcx.pat_ty(pat).sty { + if let ty::TyAdt(adt, ..) = self.tcx.tables().pat_ty(pat).sty { if adt.is_union() { for field in fields { self.require_unsafe(field.span, "matching on union field"); diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c37b6df369dfc..0543d1303a5f1 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -720,11 +720,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { //NOTE(@jroesch): mixed RefCell borrow causes crash let adj = infcx.adjustments().get(&expr.id).map(|x| x.clone()); if let Some(adjustment) = adj { - match adjustment { - adjustment::AdjustNeverToAny(..) | - adjustment::AdjustReifyFnPointer | - adjustment::AdjustUnsafeFnPointer | - adjustment::AdjustMutToConstPointer => { + match adjustment.kind { + adjustment::Adjust::NeverToAny | + adjustment::Adjust::ReifyFnPointer | + adjustment::Adjust::UnsafeFnPointer | + adjustment::Adjust::MutToConstPointer => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. debug!("walk_adjustment: trivial adjustment"); @@ -732,8 +732,21 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { return_if_err!(self.mc.cat_expr_unadjusted(expr)); self.delegate_consume(expr.id, expr.span, cmt_unadjusted); } - adjustment::AdjustDerefRef(ref adj) => { - self.walk_autoderefref(expr, adj); + adjustment::Adjust::DerefRef { autoderefs, autoref, unsize } => { + debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); + + self.walk_autoderefs(expr, autoderefs); + + let cmt_derefd = + return_if_err!(self.mc.cat_expr_autoderefd(expr, autoderefs)); + + let cmt_refd = + self.walk_autoref(expr, cmt_derefd, autoref); + + if unsize { + // Unsizing consumes the thin pointer and produces a fat one. + self.delegate_consume(expr.id, expr.span, cmt_refd); + } } } } @@ -770,28 +783,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } } - fn walk_autoderefref(&mut self, - expr: &hir::Expr, - adj: &adjustment::AutoDerefRef<'tcx>) { - debug!("walk_autoderefref expr={:?} adj={:?}", - expr, - adj); - - self.walk_autoderefs(expr, adj.autoderefs); - - let cmt_derefd = - return_if_err!(self.mc.cat_expr_autoderefd(expr, adj.autoderefs)); - - let cmt_refd = - self.walk_autoref(expr, cmt_derefd, adj.autoref); - - if adj.unsize.is_some() { - // Unsizing consumes the thin pointer and produces a fat one. - self.delegate_consume(expr.id, expr.span, cmt_refd); - } - } - - /// Walks the autoref `opt_autoref` applied to the autoderef'd /// `expr`. `cmt_derefd` is the mem-categorized form of `expr` /// after all relevant autoderefs have occurred. Because AutoRefs @@ -803,7 +794,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn walk_autoref(&mut self, expr: &hir::Expr, cmt_base: mc::cmt<'tcx>, - opt_autoref: Option>) + opt_autoref: Option>) -> mc::cmt<'tcx> { debug!("walk_autoref(expr.id={} cmt_derefd={:?} opt_autoref={:?})", @@ -822,7 +813,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { }; match *autoref { - adjustment::AutoPtr(r, m) => { + adjustment::AutoBorrow::Ref(r, m) => { self.delegate.borrow(expr.id, expr.span, cmt_base, @@ -831,7 +822,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { AutoRef); } - adjustment::AutoUnsafe(m) => { + adjustment::AutoBorrow::RawPtr(m) => { debug!("walk_autoref: expr.id={} cmt_base={:?}", expr.id, cmt_base); diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 1acd0fb0f79c0..57503398cfe57 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -163,7 +163,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> { if let hir::ExprPath(..) = expr.node { match self.infcx.tcx.expect_def(expr.id) { Def::Fn(did) if self.def_id_is_transmute(did) => { - let typ = self.infcx.tcx.node_id_to_type(expr.id); + let typ = self.infcx.tcx.tables().node_id_to_type(expr.id); match typ.sty { ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => { let from = bare_fn_ty.sig.0.inputs[0]; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 79396b9ca4dab..46bea00cca3cb 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1081,7 +1081,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprAssignOp(_, ref l, ref r) => { // an overloaded assign op is like a method call - if self.ir.tcx.is_method_call(expr.id) { + if self.ir.tcx.tables().is_method_call(expr.id) { let succ = self.propagate_through_expr(&l, succ); self.propagate_through_expr(&r, succ) } else { @@ -1113,8 +1113,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprCall(ref f, ref args) => { // FIXME(canndrew): This is_never should really be an is_uninhabited - let diverges = !self.ir.tcx.is_method_call(expr.id) && - self.ir.tcx.expr_ty_adjusted(&f).fn_ret().0.is_never(); + let diverges = !self.ir.tcx.tables().is_method_call(expr.id) && + self.ir.tcx.tables().expr_ty_adjusted(&f).fn_ret().0.is_never(); let succ = if diverges { self.s.exit_ln } else { @@ -1126,7 +1126,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 method_ty = self.ir.tcx.tables().method_map[&method_call].ty; // FIXME(canndrew): This is_never should really be an is_uninhabited let succ = if method_ty.fn_ret().0.is_never() { self.s.exit_ln @@ -1409,7 +1409,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { } hir::ExprAssignOp(_, ref l, _) => { - if !this.ir.tcx.is_method_call(expr.id) { + if !this.ir.tcx.tables().is_method_call(expr.id) { this.check_lvalue(&l); } @@ -1459,7 +1459,7 @@ fn check_fn(_v: &Liveness, impl<'a, 'tcx> Liveness<'a, 'tcx> { fn fn_ret(&self, id: NodeId) -> ty::Binder> { - let fn_ty = self.ir.tcx.node_id_to_type(id); + let fn_ty = self.ir.tcx.tables().node_id_to_type(id); match fn_ty.sty { ty::TyClosure(closure_def_id, substs) => self.ir.tcx.closure_type(closure_def_id, substs).sig.output(), @@ -1502,7 +1502,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { None if !body.stmts.is_empty() => match body.stmts.last().unwrap().node { hir::StmtSemi(ref e, _) => { - self.ir.tcx.expr_ty(&e) == fn_ret + self.ir.tcx.tables().expr_ty(&e) == fn_ret }, _ => false }, diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 9214138d21077..e3ed13e1e4017 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -354,11 +354,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult> { - let unadjusted_ty = self.expr_ty(expr)?; - Ok(unadjusted_ty.adjust( - self.tcx(), expr.span, expr.id, - self.infcx.adjustments().get(&expr.id), - |method_call| self.infcx.node_method_ty(method_call))) + self.infcx.expr_ty_adjusted(expr) } fn node_ty(&self, id: ast::NodeId) -> McResult> { @@ -396,19 +392,21 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Some(adjustment) => { - match *adjustment { - adjustment::AdjustDerefRef( - adjustment::AutoDerefRef { - autoref: None, unsize: None, autoderefs, ..}) => { + match adjustment.kind { + adjustment::Adjust::DerefRef { + autoderefs, + autoref: None, + unsize: false + } => { // Equivalent to *expr or something similar. self.cat_expr_autoderefd(expr, autoderefs) } - adjustment::AdjustNeverToAny(..) | - adjustment::AdjustReifyFnPointer | - adjustment::AdjustUnsafeFnPointer | - adjustment::AdjustMutToConstPointer | - adjustment::AdjustDerefRef(_) => { + adjustment::Adjust::NeverToAny | + adjustment::Adjust::ReifyFnPointer | + adjustment::Adjust::UnsafeFnPointer | + adjustment::Adjust::MutToConstPointer | + adjustment::Adjust::DerefRef {..} => { debug!("cat_expr({:?}): {:?}", adjustment, expr); diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index a476d0f6f30a6..1a50d7aa0adc7 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { } hir::ExprMethodCall(..) => { let method_call = ty::MethodCall::expr(expr.id); - let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id; + let def_id = self.tcx.tables().method_map[&method_call].def_id; // Mark the trait item (and, possibly, its default impl) as reachable // Or mark inherent impl item as reachable diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 5192575972b02..fd17e378787a5 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -555,11 +555,11 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr, hir::ExprMethodCall(i, ..) => { span = i.span; let method_call = ty::MethodCall::expr(e.id); - tcx.tables.borrow().method_map[&method_call].def_id + tcx.tables().method_map[&method_call].def_id } hir::ExprField(ref base_e, ref field) => { span = field.span; - match tcx.expr_ty_adjusted(base_e).sty { + match tcx.tables().expr_ty_adjusted(base_e).sty { ty::TyAdt(def, _) => { def.struct_variant().field_named(field.node).did } @@ -569,7 +569,7 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr, } hir::ExprTupField(ref base_e, ref field) => { span = field.span; - match tcx.expr_ty_adjusted(base_e).sty { + match tcx.tables().expr_ty_adjusted(base_e).sty { ty::TyAdt(def, _) => { def.struct_variant().fields[field.node].did } @@ -580,7 +580,7 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr, } } hir::ExprStruct(_, ref expr_fields, _) => { - match tcx.expr_ty(e).sty { + match tcx.tables().expr_ty(e).sty { ty::TyAdt(adt, ..) => match adt.adt_kind() { AdtKind::Struct | AdtKind::Union => { // check the stability of each field that appears @@ -637,7 +637,7 @@ pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat, debug!("check_pat(pat = {:?})", pat); if is_internal(tcx, pat.span) { return; } - let v = match tcx.pat_ty_opt(pat).map(|ty| &ty.sty) { + let v = match tcx.tables().pat_ty_opt(pat).map(|ty| &ty.sty) { Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => adt.struct_variant(), _ => return, }; diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index cfe370343ae49..333a5c74cb45c 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -8,10 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::AutoAdjustment::*; -pub use self::AutoRef::*; - -use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFoldable}; +use ty::{self, Ty, TyCtxt, TypeAndMut}; use ty::LvaluePreference::{NoPreference}; use syntax::ast; @@ -20,116 +17,122 @@ use syntax_pos::Span; use hir; #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -pub enum AutoAdjustment<'tcx> { - AdjustNeverToAny(Ty<'tcx>), // go from ! to any type - AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type - AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer - AdjustMutToConstPointer, // go from a mut raw pointer to a const raw pointer - AdjustDerefRef(AutoDerefRef<'tcx>), +pub struct Adjustment<'tcx> { + pub kind: Adjust<'tcx>, + pub target: Ty<'tcx> } -/// Represents coercing a pointer to a different kind of pointer - where 'kind' -/// here means either or both of raw vs borrowed vs unique and fat vs thin. -/// -/// We transform pointers by following the following steps in order: -/// 1. Deref the pointer `self.autoderefs` times (may be 0). -/// 2. If `autoref` is `Some(_)`, then take the address and produce either a -/// `&` or `*` pointer. -/// 3. If `unsize` is `Some(_)`, then apply the unsize transformation, -/// which will do things like convert thin pointers to fat -/// pointers, or convert structs containing thin pointers to -/// structs containing fat pointers, or convert between fat -/// pointers. We don't store the details of how the transform is -/// done (in fact, we don't know that, because it might depend on -/// the precise type parameters). We just store the target -/// type. Trans figures out what has to be done at monomorphization -/// time based on the precise source/target type at hand. -/// -/// To make that more concrete, here are some common scenarios: -/// -/// 1. The simplest cases are where the pointer is not adjusted fat vs thin. -/// Here the pointer will be dereferenced N times (where a dereference can -/// happen to raw or borrowed pointers or any smart pointer which implements -/// Deref, including Box<_>). The number of dereferences is given by -/// `autoderefs`. It can then be auto-referenced zero or one times, indicated -/// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is -/// None. -/// -/// 2. A thin-to-fat coercon involves unsizing the underlying data. We start -/// with a thin pointer, deref a number of times, unsize the underlying data, -/// then autoref. The 'unsize' phase may change a fixed length array to a -/// dynamically sized one, a concrete object to a trait object, or statically -/// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is -/// represented by: -/// -/// ``` -/// AutoDerefRef { -/// autoderefs: 1, // &[i32; 4] -> [i32; 4] -/// autoref: Some(AutoPtr), // [i32] -> &[i32] -/// unsize: Some([i32]), // [i32; 4] -> [i32] -/// } -/// ``` -/// -/// Note that for a struct, the 'deep' unsizing of the struct is not recorded. -/// E.g., `struct Foo { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]> -/// The autoderef and -ref are the same as in the above example, but the type -/// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about -/// the underlying conversions from `[i32; 4]` to `[i32]`. -/// -/// 3. Coercing a `Box` to `Box` is an interesting special case. In -/// that case, we have the pointer we need coming in, so there are no -/// autoderefs, and no autoref. Instead we just do the `Unsize` transformation. -/// At some point, of course, `Box` should move out of the compiler, in which -/// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> -> -/// Box<[i32]> is represented by: -/// -/// ``` -/// AutoDerefRef { -/// autoderefs: 0, -/// autoref: None, -/// unsize: Some(Box<[i32]>), -/// } -/// ``` -#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -pub struct AutoDerefRef<'tcx> { - /// Step 1. Apply a number of dereferences, producing an lvalue. - pub autoderefs: usize, - - /// Step 2. Optionally produce a pointer/reference from the value. - pub autoref: Option>, - - /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to - /// `&[T]`. The stored type is the target pointer type. Note that - /// the source could be a thin or fat pointer. - pub unsize: Option>, +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] +pub enum Adjust<'tcx> { + /// Go from ! to any type. + NeverToAny, + + /// Go from a fn-item type to a fn-pointer type. + ReifyFnPointer, + + /// Go from a safe fn pointer to an unsafe fn pointer. + UnsafeFnPointer, + + /// Go from a mut raw pointer to a const raw pointer. + MutToConstPointer, + + /// Represents coercing a pointer to a different kind of pointer - where 'kind' + /// here means either or both of raw vs borrowed vs unique and fat vs thin. + /// + /// We transform pointers by following the following steps in order: + /// 1. Deref the pointer `self.autoderefs` times (may be 0). + /// 2. If `autoref` is `Some(_)`, then take the address and produce either a + /// `&` or `*` pointer. + /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation, + /// which will do things like convert thin pointers to fat + /// pointers, or convert structs containing thin pointers to + /// structs containing fat pointers, or convert between fat + /// pointers. We don't store the details of how the transform is + /// done (in fact, we don't know that, because it might depend on + /// the precise type parameters). We just store the target + /// type. Trans figures out what has to be done at monomorphization + /// time based on the precise source/target type at hand. + /// + /// To make that more concrete, here are some common scenarios: + /// + /// 1. The simplest cases are where the pointer is not adjusted fat vs thin. + /// Here the pointer will be dereferenced N times (where a dereference can + /// happen to raw or borrowed pointers or any smart pointer which implements + /// Deref, including Box<_>). The number of dereferences is given by + /// `autoderefs`. It can then be auto-referenced zero or one times, indicated + /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is + /// None. + /// + /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start + /// with a thin pointer, deref a number of times, unsize the underlying data, + /// then autoref. The 'unsize' phase may change a fixed length array to a + /// dynamically sized one, a concrete object to a trait object, or statically + /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is + /// represented by: + /// + /// ``` + /// Adjust::DerefRef { + /// autoderefs: 1, // &[i32; 4] -> [i32; 4] + /// autoref: Some(AutoBorrow::Ref), // [i32] -> &[i32] + /// unsize: Some([i32]), // [i32; 4] -> [i32] + /// } + /// ``` + /// + /// Note that for a struct, the 'deep' unsizing of the struct is not recorded. + /// E.g., `struct Foo { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]> + /// The autoderef and -ref are the same as in the above example, but the type + /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about + /// the underlying conversions from `[i32; 4]` to `[i32]`. + /// + /// 3. Coercing a `Box` to `Box` is an interesting special case. In + /// that case, we have the pointer we need coming in, so there are no + /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation. + /// At some point, of course, `Box` should move out of the compiler, in which + /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> -> + /// Box<[i32]> is represented by: + /// + /// ``` + /// Adjust::DerefRef { + /// autoderefs: 0, + /// autoref: None, + /// unsize: Some(Box<[i32]>), + /// } + /// ``` + DerefRef { + /// Step 1. Apply a number of dereferences, producing an lvalue. + autoderefs: usize, + + /// Step 2. Optionally produce a pointer/reference from the value. + autoref: Option>, + + /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to + /// `&[T]`. Note that the source could be a thin or fat pointer. + unsize: bool, + } } -impl<'tcx> AutoAdjustment<'tcx> { +impl<'tcx> Adjustment<'tcx> { pub fn is_identity(&self) -> bool { - match *self { - AdjustNeverToAny(ty) => ty.is_never(), - AdjustReifyFnPointer | - AdjustUnsafeFnPointer | - AdjustMutToConstPointer => false, - AdjustDerefRef(ref r) => r.is_identity(), + match self.kind { + Adjust::NeverToAny => self.target.is_never(), + + Adjust::DerefRef { autoderefs: 0, autoref: None, unsize: false } => true, + + Adjust::ReifyFnPointer | + Adjust::UnsafeFnPointer | + Adjust::MutToConstPointer | + Adjust::DerefRef {..} => false, } } } -impl<'tcx> AutoDerefRef<'tcx> { - pub fn is_identity(&self) -> bool { - self.autoderefs == 0 && self.unsize.is_none() && self.autoref.is_none() - } -} - #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] -pub enum AutoRef<'tcx> { +pub enum AutoBorrow<'tcx> { /// Convert from T to &T. - AutoPtr(&'tcx ty::Region, hir::Mutability), + Ref(&'tcx ty::Region, hir::Mutability), /// Convert from T to *T. - /// Value to thin pointer. - AutoUnsafe(hir::Mutability), + RawPtr(hir::Mutability), } #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] @@ -139,84 +142,6 @@ pub enum CustomCoerceUnsized { } impl<'a, 'gcx, 'tcx> ty::TyS<'tcx> { - /// See `expr_ty_adjusted` - pub fn adjust(&'tcx self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - span: Span, - expr_id: ast::NodeId, - adjustment: Option<&AutoAdjustment<'tcx>>, - mut method_type: F) - -> Ty<'tcx> where - F: FnMut(ty::MethodCall) -> Option>, - { - if let ty::TyError = self.sty { - return self; - } - - return match adjustment { - Some(adjustment) => { - match *adjustment { - AdjustNeverToAny(ref ty) => ty, - - AdjustReifyFnPointer => { - match self.sty { - ty::TyFnDef(.., f) => tcx.mk_fn_ptr(f), - _ => { - bug!("AdjustReifyFnPointer adjustment on non-fn-item: {:?}", - self); - } - } - } - - AdjustUnsafeFnPointer => { - match self.sty { - ty::TyFnPtr(b) => tcx.safe_to_unsafe_fn_ty(b), - ref b => { - bug!("AdjustUnsafeFnPointer adjustment on non-fn-ptr: {:?}", - b); - } - } - } - - AdjustMutToConstPointer => { - match self.sty { - ty::TyRawPtr(mt) => tcx.mk_ptr(ty::TypeAndMut { - ty: mt.ty, - mutbl: hir::MutImmutable - }), - ref b => { - bug!("AdjustMutToConstPointer on non-raw-ptr: {:?}", - b); - } - } - } - - AdjustDerefRef(ref adj) => { - let mut adjusted_ty = self; - - if !adjusted_ty.references_error() { - for i in 0..adj.autoderefs { - adjusted_ty = - adjusted_ty.adjust_for_autoderef(tcx, - expr_id, - span, - i as u32, - &mut method_type); - } - } - - if let Some(target) = adj.unsize { - target - } else { - adjusted_ty.adjust_for_autoref(tcx, adj.autoref) - } - } - } - } - None => self - }; - } - pub fn adjust_for_autoderef(&'tcx self, tcx: TyCtxt<'a, 'gcx, 'tcx>, expr_id: ast::NodeId, @@ -247,14 +172,14 @@ impl<'a, 'gcx, 'tcx> ty::TyS<'tcx> { } pub fn adjust_for_autoref(&'tcx self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - autoref: Option>) + autoref: Option>) -> Ty<'tcx> { match autoref { None => self, - Some(AutoPtr(r, m)) => { + Some(AutoBorrow::Ref(r, m)) => { tcx.mk_ref(r, TypeAndMut { ty: self, mutbl: m }) } - Some(AutoUnsafe(m)) => { + Some(AutoBorrow::RawPtr(m)) => { tcx.mk_ptr(TypeAndMut { ty: self, mutbl: m }) } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 62cc78141db46..7e5e10435d516 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -41,7 +41,7 @@ use rustc_data_structures::accumulate_vec::AccumulateVec; use arena::TypedArena; use std::borrow::Borrow; -use std::cell::{Cell, RefCell, Ref}; +use std::cell::{Cell, RefCell}; use std::hash::{Hash, Hasher}; use std::mem; use std::ops::Deref; @@ -212,7 +212,7 @@ pub struct Tables<'tcx> { /// other items. pub item_substs: NodeMap>, - pub adjustments: NodeMap>, + pub adjustments: NodeMap>, pub method_map: ty::MethodMap<'tcx>, @@ -255,6 +255,76 @@ impl<'a, 'gcx, 'tcx> Tables<'tcx> { fru_field_types: NodeMap() } } + + pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> { + match self.node_id_to_type_opt(id) { + Some(ty) => ty, + None => { + bug!("node_id_to_type: no type for node `{}`", + tls::with(|tcx| tcx.map.node_to_string(id))) + } + } + } + + pub fn node_id_to_type_opt(&self, id: NodeId) -> Option> { + self.node_types.get(&id).cloned() + } + + pub fn node_id_item_substs(&self, id: NodeId) -> Option<&'tcx Substs<'tcx>> { + self.item_substs.get(&id).map(|ts| ts.substs) + } + + // Returns the type of a pattern as a monotype. Like @expr_ty, this function + // doesn't provide type parameter substitutions. + pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> { + self.node_id_to_type(pat.id) + } + + pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option> { + self.node_id_to_type_opt(pat.id) + } + + // Returns the type of an expression as a monotype. + // + // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in + // some cases, we insert `Adjustment` annotations such as auto-deref or + // auto-ref. The type returned by this function does not consider such + // adjustments. See `expr_ty_adjusted()` instead. + // + // NB (2): This type doesn't provide type parameter substitutions; e.g. if you + // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize" + // instead of "fn(ty) -> T with T = isize". + pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> { + self.node_id_to_type(expr.id) + } + + pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option> { + self.node_id_to_type_opt(expr.id) + } + + /// Returns the type of `expr`, considering any `Adjustment` + /// entry recorded for that expression. + pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> { + self.adjustments.get(&expr.id) + .map_or_else(|| self.expr_ty(expr), |adj| adj.target) + } + + pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr) -> Option> { + self.adjustments.get(&expr.id) + .map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr)) + } + + pub fn is_method_call(&self, expr_id: NodeId) -> bool { + self.method_map.contains_key(&ty::MethodCall::expr(expr_id)) + } + + pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool { + self.method_map.contains_key(&ty::MethodCall::autoderef(expr_id, autoderefs)) + } + + pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option> { + Some(self.upvar_capture_map.get(&upvar_id).unwrap().clone()) + } } impl<'tcx> CommonTypes<'tcx> { @@ -599,14 +669,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.ty_param_defs.borrow().get(&node_id).unwrap().clone() } - pub fn node_types(self) -> Ref<'a, NodeMap>> { - fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap> { - &tables.node_types - } - - Ref::map(self.tables.borrow(), projection) - } - pub fn node_type_insert(self, id: NodeId, ty: Ty<'gcx>) { self.tables.borrow_mut().node_types.insert(id, ty); } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index ae0a4a0e6bd11..b79ebdb14f552 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -176,8 +176,8 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized { r.super_fold_with(self) } - fn fold_autoref(&mut self, ar: &adjustment::AutoRef<'tcx>) - -> adjustment::AutoRef<'tcx> { + fn fold_autoref(&mut self, ar: &adjustment::AutoBorrow<'tcx>) + -> adjustment::AutoBorrow<'tcx> { ar.super_fold_with(self) } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 588857e557c22..2c15f08e89822 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2120,80 +2120,8 @@ impl BorrowKind { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - pub fn node_id_to_type(self, id: NodeId) -> Ty<'gcx> { - match self.node_id_to_type_opt(id) { - Some(ty) => ty, - None => bug!("node_id_to_type: no type for node `{}`", - self.map.node_to_string(id)) - } - } - - pub fn node_id_to_type_opt(self, id: NodeId) -> Option> { - self.tables.borrow().node_types.get(&id).cloned() - } - - pub fn node_id_item_substs(self, id: NodeId) -> ItemSubsts<'gcx> { - match self.tables.borrow().item_substs.get(&id) { - None => ItemSubsts { - substs: self.global_tcx().intern_substs(&[]) - }, - Some(ts) => ts.clone(), - } - } - - // Returns the type of a pattern as a monotype. Like @expr_ty, this function - // doesn't provide type parameter substitutions. - pub fn pat_ty(self, pat: &hir::Pat) -> Ty<'gcx> { - self.node_id_to_type(pat.id) - } - pub fn pat_ty_opt(self, pat: &hir::Pat) -> Option> { - self.node_id_to_type_opt(pat.id) - } - - // Returns the type of an expression as a monotype. - // - // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in - // some cases, we insert `AutoAdjustment` annotations such as auto-deref or - // auto-ref. The type returned by this function does not consider such - // adjustments. See `expr_ty_adjusted()` instead. - // - // NB (2): This type doesn't provide type parameter substitutions; e.g. if you - // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize" - // instead of "fn(ty) -> T with T = isize". - pub fn expr_ty(self, expr: &hir::Expr) -> Ty<'gcx> { - self.node_id_to_type(expr.id) - } - - pub fn expr_ty_opt(self, expr: &hir::Expr) -> Option> { - self.node_id_to_type_opt(expr.id) - } - - /// Returns the type of `expr`, considering any `AutoAdjustment` - /// entry recorded for that expression. - /// - /// It would almost certainly be better to store the adjusted ty in with - /// the `AutoAdjustment`, but I opted not to do this because it would - /// require serializing and deserializing the type and, although that's not - /// hard to do, I just hate that code so much I didn't want to touch it - /// unless it was to fix it properly, which seemed a distraction from the - /// thread at hand! -nmatsakis - pub fn expr_ty_adjusted(self, expr: &hir::Expr) -> Ty<'gcx> { - self.expr_ty(expr) - .adjust(self.global_tcx(), expr.span, expr.id, - self.tables.borrow().adjustments.get(&expr.id), - |method_call| { - self.tables.borrow().method_map.get(&method_call).map(|method| method.ty) - }) - } - - pub fn expr_ty_adjusted_opt(self, expr: &hir::Expr) -> Option> { - self.expr_ty_opt(expr).map(|t| t.adjust(self.global_tcx(), - expr.span, - expr.id, - self.tables.borrow().adjustments.get(&expr.id), - |method_call| { - self.tables.borrow().method_map.get(&method_call).map(|method| method.ty) - })) + pub fn tables(self) -> Ref<'a, Tables<'gcx>> { + self.tables.borrow() } pub fn expr_span(self, id: NodeId) -> Span { @@ -2908,19 +2836,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.mk_region(ty::ReScope(self.region_maps.node_extent(id))) } - pub fn is_method_call(self, expr_id: NodeId) -> bool { - self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id)) - } - - pub fn is_overloaded_autoderef(self, expr_id: NodeId, autoderefs: u32) -> bool { - self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id, - autoderefs)) - } - - pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option> { - Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone()) - } - pub fn visit_all_items_in_krate(self, dep_node_fn: F, visitor: &mut V) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 3165edebf1a46..9ca911837b517 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -218,15 +218,15 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ItemSubsts<'a> { } } -impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoRef<'a> { - type Lifted = ty::adjustment::AutoRef<'tcx>; +impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { + type Lifted = ty::adjustment::AutoBorrow<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { match *self { - ty::adjustment::AutoPtr(r, m) => { - tcx.lift(&r).map(|r| ty::adjustment::AutoPtr(r, m)) + ty::adjustment::AutoBorrow::Ref(r, m) => { + tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m)) } - ty::adjustment::AutoUnsafe(m) => { - Some(ty::adjustment::AutoUnsafe(m)) + ty::adjustment::AutoBorrow::RawPtr(m) => { + Some(ty::adjustment::AutoBorrow::RawPtr(m)) } } } @@ -676,13 +676,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> { +impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { - ty::adjustment::AutoPtr(ref r, m) => { - ty::adjustment::AutoPtr(r.fold_with(folder), m) + ty::adjustment::AutoBorrow::Ref(ref r, m) => { + ty::adjustment::AutoBorrow::Ref(r.fold_with(folder), m) } - ty::adjustment::AutoUnsafe(m) => ty::adjustment::AutoUnsafe(m) + ty::adjustment::AutoBorrow::RawPtr(m) => ty::adjustment::AutoBorrow::RawPtr(m) } } @@ -692,8 +692,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { - ty::adjustment::AutoPtr(r, _m) => r.visit_with(visitor), - ty::adjustment::AutoUnsafe(_m) => false, + ty::adjustment::AutoBorrow::Ref(r, _m) => r.visit_with(visitor), + ty::adjustment::AutoBorrow::RawPtr(_m) => false, } } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 5ca567410291a..2ad2a23489de4 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -436,32 +436,9 @@ impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> { } } -impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> { +impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::adjustment::AdjustNeverToAny(ref target) => { - write!(f, "AdjustNeverToAny({:?})", target) - } - ty::adjustment::AdjustReifyFnPointer => { - write!(f, "AdjustReifyFnPointer") - } - ty::adjustment::AdjustUnsafeFnPointer => { - write!(f, "AdjustUnsafeFnPointer") - } - ty::adjustment::AdjustMutToConstPointer => { - write!(f, "AdjustMutToConstPointer") - } - ty::adjustment::AdjustDerefRef(ref data) => { - write!(f, "{:?}", data) - } - } - } -} - -impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "AutoDerefRef({}, unsize={:?}, {:?})", - self.autoderefs, self.unsize, self.autoref) + write!(f, "{:?} -> {}", self.kind, self.target) } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 9bdc6887f6d03..51574868f9bfb 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -37,7 +37,7 @@ pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, decl_id: ast::NodeId, _decl_span: Span, var_id: ast::NodeId) { - let ty = bccx.tcx.node_id_to_type(var_id); + let ty = bccx.tcx.tables().node_id_to_type(var_id); let loan_path = Rc::new(LoanPath::new(LpVar(var_id), ty)); move_data.add_move(bccx.tcx, loan_path, decl_id, Declared); } diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 9aa1ac62f5523..615aca90db8bf 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -201,7 +201,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { // Finally, check if the whole match expression is exhaustive. // Check for empty enum, because is_useful only works on inhabited types. - let pat_ty = self.tcx.node_id_to_type(scrut.id); + let pat_ty = self.tcx.tables().node_id_to_type(scrut.id); if inlined_arms.is_empty() { if !pat_ty.is_uninhabited(self.tcx) { // We know the type is inhabited, so this must be wrong @@ -262,7 +262,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) { pat.walk(|p| { if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node { - let pat_ty = cx.tcx.pat_ty(p); + let pat_ty = cx.tcx.tables().pat_ty(p); if let ty::TyAdt(edef, _) = pat_ty.sty { if edef.is_enum() { if let Def::Local(..) = cx.tcx.expect_def(p.id) { @@ -486,7 +486,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, for pat in pats { pat.walk(|p| { if let PatKind::Binding(hir::BindByValue(..), _, ref sub) = p.node { - let pat_ty = cx.tcx.node_id_to_type(p.id); + let pat_ty = cx.tcx.tables().node_id_to_type(p.id); if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index c02cca0da7225..1f66d71406826 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -246,7 +246,7 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat_id: ast::NodeId, span: Span) -> Result, DefId> { - let pat_ty = tcx.expr_ty(expr); + let pat_ty = tcx.tables().expr_ty(expr); debug!("expr={:?} pat_ty={:?} pat_id={}", expr, pat_ty, pat_id); match pat_ty.sty { ty::TyFloat(_) => { @@ -329,7 +329,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Def::StructCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Const) => PatKind::Path(None, path.clone()), Def::Const(def_id) | Def::AssociatedConst(def_id) => { - let substs = Some(tcx.node_id_item_substs(expr.id).substs); + let substs = Some(tcx.tables().node_id_item_substs(expr.id) + .unwrap_or_else(|| tcx.intern_substs(&[]))); let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap(); return const_expr_to_pat(tcx, expr, pat_id, span); }, @@ -606,7 +607,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let ety = match ty_hint { ExprTypeChecked => { // After type-checking, expr_ty is guaranteed to succeed. - Some(tcx.expr_ty(e)) + Some(tcx.tables().expr_ty(e)) } UncheckedExprHint(ty) => { // Use the type hint; it's not guaranteed to be right, but it's @@ -617,7 +618,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // This expression might not be type-checked, and we have no hint. // Try to query the context for a type anyway; we might get lucky // (for example, if the expression was imported from another crate). - tcx.expr_ty_opt(e) + tcx.tables().expr_ty_opt(e) } }; let result = match e.node { @@ -759,7 +760,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let base_hint = if let ExprTypeChecked = ty_hint { ExprTypeChecked } else { - match tcx.expr_ty_opt(&base) { + match tcx.tables().expr_ty_opt(&base) { Some(t) => UncheckedExprHint(t), None => ty_hint } @@ -798,7 +799,8 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Def::Const(def_id) | Def::AssociatedConst(def_id) => { let substs = if let ExprTypeChecked = ty_hint { - Some(tcx.node_id_item_substs(e.id).substs) + Some(tcx.tables().node_id_item_substs(e.id) + .unwrap_or_else(|| tcx.intern_substs(&[]))) } else { None }; diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 946a397474765..10b2a7625cacf 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> { - let mut ty = self.tcx.node_id_to_type(pat.id); + let mut ty = self.tcx.tables().node_id_to_type(pat.id); let kind = match pat.node { PatKind::Wild => PatternKind::Wild, @@ -167,8 +167,9 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { match self.tcx.expect_def(pat.id) { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let tcx = self.tcx.global_tcx(); - let substs = Some(self.tcx.node_id_item_substs(pat.id).substs); - match eval::lookup_const_by_id(tcx, def_id, substs) { + let substs = tcx.tables().node_id_item_substs(pat.id) + .unwrap_or_else(|| tcx.intern_substs(&[])); + match eval::lookup_const_by_id(tcx, def_id, Some(substs)) { Some((const_expr, _const_ty)) => { match eval::const_expr_to_pat( tcx, const_expr, pat.id, pat.span) @@ -197,7 +198,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } PatKind::Slice(ref prefix, ref slice, ref suffix) => { - let ty = self.tcx.node_id_to_type(pat.id); + let ty = self.tcx.tables().node_id_to_type(pat.id); match ty.sty { ty::TyRef(_, mt) => PatternKind::Deref { @@ -222,7 +223,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } PatKind::Tuple(ref subpatterns, ddpos) => { - match self.tcx.node_id_to_type(pat.id).sty { + match self.tcx.tables().node_id_to_type(pat.id).sty { ty::TyTuple(ref tys) => { let subpatterns = subpatterns.iter() @@ -243,7 +244,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { PatKind::Binding(bm, ref ident, ref sub) => { let def_id = self.tcx.expect_def(pat.id).def_id(); let id = self.tcx.map.as_local_node_id(def_id).unwrap(); - let var_ty = self.tcx.node_id_to_type(pat.id); + let var_ty = self.tcx.tables().node_id_to_type(pat.id); let region = match var_ty.sty { ty::TyRef(r, _) => Some(r), _ => None, @@ -280,7 +281,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } PatKind::TupleStruct(_, ref subpatterns, ddpos) => { - let pat_ty = self.tcx.node_id_to_type(pat.id); + let pat_ty = self.tcx.tables().node_id_to_type(pat.id); let adt_def = match pat_ty.sty { ty::TyAdt(adt_def, _) => adt_def, _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"), @@ -299,7 +300,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } PatKind::Struct(_, ref fields, _) => { - let pat_ty = self.tcx.node_id_to_type(pat.id); + let pat_ty = self.tcx.tables().node_id_to_type(pat.id); let adt_def = match pat_ty.sty { ty::TyAdt(adt_def, _) => adt_def, _ => { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 10ff7dc89f9a3..8dee9b6ddd44d 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -501,7 +501,7 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { pp::space(&mut s.s)?; pp::word(&mut s.s, "as")?; pp::space(&mut s.s)?; - pp::word(&mut s.s, &self.tcx.expr_ty(expr).to_string())?; + pp::word(&mut s.s, &self.tcx.tables().expr_ty(expr).to_string())?; s.pclose() } _ => Ok(()), diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index eee34324a6583..b3c0e9ef2b727 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -34,7 +34,6 @@ use middle::stability; use rustc::cfg; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::adjustment; use rustc::traits::{self, Reveal}; use rustc::hir::map as hir_map; use util::nodemap::NodeSet; @@ -118,7 +117,9 @@ impl LateLintPass for BoxPointers { hir::ItemTy(..) | hir::ItemEnum(..) | hir::ItemStruct(..) | - hir::ItemUnion(..) => self.check_heap_type(cx, it.span, cx.tcx.node_id_to_type(it.id)), + hir::ItemUnion(..) => { + self.check_heap_type(cx, it.span, cx.tcx.tables().node_id_to_type(it.id)) + } _ => (), } @@ -129,7 +130,7 @@ impl LateLintPass for BoxPointers { for struct_field in struct_def.fields() { self.check_heap_type(cx, struct_field.span, - cx.tcx.node_id_to_type(struct_field.id)); + cx.tcx.tables().node_id_to_type(struct_field.id)); } } _ => (), @@ -137,7 +138,7 @@ impl LateLintPass for BoxPointers { } fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { - let ty = cx.tcx.node_id_to_type(e.id); + let ty = cx.tcx.tables().node_id_to_type(e.id); self.check_heap_type(cx, e.span, ty); } } @@ -585,7 +586,7 @@ impl LateLintPass for MissingDebugImplementations { let mut impls = NodeSet(); debug_def.for_each_impl(cx.tcx, |d| { if let Some(n) = cx.tcx.map.as_local_node_id(d) { - if let Some(ty_def) = cx.tcx.node_id_to_type(n).ty_to_def_id() { + if let Some(ty_def) = cx.tcx.tables().node_id_to_type(n).ty_to_def_id() { if let Some(node_id) = cx.tcx.map.as_local_node_id(ty_def) { impls.insert(node_id); } @@ -939,8 +940,10 @@ impl LateLintPass for UnconditionalRecursion { method: &ty::Method, id: ast::NodeId) -> bool { + use rustc::ty::adjustment::*; + // Check for method calls and overloaded operators. - let opt_m = tcx.tables.borrow().method_map.get(&ty::MethodCall::expr(id)).cloned(); + let opt_m = tcx.tables().method_map.get(&ty::MethodCall::expr(id)).cloned(); if let Some(m) = opt_m { if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) { return true; @@ -948,15 +951,12 @@ impl LateLintPass for UnconditionalRecursion { } // Check for overloaded autoderef method calls. - let opt_adj = tcx.tables.borrow().adjustments.get(&id).cloned(); - if let Some(adjustment::AdjustDerefRef(adj)) = opt_adj { - for i in 0..adj.autoderefs { + let opt_adj = tcx.tables().adjustments.get(&id).cloned(); + if let Some(Adjustment { kind: Adjust::DerefRef { autoderefs, .. }, .. }) = opt_adj { + for i in 0..autoderefs { let method_call = ty::MethodCall::autoderef(id, i as u32); - if let Some(m) = tcx.tables - .borrow() - .method_map - .get(&method_call) - .cloned() { + if let Some(m) = tcx.tables().method_map.get(&method_call) + .cloned() { if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) { return true; } @@ -971,12 +971,10 @@ impl LateLintPass for UnconditionalRecursion { // it doesn't necessarily have a definition. match tcx.expect_def_or_none(callee.id) { Some(Def::Method(def_id)) => { - let item_substs = tcx.node_id_item_substs(callee.id); - method_call_refers_to_method(tcx, - method, - def_id, - &item_substs.substs, - id) + let substs = tcx.tables().node_id_item_substs(callee.id) + .unwrap_or_else(|| tcx.intern_substs(&[])); + method_call_refers_to_method( + tcx, method, def_id, substs, id) } _ => false, } @@ -1213,7 +1211,7 @@ impl LateLintPass for MutableTransmutes { if !def_id_is_transmute(cx, did) { return None; } - let typ = cx.tcx.node_id_to_type(expr.id); + let typ = cx.tcx.tables().node_id_to_type(expr.id); match typ.sty { ty::TyFnDef(.., ref bare_fn) if bare_fn.abi == RustIntrinsic => { let from = bare_fn.sig.0.inputs[0]; @@ -1284,7 +1282,7 @@ impl LateLintPass for UnionsWithDropFields { if let hir::ItemUnion(ref vdata, _) = item.node { let param_env = &ty::ParameterEnvironment::for_item(ctx.tcx, item.id); for field in vdata.fields() { - let field_ty = ctx.tcx.node_id_to_type(field.id); + let field_ty = ctx.tcx.tables().node_id_to_type(field.id); if ctx.tcx.type_needs_drop_given_env(field_ty, param_env) { ctx.span_lint(UNIONS_WITH_DROP_FIELDS, field.span, diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 9464bf30b693f..b04759955a956 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -113,14 +113,14 @@ impl LateLintPass for TypeLimits { forbid_unsigned_negation(cx, e.span); } ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => { - if let ty::TyUint(_) = cx.tcx.node_id_to_type(e.id).sty { + if let ty::TyUint(_) = cx.tcx.tables().node_id_to_type(e.id).sty { forbid_unsigned_negation(cx, e.span); } } _ => (), } } else { - let t = cx.tcx.node_id_to_type(expr.id); + let t = cx.tcx.tables().node_id_to_type(expr.id); if let ty::TyUint(_) = t.sty { forbid_unsigned_negation(cx, e.span); } @@ -138,7 +138,7 @@ impl LateLintPass for TypeLimits { } if binop.node.is_shift() { - let opt_ty_bits = match cx.tcx.node_id_to_type(l.id).sty { + let opt_ty_bits = match cx.tcx.tables().node_id_to_type(l.id).sty { ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)), ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)), _ => None, @@ -171,7 +171,7 @@ impl LateLintPass for TypeLimits { } } hir::ExprLit(ref lit) => { - match cx.tcx.node_id_to_type(e.id).sty { + match cx.tcx.tables().node_id_to_type(e.id).sty { ty::TyInt(t) => { match lit.node { ast::LitKind::Int(v, ast::LitIntType::Signed(_)) | @@ -324,7 +324,7 @@ impl LateLintPass for TypeLimits { // Normalize the binop so that the literal is always on the RHS in // the comparison let norm_binop = if swap { rev_binop(binop) } else { binop }; - match tcx.node_id_to_type(expr.id).sty { + match tcx.tables().node_id_to_type(expr.id).sty { ty::TyInt(int_ty) => { let (min, max) = int_ty_range(int_ty); let lit_val: i64 = match lit.node { @@ -740,7 +740,7 @@ impl LateLintPass for VariantSizeDifferences { if let hir::ItemEnum(ref enum_definition, ref gens) = it.node { if gens.ty_params.is_empty() { // sizes only make sense for non-generic types - let t = cx.tcx.node_id_to_type(it.id); + let t = cx.tcx.tables().node_id_to_type(it.id); let layout = cx.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| { let ty = cx.tcx.erase_regions(&t); ty.layout(&infcx) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index a29ff18ab5318..15430a5c9f99d 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -140,7 +140,7 @@ impl LateLintPass for UnusedResults { return; } - let t = cx.tcx.expr_ty(&expr); + let t = cx.tcx.tables().expr_ty(&expr); let warned = match t.sty { ty::TyTuple(ref tys) if tys.is_empty() => return, ty::TyNever => return, @@ -441,16 +441,15 @@ impl LateLintPass for UnusedAllocation { _ => return, } - if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) { - if let adjustment::AdjustDerefRef(adjustment::AutoDerefRef { ref autoref, .. }) = - *adjustment { + if let Some(adjustment) = cx.tcx.tables().adjustments.get(&e.id) { + if let adjustment::Adjust::DerefRef { autoref, .. } = adjustment.kind { match autoref { - &Some(adjustment::AutoPtr(_, hir::MutImmutable)) => { + Some(adjustment::AutoBorrow::Ref(_, hir::MutImmutable)) => { cx.span_lint(UNUSED_ALLOCATION, e.span, "unnecessary allocation, use & instead"); } - &Some(adjustment::AutoPtr(_, hir::MutMutable)) => { + Some(adjustment::AutoBorrow::Ref(_, hir::MutMutable)) => { cx.span_lint(UNUSED_ALLOCATION, e.span, "unnecessary allocation, use &mut instead"); diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index f001f85131978..e009955b92ee4 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -38,7 +38,7 @@ enum TableEntry<'tcx> { Def(Def), NodeType(Ty<'tcx>), ItemSubsts(ty::ItemSubsts<'tcx>), - Adjustment(ty::adjustment::AutoAdjustment<'tcx>), + Adjustment(ty::adjustment::Adjustment<'tcx>), ConstQualif(ConstQualif), } @@ -94,9 +94,9 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> }; encode(tcx.expect_def_or_none(id).map(TableEntry::Def)); - encode(tcx.node_types().get(&id).cloned().map(TableEntry::NodeType)); - encode(tcx.tables.borrow().item_substs.get(&id).cloned().map(TableEntry::ItemSubsts)); - encode(tcx.tables.borrow().adjustments.get(&id).cloned().map(TableEntry::Adjustment)); + encode(tcx.tables().node_types.get(&id).cloned().map(TableEntry::NodeType)); + encode(tcx.tables().item_substs.get(&id).cloned().map(TableEntry::ItemSubsts)); + encode(tcx.tables().adjustments.get(&id).cloned().map(TableEntry::Adjustment)); encode(tcx.const_qualif_map.borrow().get(&id).cloned().map(TableEntry::ConstQualif)); } } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e8734e4275712..fdb117ef81b13 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1016,7 +1016,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = ClosureData { kind: tcx.closure_kind(def_id), - ty: self.lazy(&tcx.tables.borrow().closure_tys[&def_id]), + ty: self.lazy(&tcx.tables().closure_tys[&def_id]), }; Entry { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d6fcc79a9a213..b37dd8dd0a907 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -191,7 +191,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, assert_eq!(block, builder.return_block()); let mut spread_arg = None; - match tcx.node_id_to_type(fn_id).sty { + match tcx.tables().node_id_to_type(fn_id).sty { ty::TyFnDef(_, _, f) if f.abi == Abi::RustCall => { // RustCall pseudo-ABI untuples the last argument. spread_arg = Some(Local::new(arguments.len())); @@ -203,7 +203,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| { freevars.iter().map(|fv| { let var_id = tcx.map.as_local_node_id(fv.def.def_id()).unwrap(); - let by_ref = tcx.upvar_capture(ty::UpvarId { + let by_ref = tcx.tables().upvar_capture(ty::UpvarId { var_id: var_id, closure_expr_id: fn_id }).map_or(false, |capture| match capture { @@ -233,7 +233,7 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, ast_expr: &'tcx hir::Expr) -> (Mir<'tcx>, ScopeAuxiliaryVec) { let tcx = hir.tcx(); - let ty = tcx.expr_ty_adjusted(ast_expr); + let ty = tcx.tables().expr_ty_adjusted(ast_expr); let span = tcx.map.span(item_id); let mut builder = Builder::new(hir, span, 0, ty); diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index ec1136368c135..cb69de2cb3cac 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -77,7 +77,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { - let block_ty = cx.tcx.node_id_to_type(block.id); + let block_ty = cx.tcx.tables().node_id_to_type(block.id); let temp_lifetime = cx.tcx.region_maps.temporary_scope(block.id); let expr = Expr { ty: block_ty, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 1b324ac3132fc..ba0d3b49a6c1a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -35,15 +35,15 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span); let mut expr = make_mirror_unadjusted(cx, self); + let adj = cx.tcx.tables().adjustments.get(&self.id).cloned(); debug!("make_mirror: unadjusted-expr={:?} applying adjustments={:?}", - expr, cx.tcx.tables.borrow().adjustments.get(&self.id)); + expr, adj); // Now apply adjustments, if any. - match cx.tcx.tables.borrow().adjustments.get(&self.id) { + match adj.map(|adj| (adj.kind, adj.target)) { None => {} - Some(&ty::adjustment::AdjustReifyFnPointer) => { - let adjusted_ty = cx.tcx.expr_ty_adjusted(self); + Some((ty::adjustment::Adjust::ReifyFnPointer, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, ty: adjusted_ty, @@ -51,8 +51,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::ReifyFnPointer { source: expr.to_ref() }, }; } - Some(&ty::adjustment::AdjustUnsafeFnPointer) => { - let adjusted_ty = cx.tcx.expr_ty_adjusted(self); + Some((ty::adjustment::Adjust::UnsafeFnPointer, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, ty: adjusted_ty, @@ -60,7 +59,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() }, }; } - Some(&ty::adjustment::AdjustNeverToAny(adjusted_ty)) => { + Some((ty::adjustment::Adjust::NeverToAny, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, ty: adjusted_ty, @@ -68,8 +67,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::NeverToAny { source: expr.to_ref() }, }; } - Some(&ty::adjustment::AdjustMutToConstPointer) => { - let adjusted_ty = cx.tcx.expr_ty_adjusted(self); + Some((ty::adjustment::Adjust::MutToConstPointer, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, ty: adjusted_ty, @@ -77,8 +75,9 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::Cast { source: expr.to_ref() }, }; } - Some(&ty::adjustment::AdjustDerefRef(ref adj)) => { - for i in 0..adj.autoderefs { + Some((ty::adjustment::Adjust::DerefRef { autoderefs, autoref, unsize }, + adjusted_ty)) => { + for i in 0..autoderefs { let i = i as u32; let adjusted_ty = expr.ty.adjust_for_autoderef( @@ -86,11 +85,11 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { self.id, self.span, i, - |mc| cx.tcx.tables.borrow().method_map.get(&mc).map(|m| m.ty)); + |mc| cx.tcx.tables().method_map.get(&mc).map(|m| m.ty)); debug!("make_mirror: autoderef #{}, adjusted_ty={:?}", i, adjusted_ty); let method_key = ty::MethodCall::autoderef(self.id, i); let meth_ty = - cx.tcx.tables.borrow().method_map.get(&method_key).map(|m| m.ty); + cx.tcx.tables().method_map.get(&method_key).map(|m| m.ty); let kind = if let Some(meth_ty) = meth_ty { debug!("make_mirror: overloaded autoderef (meth_ty={:?})", meth_ty); @@ -128,10 +127,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; } - if let Some(autoref) = adj.autoref { + if let Some(autoref) = autoref { let adjusted_ty = expr.ty.adjust_for_autoref(cx.tcx, Some(autoref)); match autoref { - ty::adjustment::AutoPtr(r, m) => { + ty::adjustment::AutoBorrow::Ref(r, m) => { expr = Expr { temp_lifetime: temp_lifetime, ty: adjusted_ty, @@ -143,7 +142,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }, }; } - ty::adjustment::AutoUnsafe(m) => { + ty::adjustment::AutoBorrow::RawPtr(m) => { // Convert this to a suitable `&foo` and // then an unsafe coercion. Limit the region to be just this // expression. @@ -169,10 +168,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { } } - if let Some(target) = adj.unsize { + if unsize { expr = Expr { temp_lifetime: temp_lifetime, - ty: target, + ty: adjusted_ty, span: self.span, kind: ExprKind::Unsize { source: expr.to_ref() }, }; @@ -212,7 +211,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> { - let expr_ty = cx.tcx.expr_ty(expr); + let expr_ty = cx.tcx.tables().expr_ty(expr); let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); let kind = match expr.node { @@ -231,7 +230,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprCall(ref fun, ref args) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { // The callee is something implementing Fn, FnMut, or FnOnce. // Find the actual method implementation being called and // build the appropriate UFCS call expression with the @@ -282,7 +281,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }) } else { None }; if let Some((adt_def, index)) = adt_data { - let substs = cx.tcx.node_id_item_substs(fun.id).substs; + let substs = cx.tcx.tables().node_id_item_substs(fun.id) + .unwrap_or_else(|| cx.tcx.intern_substs(&[])); let field_refs = args.iter().enumerate().map(|(idx, e)| FieldExprRef { name: Field::new(idx), expr: e.to_ref() @@ -296,7 +296,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } else { ExprKind::Call { - ty: cx.tcx.node_id_to_type(fun.id), + ty: cx.tcx.tables().node_id_to_type(fun.id), fun: fun.to_ref(), args: args.to_ref(), } @@ -328,7 +328,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprAssignOp(op, ref lhs, ref rhs) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { @@ -350,7 +350,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }, hir::ExprBinary(op, ref lhs, ref rhs) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { @@ -406,7 +406,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprIndex(ref lhs, ref index) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { overloaded_lvalue(cx, expr, ty::MethodCall::expr(expr.id), PassArgs::ByValue, lhs.to_ref(), vec![index]) } else { @@ -418,7 +418,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprUnary(hir::UnOp::UnDeref, ref arg) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { overloaded_lvalue(cx, expr, ty::MethodCall::expr(expr.id), PassArgs::ByValue, arg.to_ref(), vec![]) } else { @@ -427,7 +427,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprUnary(hir::UnOp::UnNot, ref arg) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id), PassArgs::ByValue, arg.to_ref(), vec![]) } else { @@ -439,7 +439,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => { - if cx.tcx.is_method_call(expr.id) { + if cx.tcx.tables().is_method_call(expr.id) { overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id), PassArgs::ByValue, arg.to_ref(), vec![]) } else { @@ -470,10 +470,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, base: base.as_ref().map(|base| { FruInfo { base: base.to_ref(), - field_types: cx.tcx.tables - .borrow() - .fru_field_types[&expr.id] - .clone() + field_types: + cx.tcx.tables().fru_field_types[&expr.id].clone() } }) } @@ -512,7 +510,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprClosure(..) => { - let closure_ty = cx.tcx.expr_ty(expr); + let closure_ty = cx.tcx.tables().expr_ty(expr); let (def_id, substs) = match closure_ty.sty { ty::TyClosure(def_id, substs) => (def_id, substs), _ => { @@ -551,7 +549,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprRepeat(ref v, ref c) => ExprKind::Repeat { value: v.to_ref(), count: TypedConstVal { - ty: cx.tcx.expr_ty(c), + ty: cx.tcx.tables().expr_ty(c), span: c.span, value: match const_eval::eval_const_expr(cx.tcx.global_tcx(), c) { ConstVal::Integral(ConstInt::Usize(u)) => u, @@ -579,7 +577,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::Loop { condition: None, body: block::to_expr_ref(cx, body) }, hir::ExprField(ref source, name) => { - let index = match cx.tcx.expr_ty_adjusted(source).sty { + let index = match cx.tcx.tables().expr_ty_adjusted(source).sty { ty::TyAdt(adt_def, _) => adt_def.variants[0].index_of_field_named(name.node), ref ty => @@ -631,8 +629,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &hir::Expr, method_call: ty::MethodCall) -> Expr<'tcx> { - let tables = cx.tcx.tables.borrow(); - let callee = &tables.method_map[&method_call]; + let callee = cx.tcx.tables().method_map[&method_call]; let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); Expr { temp_lifetime: temp_lifetime, @@ -666,8 +663,8 @@ fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> ExprKind<'tcx> { - let substs = cx.tcx.node_id_item_substs(expr.id).substs; - // Otherwise there may be def_map borrow conflicts + let substs = cx.tcx.tables().node_id_item_substs(expr.id) + .unwrap_or_else(|| cx.tcx.intern_substs(&[])); let def = cx.tcx.expect_def(expr.id); let def_id = match def { // A regular function, constructor function or a constant. @@ -677,18 +674,20 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Def::Const(def_id) | Def::AssociatedConst(def_id) => def_id, Def::StructCtor(def_id, CtorKind::Const) | - Def::VariantCtor(def_id, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty { - // A unit struct/variant which is used as a value. - // We return a completely different ExprKind here to account for this special case. - ty::TyAdt(adt_def, substs) => return ExprKind::Adt { - adt_def: adt_def, - variant_index: adt_def.variant_index_with_id(def_id), - substs: substs, - fields: vec![], - base: None, - }, - ref sty => bug!("unexpected sty: {:?}", sty) - }, + Def::VariantCtor(def_id, CtorKind::Const) => { + match cx.tcx.tables().node_id_to_type(expr.id).sty { + // A unit struct/variant which is used as a value. + // We return a completely different ExprKind here to account for this special case. + ty::TyAdt(adt_def, substs) => return ExprKind::Adt { + adt_def: adt_def, + variant_index: adt_def.variant_index_with_id(def_id), + substs: substs, + fields: vec![], + base: None, + }, + ref sty => bug!("unexpected sty: {:?}", sty) + } + } Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id, @@ -720,7 +719,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Def::Upvar(def_id, index, closure_expr_id) => { let id_var = cx.tcx.map.as_local_node_id(def_id).unwrap(); debug!("convert_var(upvar({:?}, {:?}, {:?}))", id_var, index, closure_expr_id); - let var_ty = cx.tcx.node_id_to_type(id_var); + let var_ty = cx.tcx.tables().node_id_to_type(id_var); let body_id = match cx.tcx.map.find(closure_expr_id) { Some(map::NodeExpr(expr)) => { @@ -737,7 +736,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }; // FIXME free regions in closures are not right - let closure_ty = cx.tcx.node_id_to_type(closure_expr_id); + let closure_ty = cx.tcx.tables().node_id_to_type(closure_expr_id); // FIXME we're just hard-coding the idea that the // signature will be &self or &mut self and hence will @@ -809,7 +808,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, var_id: id_var, closure_expr_id: closure_expr_id, }; - let upvar_capture = match cx.tcx.upvar_capture(upvar_id) { + let upvar_capture = match cx.tcx.tables().upvar_capture(upvar_id) { Some(c) => c, None => { span_bug!( @@ -893,7 +892,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, argrefs.extend( args.iter() .map(|arg| { - let arg_ty = cx.tcx.expr_ty_adjusted(arg); + let arg_ty = cx.tcx.tables().expr_ty_adjusted(arg); let adjusted_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { ty: arg_ty, @@ -931,9 +930,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // line up (this is because `*x` and `x[y]` represent lvalues): // to find the type &T of the content returned by the method; - let tables = cx.tcx.tables.borrow(); - let callee = &tables.method_map[&method_call]; - let ref_ty = callee.ty.fn_ret(); + let ref_ty = cx.tcx.tables().method_map[&method_call].ty.fn_ret(); let ref_ty = cx.tcx.no_late_bound_regions(&ref_ty).unwrap(); // callees always have all late-bound regions fully instantiated, @@ -962,9 +959,9 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, var_id: id_var, closure_expr_id: closure_expr.id, }; - let upvar_capture = cx.tcx.upvar_capture(upvar_id).unwrap(); + let upvar_capture = cx.tcx.tables().upvar_capture(upvar_id).unwrap(); let temp_lifetime = cx.tcx.region_maps.temporary_scope(closure_expr.id); - let var_ty = cx.tcx.node_id_to_type(id_var); + let var_ty = cx.tcx.tables().node_id_to_type(id_var); let captured_var = Expr { temp_lifetime: temp_lifetime, ty: var_ty, diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index b0e2d6e73d37a..0ffc59fe6bf45 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -214,7 +214,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { id: ast::NodeId) { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) - let fn_sig = match self.tcx.tables.borrow().liberated_fn_sigs.get(&id) { + let fn_sig = match self.tcx.tables().liberated_fn_sigs.get(&id) { Some(f) => f.clone(), None => { span_bug!(span, "no liberated fn sig for {:?}", id); @@ -248,7 +248,7 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, closure_expr_id: ast::NodeId, body_id: ast::NodeId) -> Ty<'tcx> { - let closure_ty = tcx.node_id_to_type(closure_expr_id); + let closure_ty = tcx.tables().node_id_to_type(closure_expr_id); // We're just hard-coding the idea that the signature will be // &self or &mut self and hence will have a bound region with diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 8ad4d7f57a6f0..f23539e88f78d 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { let mut outer = self.qualif; self.qualif = ConstQualif::empty(); - let node_ty = self.tcx.node_id_to_type(ex.id); + let node_ty = self.tcx.tables().node_id_to_type(ex.id); check_expr(self, ex, node_ty); check_adjustments(self, ex); @@ -449,14 +449,14 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node match e.node { hir::ExprUnary(..) | hir::ExprBinary(..) | - hir::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => { + hir::ExprIndex(..) if v.tcx.tables().method_map.contains_key(&method_call) => { v.add_qualif(ConstQualif::NOT_CONST); } hir::ExprBox(_) => { v.add_qualif(ConstQualif::NOT_CONST); } hir::ExprUnary(op, ref inner) => { - match v.tcx.node_id_to_type(inner.id).sty { + match v.tcx.tables().node_id_to_type(inner.id).sty { ty::TyRawPtr(_) => { assert!(op == hir::UnDeref); @@ -466,7 +466,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprBinary(op, ref lhs, _) => { - match v.tcx.node_id_to_type(lhs.id).sty { + match v.tcx.tables().node_id_to_type(lhs.id).sty { ty::TyRawPtr(_) => { assert!(op.node == hir::BiEq || op.node == hir::BiNe || op.node == hir::BiLe || op.node == hir::BiLt || @@ -503,7 +503,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } Def::Const(did) | Def::AssociatedConst(did) => { - let substs = Some(v.tcx.node_id_item_substs(e.id).substs); + let substs = Some(v.tcx.tables().node_id_item_substs(e.id) + .unwrap_or_else(|| v.tcx.intern_substs(&[]))); if let Some((expr, _)) = lookup_const_by_id(v.tcx, did, substs) { let inner = v.global_expr(Mode::Const, expr); v.add_qualif(inner); @@ -555,7 +556,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprMethodCall(..) => { - let method = v.tcx.tables.borrow().method_map[&method_call]; + let method = v.tcx.tables().method_map[&method_call]; let is_const = match v.tcx.impl_or_trait_item(method.def_id).container() { ty::ImplContainer(_) => v.handle_const_fn_call(e, method.def_id, node_ty), ty::TraitContainer(_) => false @@ -565,7 +566,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprStruct(..) => { - if let ty::TyAdt(adt, ..) = v.tcx.expr_ty(e).sty { + if let ty::TyAdt(adt, ..) = v.tcx.tables().expr_ty(e).sty { // unsafe_cell_type doesn't necessarily exist with no_core if Some(adt.did) == v.tcx.lang_items.unsafe_cell_type() { v.add_qualif(ConstQualif::MUTABLE_MEM); @@ -624,16 +625,18 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node /// Check the adjustments of an expression fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) { - match v.tcx.tables.borrow().adjustments.get(&e.id) { + use rustc::ty::adjustment::*; + + match v.tcx.tables().adjustments.get(&e.id).map(|adj| adj.kind) { None | - Some(&ty::adjustment::AdjustNeverToAny(..)) | - Some(&ty::adjustment::AdjustReifyFnPointer) | - Some(&ty::adjustment::AdjustUnsafeFnPointer) | - Some(&ty::adjustment::AdjustMutToConstPointer) => {} + Some(Adjust::NeverToAny) | + Some(Adjust::ReifyFnPointer) | + Some(Adjust::UnsafeFnPointer) | + Some(Adjust::MutToConstPointer) => {} - Some(&ty::adjustment::AdjustDerefRef(ty::adjustment::AutoDerefRef { autoderefs, .. })) => { + Some(Adjust::DerefRef { autoderefs, .. }) => { if (0..autoderefs as u32) - .any(|autoderef| v.tcx.is_overloaded_autoderef(e.id, autoderef)) { + .any(|autoderef| v.tcx.tables().is_overloaded_autoderef(e.id, autoderef)) { v.add_qualif(ConstQualif::NOT_CONST); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 77b3e76fc541f..8fdfecd4a5865 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -430,11 +430,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { match expr.node { hir::ExprMethodCall(..) => { let method_call = ty::MethodCall::expr(expr.id); - let method = self.tcx.tables.borrow().method_map[&method_call]; + let method = self.tcx.tables().method_map[&method_call]; self.check_method(expr.span, method.def_id); } hir::ExprStruct(_, ref expr_fields, _) => { - let adt = self.tcx.expr_ty(expr).ty_adt_def().unwrap(); + let adt = self.tcx.tables().expr_ty(expr).ty_adt_def().unwrap(); let variant = adt.variant_of_def(self.tcx.expect_def(expr.id)); // RFC 736: ensure all unmentioned fields are visible. // Rather than computing the set of unmentioned fields @@ -495,14 +495,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { match pattern.node { PatKind::Struct(_, ref fields, _) => { - let adt = self.tcx.pat_ty(pattern).ty_adt_def().unwrap(); + let adt = self.tcx.tables().pat_ty(pattern).ty_adt_def().unwrap(); let variant = adt.variant_of_def(self.tcx.expect_def(pattern.id)); for field in fields { self.check_field(field.span, adt, variant.field_named(field.node.name)); } } PatKind::TupleStruct(_, ref fields, ddpos) => { - match self.tcx.pat_ty(pattern).sty { + match self.tcx.tables().pat_ty(pattern).sty { // enum fields have no privacy at this time ty::TyAdt(def, _) if !def.is_enum() => { let expected_len = def.struct_variant().fields.len(); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 8a628289b7f94..db4788c3ceadb 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -356,7 +356,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { collector.visit_pat(&arg.pat); let span_utils = self.span.clone(); for &(id, ref p, ..) in &collector.collected_paths { - let typ = self.tcx.node_types().get(&id).unwrap().to_string(); + let typ = self.tcx.tables().node_types.get(&id).unwrap().to_string(); // get the span only for the name of the variable (I hope the path is only ever a // variable name, but who knows?) let sub_span = span_utils.span_for_last_ident(p.span); @@ -988,7 +988,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { match p.node { PatKind::Struct(ref path, ref fields, _) => { visit::walk_path(self, path); - let adt = self.tcx.node_id_to_type(p.id).ty_adt_def().unwrap(); + let adt = self.tcx.tables().node_id_to_type(p.id).ty_adt_def().unwrap(); let variant = adt.variant_of_def(self.tcx.expect_def(p.id)); for &Spanned { node: ref field, span } in fields { @@ -1023,8 +1023,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { ast::Mutability::Immutable => value.to_string(), _ => String::new(), }; - let types = self.tcx.node_types(); - let typ = match types.get(&id) { + let typ = match self.tcx.tables().node_types.get(&id) { Some(typ) => { let typ = typ.to_string(); if !value.is_empty() { @@ -1355,7 +1354,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> } ast::ExprKind::Struct(ref path, ref fields, ref base) => { let hir_expr = self.save_ctxt.tcx.map.expect_expr(ex.id); - let adt = self.tcx.expr_ty(&hir_expr).ty_adt_def().unwrap(); + let adt = self.tcx.tables().expr_ty(&hir_expr).ty_adt_def().unwrap(); let def = self.tcx.expect_def(hir_expr.id); self.process_struct_lit(ex, path, fields, adt.variant_of_def(def), base) } @@ -1381,7 +1380,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> return; } }; - let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty; + let ty = &self.tcx.tables().expr_ty_adjusted(&hir_node).sty; match *ty { ty::TyAdt(def, _) => { let sub_span = self.span.sub_span_after_token(ex.span, token::Dot); @@ -1468,7 +1467,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> } else { "".to_string() }; - let typ = self.tcx.node_types() + let typ = self.tcx.tables().node_types .get(&id).map(|t| t.to_string()).unwrap_or(String::new()); value.push_str(": "); value.push_str(&typ); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 15c74f2ed6ab5..7e008f741624b 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -286,7 +286,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: NodeId) -> Option { if let Some(ident) = field.ident { let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); - let typ = self.tcx.node_types().get(&field.id).unwrap().to_string(); + let typ = self.tcx.tables().node_types.get(&field.id).unwrap().to_string(); let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon); filter!(self.span_utils, sub_span, field.span, None); Some(VariableData { @@ -418,7 +418,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { let hir_node = self.tcx.map.expect_expr(expr.id); - let ty = self.tcx.expr_ty_adjusted_opt(&hir_node); + let ty = self.tcx.tables().expr_ty_adjusted_opt(&hir_node); if ty.is_none() || ty.unwrap().sty == ty::TyError { return None; } @@ -432,7 +432,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { return None; } }; - match self.tcx.expr_ty_adjusted(&hir_node).sty { + match self.tcx.tables().expr_ty_adjusted(&hir_node).sty { ty::TyAdt(def, _) if !def.is_enum() => { let f = def.struct_variant().field_named(ident.node.name); let sub_span = self.span_utils.span_for_last_ident(expr.span); @@ -451,7 +451,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } ast::ExprKind::Struct(ref path, ..) => { - match self.tcx.expr_ty_adjusted(&hir_node).sty { + match self.tcx.tables().expr_ty_adjusted(&hir_node).sty { ty::TyAdt(def, _) if !def.is_enum() => { let sub_span = self.span_utils.span_for_last_ident(path.span); filter!(self.span_utils, sub_span, path.span, None); @@ -472,7 +472,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ExprKind::MethodCall(..) => { let method_call = ty::MethodCall::expr(expr.id); - let method_id = self.tcx.tables.borrow().method_map[&method_call].def_id; + let method_id = self.tcx.tables().method_map[&method_call].def_id; let (def_id, decl_id) = match self.tcx.impl_or_trait_item(method_id).container() { ty::ImplContainer(_) => (Some(method_id), None), ty::TraitContainer(_) => (None, Some(method_id)), diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index cd81d114eb770..ffb13a833a582 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -74,7 +74,7 @@ impl<'tcx> Callee<'tcx> { pub fn method_call<'blk>(bcx: Block<'blk, 'tcx>, method_call: ty::MethodCall) -> Callee<'tcx> { - let method = bcx.tcx().tables.borrow().method_map[&method_call]; + let method = bcx.tcx().tables().method_map[&method_call]; Callee::method(bcx, method) } diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 8348da9f7b7bf..a439d415ede15 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -1082,10 +1082,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemStruct(_, ref generics) | hir::ItemUnion(_, ref generics) => { if !generics.is_parameterized() { - let ty = { - let tables = self.scx.tcx().tables.borrow(); - tables.node_types[&item.id] - }; + let ty = self.scx.tcx().tables().node_types[&item.id]; if self.mode == TransItemCollectionMode::Eager { debug!("RootCollector: ADT drop-glue for {}", diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 863aecc824433..4bb34850e0870 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1765,7 +1765,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, }; let is_local_to_unit = is_node_local_to_unit(cx, node_id); - let variable_type = tcx.erase_regions(&tcx.node_id_to_type(node_id)); + let variable_type = tcx.erase_regions(&tcx.tables().node_id_to_type(node_id)); let type_metadata = type_metadata(cx, variable_type, span); let var_name = tcx.item_name(node_def_id).to_string(); let linkage_name = mangled_name_of_item(cx, node_def_id, ""); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8799050b1b999..2db58ef066296 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1551,7 +1551,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.prohibit_type_params(base_segments); let impl_id = tcx.map.as_local_node_id(def_id).unwrap(); - let ty = tcx.node_id_to_type(impl_id); + let ty = tcx.tables().node_id_to_type(impl_id); if let Some(free_substs) = self.get_free_substs() { ty.subst(tcx, free_substs) } else { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index c5a21d7dd91ce..3cf64fa439d7d 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If the callee is a bare function or a closure, then we're all set. match self.structurally_resolved_type(callee_expr.span, adjusted_ty).sty { ty::TyFnDef(..) | ty::TyFnPtr(_) => { - self.write_autoderef_adjustment(callee_expr.id, autoderefs); + self.write_autoderef_adjustment(callee_expr.id, autoderefs, adjusted_ty); return Some(CallStep::Builtin); } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index ccc944813ff18..16493412d690b 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -65,10 +65,7 @@ use check::FnCtxt; use rustc::hir; use rustc::infer::{Coercion, InferOk, TypeOrigin, TypeTrace}; use rustc::traits::{self, ObligationCause}; -use rustc::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef}; -use rustc::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer}; -use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; -use rustc::ty::adjustment::AdjustNeverToAny; +use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty}; use rustc::ty::fold::TypeFoldable; use rustc::ty::error::TypeError; @@ -93,7 +90,7 @@ impl<'a, 'gcx, 'tcx> Deref for Coerce<'a, 'gcx, 'tcx> { } } -type CoerceResult<'tcx> = RelateResult<'tcx, (Ty<'tcx>, AutoAdjustment<'tcx>)>; +type CoerceResult<'tcx> = RelateResult<'tcx, (Ty<'tcx>, Adjust<'tcx>)>; fn coerce_mutbls<'tcx>(from_mutbl: hir::Mutability, to_mutbl: hir::Mutability) @@ -144,12 +141,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { /// Synthesize an identity adjustment. fn identity(&self, ty: Ty<'tcx>) -> CoerceResult<'tcx> { - Ok((ty, - AdjustDerefRef(AutoDerefRef { - autoderefs: 0, - autoref: None, - unsize: None, - }))) + Ok((ty, Adjust::DerefRef { + autoderefs: 0, + autoref: None, + unsize: false, + })) } fn coerce<'a, E, I>(&self, exprs: &E, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> @@ -166,7 +162,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { } if a.is_never() { - return Ok((b, AdjustNeverToAny(b))); + return Ok((b, Adjust::NeverToAny)); } // Consider coercing the subtype to a DST @@ -396,17 +392,16 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { ty::TyRef(r_borrow, _) => r_borrow, _ => span_bug!(span, "expected a ref type, got {:?}", ty), }; - let autoref = Some(AutoPtr(r_borrow, mt_b.mutbl)); + let autoref = Some(AutoBorrow::Ref(r_borrow, mt_b.mutbl)); debug!("coerce_borrowed_pointer: succeeded ty={:?} autoderefs={:?} autoref={:?}", ty, autoderefs, autoref); - Ok((ty, - AdjustDerefRef(AutoDerefRef { - autoderefs: autoderefs, - autoref: autoref, - unsize: None, - }))) + Ok((ty, Adjust::DerefRef { + autoderefs: autoderefs, + autoref: autoref, + unsize: false, + })) } @@ -437,11 +432,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let coercion = Coercion(self.origin.span()); let r_borrow = self.next_region_var(coercion); - (mt_a.ty, Some(AutoPtr(r_borrow, mt_b.mutbl))) + (mt_a.ty, Some(AutoBorrow::Ref(r_borrow, mt_b.mutbl))) } (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) => { coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?; - (mt_a.ty, Some(AutoUnsafe(mt_b.mutbl))) + (mt_a.ty, Some(AutoBorrow::RawPtr(mt_b.mutbl))) } _ => (source, None), }; @@ -497,13 +492,13 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { *self.unsizing_obligations.borrow_mut() = leftover_predicates; - let adjustment = AutoDerefRef { + let adjustment = Adjust::DerefRef { autoderefs: if reborrow.is_some() { 1 } else { 0 }, autoref: reborrow, - unsize: Some(target), + unsize: true, }; debug!("Success, coerced with {:?}", adjustment); - Ok((target, AdjustDerefRef(adjustment))) + Ok((target, adjustment)) } fn coerce_from_safe_fn(&self, @@ -516,7 +511,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { (hir::Unsafety::Normal, hir::Unsafety::Unsafe) => { let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); return self.unify_and_identity(unsafe_a, b) - .map(|(ty, _)| (ty, AdjustUnsafeFnPointer)); + .map(|(ty, _)| (ty, Adjust::UnsafeFnPointer)); } _ => {} } @@ -555,7 +550,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { ty::TyFnPtr(_) => { let a_fn_pointer = self.tcx.mk_fn_ptr(fn_ty_a); self.coerce_from_safe_fn(a_fn_pointer, fn_ty_a, b) - .map(|(ty, _)| (ty, AdjustReifyFnPointer)) + .map(|(ty, _)| (ty, Adjust::ReifyFnPointer)) } _ => self.unify_and_identity(a, b), } @@ -585,17 +580,17 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { coerce_mutbls(mt_a.mutbl, mutbl_b)?; // Although references and unsafe ptrs have the same - // representation, we still register an AutoDerefRef so that + // representation, we still register an Adjust::DerefRef so that // regionck knows that the region for `a` must be valid here. Ok((ty, if is_ref { - AdjustDerefRef(AutoDerefRef { + Adjust::DerefRef { autoderefs: 1, - autoref: Some(AutoUnsafe(mutbl_b)), - unsize: None, - }) + autoref: Some(AutoBorrow::RawPtr(mutbl_b)), + unsize: false, + } } else if mt_a.mutbl != mutbl_b { - AdjustMutToConstPointer + Adjust::MutToConstPointer } else { noop })) @@ -606,24 +601,25 @@ fn apply<'a, 'b, 'gcx, 'tcx, E, I>(coerce: &mut Coerce<'a, 'gcx, 'tcx>, exprs: &E, a: Ty<'tcx>, b: Ty<'tcx>) - -> CoerceResult<'tcx> + -> RelateResult<'tcx, Adjustment<'tcx>> where E: Fn() -> I, I: IntoIterator { - let (ty, adjustment) = indent(|| coerce.coerce(exprs, a, b))?; + let (ty, adjust) = indent(|| coerce.coerce(exprs, a, b))?; let fcx = coerce.fcx; - if let AdjustDerefRef(auto) = adjustment { - if auto.unsize.is_some() { - let mut obligations = coerce.unsizing_obligations.borrow_mut(); - for obligation in obligations.drain(..) { - fcx.register_predicate(obligation); - } + if let Adjust::DerefRef { unsize: true, .. } = adjust { + let mut obligations = coerce.unsizing_obligations.borrow_mut(); + for obligation in obligations.drain(..) { + fcx.register_predicate(obligation); } } - Ok((ty, adjustment)) + Ok(Adjustment { + kind: adjust, + target: ty + }) } impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { @@ -641,17 +637,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut coerce = Coerce::new(self, TypeOrigin::ExprAssignable(expr.span)); self.commit_if_ok(|_| { - let (ty, adjustment) = apply(&mut coerce, &|| Some(expr), source, target)?; + let adjustment = apply(&mut coerce, &|| Some(expr), source, target)?; if !adjustment.is_identity() { debug!("Success, coerced with {:?}", adjustment); match self.tables.borrow().adjustments.get(&expr.id) { None | - Some(&AdjustNeverToAny(..)) => (), + Some(&Adjustment { kind: Adjust::NeverToAny, .. }) => (), _ => bug!("expr already has an adjustment on it!"), }; self.write_adjustment(expr.id, adjustment); } - Ok(ty) + Ok(adjustment.target) }) } @@ -705,12 +701,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Reify both sides and return the reified fn pointer type. + let fn_ptr = self.tcx.mk_fn_ptr(fty); for expr in exprs().into_iter().chain(Some(new)) { // No adjustments can produce a fn item, so this should never trip. assert!(!self.tables.borrow().adjustments.contains_key(&expr.id)); - self.write_adjustment(expr.id, AdjustReifyFnPointer); + self.write_adjustment(expr.id, Adjustment { + kind: Adjust::ReifyFnPointer, + target: fn_ptr + }); } - return Ok(self.tcx.mk_fn_ptr(fty)); + return Ok(fn_ptr); } _ => {} } @@ -724,11 +724,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if !self.tables.borrow().adjustments.contains_key(&new.id) { let result = self.commit_if_ok(|_| apply(&mut coerce, &|| Some(new), new_ty, prev_ty)); match result { - Ok((ty, adjustment)) => { + Ok(adjustment) => { if !adjustment.is_identity() { self.write_adjustment(new.id, adjustment); } - return Ok(ty); + return Ok(adjustment.target); } Err(e) => first_error = Some(e), } @@ -738,10 +738,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // This requires ensuring there are no coercions applied to *any* of the // previous expressions, other than noop reborrows (ignoring lifetimes). for expr in exprs() { - let noop = match self.tables.borrow().adjustments.get(&expr.id) { - Some(&AdjustDerefRef(AutoDerefRef { autoderefs: 1, - autoref: Some(AutoPtr(_, mutbl_adj)), - unsize: None })) => { + let noop = match self.tables.borrow().adjustments.get(&expr.id).map(|adj| adj.kind) { + Some(Adjust::DerefRef { + autoderefs: 1, + autoref: Some(AutoBorrow::Ref(_, mutbl_adj)), + unsize: false + }) => { match self.node_ty(expr.id).sty { ty::TyRef(_, mt_orig) => { // Reborrow that we can safely ignore. @@ -750,7 +752,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => false, } } - Some(&AdjustNeverToAny(_)) => true, + Some(Adjust::NeverToAny) => true, Some(_) => false, None => true, }; @@ -783,18 +785,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }) } } - Ok((ty, adjustment)) => { + Ok(adjustment) => { if !adjustment.is_identity() { + let mut tables = self.tables.borrow_mut(); for expr in exprs() { - let previous = self.tables.borrow().adjustments.get(&expr.id).cloned(); - if let Some(AdjustNeverToAny(_)) = previous { - self.write_adjustment(expr.id, AdjustNeverToAny(ty)); - } else { - self.write_adjustment(expr.id, adjustment); + if let Some(&mut Adjustment { + kind: Adjust::NeverToAny, + ref mut target + }) = tables.adjustments.get_mut(&expr.id) { + *target = adjustment.target; + continue; } + tables.adjustments.insert(expr.id, adjustment); } } - Ok(ty) + Ok(adjustment.target) } } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 722089cd50c0c..f88bb355d1270 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -15,7 +15,7 @@ use hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, LvaluePreference, NoPreference, PreferMutLvalue, Ty}; -use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr}; +use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use rustc::ty::fold::TypeFoldable; use rustc::infer::{self, InferOk, TypeOrigin}; use syntax_pos::Span; @@ -140,20 +140,19 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { unadjusted_self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>) -> Ty<'tcx> { - let (autoref, unsize) = if let Some(mutbl) = pick.autoref { + let autoref = if let Some(mutbl) = pick.autoref { let region = self.next_region_var(infer::Autoref(self.span)); - let autoref = AutoPtr(region, mutbl); - (Some(autoref), - pick.unsize.map(|target| target.adjust_for_autoref(self.tcx, Some(autoref)))) + Some(AutoBorrow::Ref(region, mutbl)) } else { // No unsizing should be performed without autoref (at // least during method dispach). This is because we // currently only unsize `[T;N]` to `[T]`, and naturally // that must occur being a reference. assert!(pick.unsize.is_none()); - (None, None) + None }; + // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various tables. let mut autoderef = self.autoderef(self.span, unadjusted_self_ty); @@ -163,19 +162,20 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { autoderef.unambiguous_final_ty(); autoderef.finalize(LvaluePreference::NoPreference, Some(self.self_expr)); + let target = pick.unsize.unwrap_or(autoderefd_ty); + let target = target.adjust_for_autoref(self.tcx, autoref); + // Write out the final adjustment. - self.write_adjustment(self.self_expr.id, - AdjustDerefRef(AutoDerefRef { - autoderefs: pick.autoderefs, - autoref: autoref, - unsize: unsize, - })); - - if let Some(target) = unsize { - target - } else { - autoderefd_ty.adjust_for_autoref(self.tcx, autoref) - } + self.write_adjustment(self.self_expr.id, Adjustment { + kind: Adjust::DerefRef { + autoderefs: pick.autoderefs, + autoref: autoref, + unsize: pick.unsize.is_some(), + }, + target: target + }); + + target } /////////////////////////////////////////////////////////////////////////// @@ -463,29 +463,23 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Fix up autoderefs and derefs. for (i, &expr) in exprs.iter().rev().enumerate() { + debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?}", i, expr); + // Count autoderefs. - let autoderef_count = match self.tables - .borrow() - .adjustments - .get(&expr.id) { - Some(&AdjustDerefRef(ref adj)) => adj.autoderefs, - Some(_) | None => 0, - }; - - debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?} \ - autoderef_count={}", - i, - expr, - autoderef_count); - - if autoderef_count > 0 { - let mut autoderef = self.autoderef(expr.span, self.node_ty(expr.id)); - autoderef.nth(autoderef_count).unwrap_or_else(|| { - span_bug!(expr.span, - "expr was deref-able {} times but now isn't?", - autoderef_count); - }); - autoderef.finalize(PreferMutLvalue, Some(expr)); + let adjustment = self.tables.borrow().adjustments.get(&expr.id).cloned(); + match adjustment { + Some(Adjustment { kind: Adjust::DerefRef { autoderefs, .. }, .. }) => { + if autoderefs > 0 { + let mut autoderef = self.autoderef(expr.span, self.node_ty(expr.id)); + autoderef.nth(autoderefs).unwrap_or_else(|| { + span_bug!(expr.span, + "expr was deref-able {} times but now isn't?", + autoderefs); + }); + autoderef.finalize(PreferMutLvalue, Some(expr)); + } + } + Some(_) | None => {} } // Don't retry the first one or we might infinite loop! @@ -503,45 +497,55 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // ought to recode this routine so it doesn't // (ab)use the normal type checking paths. let adj = self.tables.borrow().adjustments.get(&base_expr.id).cloned(); - let (autoderefs, unsize) = match adj { - Some(AdjustDerefRef(adr)) => { - match adr.autoref { + let (autoderefs, unsize, adjusted_base_ty) = match adj { + Some(Adjustment { + kind: Adjust::DerefRef { autoderefs, autoref, unsize }, + target + }) => { + match autoref { None => { - assert!(adr.unsize.is_none()); - (adr.autoderefs, None) - } - Some(AutoPtr(..)) => { - (adr.autoderefs, - adr.unsize.map(|target| { - target.builtin_deref(false, NoPreference) - .expect("fixup: AutoPtr is not &T") - .ty - })) + assert!(!unsize); } + Some(AutoBorrow::Ref(..)) => {} Some(_) => { span_bug!(base_expr.span, "unexpected adjustment autoref {:?}", - adr); + adj); } } + + (autoderefs, unsize, if unsize { + target.builtin_deref(false, NoPreference) + .expect("fixup: AutoBorrow::Ref is not &T") + .ty + } else { + let ty = self.node_ty(base_expr.id); + let mut ty = self.shallow_resolve(ty); + let mut method_type = |method_call: ty::MethodCall| { + self.tables.borrow().method_map.get(&method_call).map(|m| { + self.resolve_type_vars_if_possible(&m.ty) + }) + }; + + if !ty.references_error() { + for i in 0..autoderefs { + ty = ty.adjust_for_autoderef(self.tcx, + base_expr.id, + base_expr.span, + i as u32, + &mut method_type); + } + } + + ty + }) } - None => (0, None), + None => (0, false, self.node_ty(base_expr.id)), Some(_) => { span_bug!(base_expr.span, "unexpected adjustment type"); } }; - let (adjusted_base_ty, unsize) = if let Some(target) = unsize { - (target, true) - } else { - (self.adjust_expr_ty(base_expr, - Some(&AdjustDerefRef(AutoDerefRef { - autoderefs: autoderefs, - autoref: None, - unsize: None, - }))), - false) - }; let index_expr_ty = self.node_ty(index_expr.id); let result = self.try_index_step(ty::MethodCall::expr(expr.id), diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f084b85a45f81..2df562f9ade46 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -16,7 +16,7 @@ use hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable}; -use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr}; +use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use rustc::infer; use syntax::ast; @@ -294,11 +294,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { unsize, method_ty.explicit_self); - match method_ty.explicit_self { + let autoref = match method_ty.explicit_self { ty::ExplicitSelfCategory::ByValue => { // Trait method is fn(self), no transformation needed. assert!(!unsize); - self.write_autoderef_adjustment(self_expr.id, autoderefs); + None } ty::ExplicitSelfCategory::ByReference(..) => { @@ -306,16 +306,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // autoref. Pull the region etc out of the type of first argument. match transformed_self_ty.sty { ty::TyRef(region, ty::TypeAndMut { mutbl, ty: _ }) => { - self.write_adjustment(self_expr.id, - AdjustDerefRef(AutoDerefRef { - autoderefs: autoderefs, - autoref: Some(AutoPtr(region, mutbl)), - unsize: if unsize { - Some(transformed_self_ty) - } else { - None - }, - })); + Some(AutoBorrow::Ref(region, mutbl)) } _ => { @@ -331,7 +322,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "unexpected explicit self type in operator method: {:?}", method_ty.explicit_self); } - } + }; + + self.write_adjustment(self_expr.id, Adjustment { + kind: Adjust::DerefRef { + autoderefs: autoderefs, + autoref: autoref, + unsize: unsize + }, + target: transformed_self_ty + }); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 75a14bb3db922..1c9c80bb7fc61 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -773,7 +773,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { check_union(ccx, it.id, it.span); } hir::ItemTy(_, ref generics) => { - let pty_ty = ccx.tcx.node_id_to_type(it.id); + let pty_ty = ccx.tcx.tables().node_id_to_type(it.id); check_bounds_are_used(ccx, generics, pty_ty); } hir::ItemForeignMod(ref m) => { @@ -1188,7 +1188,7 @@ fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, item_id: ast::NodeId) -> bool { - let rty = tcx.node_id_to_type(item_id); + let rty = tcx.tables().node_id_to_type(item_id); // Check that it is possible to represent this type. This call identifies // (1) types that contain themselves and (2) types that contain a different @@ -1207,7 +1207,7 @@ fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::NodeId) { - let t = tcx.node_id_to_type(id); + let t = tcx.tables().node_id_to_type(id); match t.sty { ty::TyAdt(def, substs) if def.is_struct() => { let fields = &def.struct_variant().fields; @@ -1564,20 +1564,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn write_autoderef_adjustment(&self, node_id: ast::NodeId, - derefs: usize) { - self.write_adjustment( - node_id, - adjustment::AdjustDerefRef(adjustment::AutoDerefRef { + derefs: usize, + adjusted_ty: Ty<'tcx>) { + self.write_adjustment(node_id, adjustment::Adjustment { + kind: adjustment::Adjust::DerefRef { autoderefs: derefs, autoref: None, - unsize: None - }) - ); + unsize: false + }, + target: adjusted_ty + }); } pub fn write_adjustment(&self, node_id: ast::NodeId, - adj: adjustment::AutoAdjustment<'tcx>) { + adj: adjustment::Adjustment<'tcx>) { debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj); if adj.is_identity() { @@ -1743,21 +1744,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { t } - /// Apply `adjustment` to the type of `expr` - pub fn adjust_expr_ty(&self, - expr: &hir::Expr, - adjustment: Option<&adjustment::AutoAdjustment<'tcx>>) - -> Ty<'tcx> - { - let raw_ty = self.node_ty(expr.id); - let raw_ty = self.shallow_resolve(raw_ty); - let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty); - raw_ty.adjust(self.tcx, expr.span, expr.id, adjustment, |method_call| { - self.tables.borrow().method_map.get(&method_call) - .map(|method| resolve_ty(method.ty)) - }) - } - pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { match self.tables.borrow().node_types.get(&id) { Some(&t) => t, @@ -2294,7 +2280,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("try_index_step: success, using built-in indexing"); // If we had `[T; N]`, we should've caught it before unsizing to `[T]`. assert!(!unsize); - self.write_autoderef_adjustment(base_expr.id, autoderefs); + self.write_autoderef_adjustment(base_expr.id, autoderefs, adjusted_ty); return Some((tcx.types.usize, ty)); } _ => {} @@ -2850,9 +2836,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // In case we did perform an adjustment, we have to update // 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())); + if res.is_ok() { + let adj = self.tables.borrow().adjustments.get(&then.id).cloned(); + if let Some(adj) = adj { + self.write_ty(then_blk.id, adj.target); + } } res @@ -2913,7 +2901,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_autoderef_adjustment(base.id, autoderefs); + self.write_autoderef_adjustment(base.id, autoderefs, base_t); return field_ty; } private_candidate = Some((base_def.did, field_ty)); @@ -3031,7 +3019,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(field_ty) = field { autoderef.finalize(lvalue_pref, Some(base)); - self.write_autoderef_adjustment(base.id, autoderefs); + self.write_autoderef_adjustment(base.id, autoderefs, base_t); return field_ty; } } @@ -3341,8 +3329,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if ty.is_never() { if let Some(hir::map::NodeExpr(_)) = self.tcx.map.find(expr.id) { let adj_ty = self.next_diverging_ty_var(); - let adj = adjustment::AdjustNeverToAny(adj_ty); - self.write_adjustment(expr.id, adj); + self.write_adjustment(expr.id, adjustment::Adjustment { + kind: adjustment::Adjust::NeverToAny, + target: adj_ty + }); return adj_ty; } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 939deee27c602..63f7a59f24fde 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -259,23 +259,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.resolve_type(t) } - fn resolve_method_type(&self, method_call: MethodCall) -> Option> { - let method_ty = self.tables.borrow().method_map - .get(&method_call).map(|method| method.ty); - method_ty.map(|method_ty| self.resolve_type(method_ty)) - } - /// Try to resolve the type for the given node. pub fn resolve_expr_type_adjusted(&mut self, expr: &hir::Expr) -> Ty<'tcx> { - let ty_unadjusted = self.resolve_node_type(expr.id); - if ty_unadjusted.references_error() { - ty_unadjusted - } else { - ty_unadjusted.adjust( - self.tcx, expr.span, expr.id, - self.tables.borrow().adjustments.get(&expr.id), - |method_call| self.resolve_method_type(method_call)) - } + let ty = self.tables.borrow().expr_ty_adjusted(expr); + self.resolve_type(ty) } fn visit_fn_body(&mut self, @@ -558,10 +545,8 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { let adjustment = self.tables.borrow().adjustments.get(&expr.id).map(|a| a.clone()); if let Some(adjustment) = adjustment { debug!("adjustment={:?}", adjustment); - match adjustment { - adjustment::AdjustDerefRef(adjustment::AutoDerefRef { - autoderefs, ref autoref, .. - }) => { + match adjustment.kind { + adjustment::Adjust::DerefRef { autoderefs, ref autoref, .. } => { let expr_ty = self.resolve_node_type(expr.id); self.constrain_autoderefs(expr, autoderefs, expr_ty); if let Some(ref autoref) = *autoref { @@ -951,7 +936,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let origin = infer::ParameterOrigin::OverloadedDeref; self.substs_wf_in_scope(origin, method.substs, deref_expr.span, r_deref_expr); - // Treat overloaded autoderefs as if an AutoRef adjustment + // Treat overloaded autoderefs as if an AutoBorrow adjustment // was applied on the base type, as that is always the case. let fn_sig = method.ty.fn_sig(); let fn_sig = // late-bound regions should have been instantiated @@ -1065,15 +1050,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { id: ast::NodeId, minimum_lifetime: &'tcx ty::Region) { - let tcx = self.tcx; - // Try to resolve the type. If we encounter an error, then typeck // is going to fail anyway, so just stop here and let typeck // report errors later on in the writeback phase. let ty0 = self.resolve_node_type(id); - let ty = ty0.adjust(tcx, origin.span(), id, - self.tables.borrow().adjustments.get(&id), - |method_call| self.resolve_method_type(method_call)); + let ty = self.tables.borrow().adjustments.get(&id).map_or(ty0, |adj| adj.target); + let ty = self.resolve_type(ty); debug!("constrain_regions_in_type_of_node(\ ty={}, ty0={}, id={}, minimum_lifetime={:?})", ty, ty0, @@ -1170,7 +1152,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn link_autoref(&self, expr: &hir::Expr, autoderefs: usize, - autoref: &adjustment::AutoRef<'tcx>) + autoref: &adjustment::AutoBorrow<'tcx>) { debug!("link_autoref(autoref={:?})", autoref); let mc = mc::MemCategorizationContext::new(self); @@ -1178,12 +1160,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("expr_cmt={:?}", expr_cmt); match *autoref { - adjustment::AutoPtr(r, m) => { + adjustment::AutoBorrow::Ref(r, m) => { self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt); } - adjustment::AutoUnsafe(m) => { + adjustment::AutoBorrow::RawPtr(m) => { let r = self.tcx.node_scope_region(expr.id); self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index e3634cfe5f5e3..be1f2e35679d7 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -416,7 +416,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } } None => { - let self_ty = fcx.tcx.node_id_to_type(item.id); + let self_ty = fcx.tcx.tables().node_id_to_type(item.id); let self_ty = fcx.instantiate_type_scheme(item.span, free_substs, &self_ty); fcx.register_wf_obligation(self_ty, ast_self_ty.span, this.code.clone()); } @@ -519,7 +519,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { item: &hir::Item, ast_generics: &hir::Generics) { - let ty = self.tcx().node_id_to_type(item.id); + let ty = self.tcx().tables().node_id_to_type(item.id); if self.tcx().has_error_field(ty) { return; } @@ -649,7 +649,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fields = struct_def.fields().iter() .map(|field| { - let field_ty = self.tcx.node_id_to_type(field.id); + let field_ty = self.tcx.tables().node_id_to_type(field.id); let field_ty = self.instantiate_type_scheme(field.span, &self.parameter_environment .free_substs, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 8685f703a599c..5ef3e8699602b 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -229,7 +229,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { debug!("Type for pattern binding {} (id {}) resolved to {:?}", pat_to_string(p), p.id, - self.tcx().node_id_to_type(p.id)); + self.tcx().tables().node_id_to_type(p.id)); intravisit::walk_pat(self, p); } @@ -381,36 +381,40 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } Some(adjustment) => { - let resolved_adjustment = match adjustment { - adjustment::AdjustNeverToAny(ty) => { - adjustment::AdjustNeverToAny(self.resolve(&ty, reason)) + let resolved_adjustment = match adjustment.kind { + adjustment::Adjust::NeverToAny => { + adjustment::Adjust::NeverToAny } - adjustment::AdjustReifyFnPointer => { - adjustment::AdjustReifyFnPointer + adjustment::Adjust::ReifyFnPointer => { + adjustment::Adjust::ReifyFnPointer } - adjustment::AdjustMutToConstPointer => { - adjustment::AdjustMutToConstPointer + adjustment::Adjust::MutToConstPointer => { + adjustment::Adjust::MutToConstPointer } - adjustment::AdjustUnsafeFnPointer => { - adjustment::AdjustUnsafeFnPointer + adjustment::Adjust::UnsafeFnPointer => { + adjustment::Adjust::UnsafeFnPointer } - adjustment::AdjustDerefRef(adj) => { - for autoderef in 0..adj.autoderefs { + adjustment::Adjust::DerefRef { autoderefs, autoref, unsize } => { + for autoderef in 0..autoderefs { let method_call = MethodCall::autoderef(id, autoderef as u32); self.visit_method_map_entry(reason, method_call); } - adjustment::AdjustDerefRef(adjustment::AutoDerefRef { - autoderefs: adj.autoderefs, - autoref: self.resolve(&adj.autoref, reason), - unsize: self.resolve(&adj.unsize, reason), - }) + adjustment::Adjust::DerefRef { + autoderefs: autoderefs, + autoref: self.resolve(&autoref, reason), + unsize: unsize, + } } }; + let resolved_adjustment = adjustment::Adjustment { + kind: resolved_adjustment, + target: self.resolve(&adjustment.target, reason) + }; debug!("Adjustments for node {}: {:?}", id, resolved_adjustment); self.tcx().tables.borrow_mut().adjustments.insert( id, resolved_adjustment); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index c16dd788c4ec8..5a48b5f0e1fd1 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -211,7 +211,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, main_id: ast::NodeId, main_span: Span) { let tcx = ccx.tcx; - let main_t = tcx.node_id_to_type(main_id); + let main_t = tcx.tables().node_id_to_type(main_id); match main_t.sty { ty::TyFnDef(..) => { match tcx.map.find(main_id) { @@ -263,7 +263,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt, start_id: ast::NodeId, start_span: Span) { let tcx = ccx.tcx; - let start_t = tcx.node_id_to_type(start_id); + let start_t = tcx.tables().node_id_to_type(start_id); match start_t.sty { ty::TyFnDef(..) => { match tcx.map.find(start_id) {