diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-05-20 16:11:07 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-06-01 08:59:47 +0300 |
| commit | 552ab37a100231f8f2416b5ecc7e350c17e6487f (patch) | |
| tree | 013fe2efb07f5f00e0b8066ff23c0e8918e859c5 | |
| parent | 9eae6ba7fad883300c83d77782ae78b0db6f3bb7 (diff) | |
rustc: replace method_map with Def::Method and node_substs entries.
| -rw-r--r-- | src/librustc/cfg/construct.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ich/impls_ty.rs | 6 | ||||
| -rw-r--r-- | src/librustc/middle/dead.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/effect.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 6 | ||||
| -rw-r--r-- | src/librustc/middle/liveness.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/reachable.rs | 3 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 25 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 2 | ||||
| -rw-r--r-- | src/librustc_lint/builtin.rs | 29 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/expr.rs | 51 | ||||
| -rw-r--r-- | src/librustc_passes/consts.rs | 8 | ||||
| -rw-r--r-- | src/librustc_save_analysis/lib.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/callee.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/confirm.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 19 | ||||
| -rw-r--r-- | src/librustc_typeck/check/op.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/regionck.rs | 20 | ||||
| -rw-r--r-- | src/librustc_typeck/check/writeback.rs | 40 |
20 files changed, 120 insertions, 119 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index affc84382a5..85b1858c875 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -355,11 +355,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } hir::ExprIndex(ref l, ref r) | - hir::ExprBinary(_, ref l, ref r) if self.tables.is_method_call(expr.id) => { + hir::ExprBinary(_, ref l, ref r) if self.tables.is_method_call(expr) => { self.call(expr, pred, &l, Some(&**r).into_iter()) } - hir::ExprUnary(_, ref e) if self.tables.is_method_call(expr.id) => { + hir::ExprUnary(_, ref e) if self.tables.is_method_call(expr) => { self.call(expr, pred, &e, None::<hir::Expr>.iter()) } diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 2615fdd86d6..e607a6bf74a 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -598,11 +598,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<' hcx: &mut StableHashingContext<'a, 'tcx>, hasher: &mut StableHasher<W>) { let ty::TypeckTables { - ref type_relative_path_defs, + ref type_dependent_defs, ref node_types, ref node_substs, ref adjustments, - ref method_map, ref upvar_capture_map, ref closure_tys, ref closure_kinds, @@ -619,11 +618,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<' } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - ich::hash_stable_nodemap(hcx, hasher, type_relative_path_defs); + ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs); ich::hash_stable_nodemap(hcx, hasher, node_types); ich::hash_stable_nodemap(hcx, hasher, node_substs); ich::hash_stable_nodemap(hcx, hasher, adjustments); - ich::hash_stable_nodemap(hcx, hasher, method_map); ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| { let ty::UpvarId { var_id, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index ebae3933bdd..6077b7863e2 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn lookup_and_handle_method(&mut self, id: ast::NodeId) { - self.check_def_id(self.tables.method_map[&id].def_id); + self.check_def_id(self.tables.type_dependent_defs[&id].def_id()); } fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index c9593e54a86..74e1225f394 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -173,8 +173,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { match expr.node { hir::ExprMethodCall(..) => { - let method = self.tables.method_map[&expr.id]; - let base_type = self.tcx.type_of(method.def_id); + let def_id = self.tables.type_dependent_defs[&expr.id].def_id(); + let base_type = self.tcx.type_of(def_id); debug!("effect: method call case, base type is {:?}", base_type); if type_is_unsafe_function(base_type) { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 45afc17f339..340a929331f 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -563,8 +563,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } ty::TyError => { } _ => { - let method = self.mc.infcx.tables.borrow().method_map[&call.id]; - match OverloadedCallType::from_method_id(self.tcx(), method.def_id) { + let def_id = self.mc.infcx.tables.borrow().type_dependent_defs[&call.id].def_id(); + match OverloadedCallType::from_method_id(self.tcx(), def_id) { FnMutOverloadedCall => { let call_scope_r = self.tcx().node_scope_region(call.id); self.borrow_expr(callee, @@ -849,7 +849,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pass_args: PassArgs) -> bool { - if !self.mc.infcx.tables.borrow().is_method_call(expr.id) { + if !self.mc.infcx.tables.borrow().is_method_call(expr) { return false; } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 6a74af6eb8a..c6a42be6135 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1045,7 +1045,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprAssignOp(_, ref l, ref r) => { // an overloaded assign op is like a method call - if self.tables.is_method_call(expr.id) { + if self.tables.is_method_call(expr) { let succ = self.propagate_through_expr(&l, succ); self.propagate_through_expr(&r, succ) } else { @@ -1366,7 +1366,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { } hir::ExprAssignOp(_, ref l, _) => { - if !this.tables.is_method_call(expr.id) { + if !this.tables.is_method_call(expr) { this.check_lvalue(&l); } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index cc65777bfce..f971700b2c8 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -515,7 +515,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let expr_ty = self.expr_ty(expr)?; match expr.node { hir::ExprUnary(hir::UnDeref, ref e_base) => { - if self.infcx.tables.borrow().is_method_call(expr.id) { + if self.infcx.tables.borrow().is_method_call(expr) { self.cat_overloaded_lvalue(expr, e_base, false) } else { let base_cmt = self.cat_expr(&e_base)?; @@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } hir::ExprIndex(ref base, _) => { - if self.infcx.tables.borrow().is_method_call(expr.id()) { + if self.infcx.tables.borrow().is_method_call(expr) { // If this is an index implemented by a method call, then it // will include an implicit deref of the result. // The call to index() returns a `&T` value, which diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index e5cc7aae4e9..c2f69147e3a 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -110,8 +110,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(self.tables.qpath_def(qpath, expr.id)) } hir::ExprMethodCall(..) => { - let def_id = self.tables.method_map[&expr.id].def_id; - Some(Def::Method(def_id)) + Some(self.tables.type_dependent_defs[&expr.id]) } _ => None }; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a0ad3da45e0..f0cee2fe2b1 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -206,8 +206,9 @@ pub struct CommonTypes<'tcx> { #[derive(RustcEncodable, RustcDecodable)] pub struct TypeckTables<'tcx> { - /// Resolved definitions for `<T>::X` associated paths. - pub type_relative_path_defs: NodeMap<Def>, + /// Resolved definitions for `<T>::X` associated paths and + /// method calls, including those of overloaded operators. + pub type_dependent_defs: NodeMap<Def>, /// Stores the types for various nodes in the AST. Note that this table /// is not guaranteed to be populated until after typeck. See @@ -222,8 +223,6 @@ pub struct TypeckTables<'tcx> { pub adjustments: NodeMap<ty::adjustment::Adjustment<'tcx>>, - pub method_map: NodeMap<ty::MethodCallee<'tcx>>, - /// Borrows pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>, @@ -271,11 +270,10 @@ pub struct TypeckTables<'tcx> { impl<'tcx> TypeckTables<'tcx> { pub fn empty() -> TypeckTables<'tcx> { TypeckTables { - type_relative_path_defs: NodeMap(), + type_dependent_defs: NodeMap(), node_types: FxHashMap(), node_substs: NodeMap(), adjustments: NodeMap(), - method_map: FxHashMap(), upvar_capture_map: FxHashMap(), closure_tys: NodeMap(), closure_kinds: NodeMap(), @@ -294,7 +292,7 @@ impl<'tcx> TypeckTables<'tcx> { match *qpath { hir::QPath::Resolved(_, ref path) => path.def, hir::QPath::TypeRelative(..) => { - self.type_relative_path_defs.get(&id).cloned().unwrap_or(Def::Err) + self.type_dependent_defs.get(&id).cloned().unwrap_or(Def::Err) } } } @@ -357,8 +355,17 @@ impl<'tcx> TypeckTables<'tcx> { .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(&expr_id) + pub fn is_method_call(&self, expr: &hir::Expr) -> bool { + // Only paths and method calls/overloaded operators have + // entries in type_dependent_defs, ignore the former here. + if let hir::ExprPath(_) = expr.node { + return false; + } + + match self.type_dependent_defs.get(&expr.id) { + Some(&Def::Method(_)) => true, + _ => false + } } pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index df7c2e567f7..76132cab2cd 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -141,8 +141,6 @@ pub enum TypeVariants<'tcx> { TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>), /// A pointer to a function. Written as `fn() -> i32`. - /// FIXME: This is currently also used to represent the callee of a method; - /// see ty::MethodCallee etc. TyFnPtr(PolyFnSig<'tcx>), /// A trait, defined with `trait`. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 8a374358bb9..04645214ce8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -881,17 +881,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { -> bool { use rustc::ty::adjustment::*; - // Check for method calls and overloaded operators. - if let Some(m) = cx.tables.method_map.get(&id).cloned() { - if method_call_refers_to_method(cx.tcx, method, m.def_id, m.substs, id) { - return true; - } - } + // Ignore non-expressions. + let expr = if let hir_map::NodeExpr(e) = cx.tcx.hir.get(id) { + e + } else { + return false; + }; // Check for overloaded autoderef method calls. - if let Some(Adjustment { + if let Some(&Adjustment { kind: Adjust::DerefRef { ref autoderefs, .. }, .. - }) = cx.tables.adjustments.get(&id).cloned() { + }) = cx.tables.adjustments.get(&id) { for &overloaded in autoderefs { if let Some(m) = overloaded { if method_call_refers_to_method(cx.tcx, method, m.def_id, m.substs, id) { @@ -901,9 +901,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { } } + // Check for method calls and overloaded operators. + if cx.tables.is_method_call(expr) { + let def_id = cx.tables.type_dependent_defs[&id].def_id(); + let substs = cx.tables.node_substs(id); + if method_call_refers_to_method(cx.tcx, method, def_id, substs, id) { + return true; + } + } + // Check for calls to methods via explicit paths (e.g. `T::method()`). - match cx.tcx.hir.get(id) { - hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { + match expr.node { + hir::ExprCall(ref callee, _) => { let def = if let hir::ExprPath(ref qpath) = callee.node { cx.tables.qpath_def(qpath, callee.id) } else { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index c11cd38fe34..cd540f309b0 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -118,7 +118,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { overloaded_lvalue(cx, self, mt.ty, - method, + Some(method), PassArgs::ByRef, expr.to_ref(), vec![]) @@ -244,8 +244,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Here comes the interesting stuff: hir::ExprMethodCall(.., ref args) => { // Rewrite a.b(c) into UFCS form like Trait::b(a, c) - let method = cx.tables().method_map[&expr.id]; - let expr = method_callee(cx, expr, method); + let expr = method_callee(cx, expr, None); let args = args.iter() .map(|e| e.to_ref()) .collect(); @@ -257,7 +256,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprCall(ref fun, ref args) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { // 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 @@ -265,7 +264,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // rewrite f(u, v) into FnOnce::call_once(f, (u, v)) - let method = method_callee(cx, expr, method); + let method = method_callee(cx, expr, None); let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e)); let tupled_args = Expr { @@ -346,7 +345,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprAssignOp(op, ref lhs, ref rhs) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { @@ -354,7 +353,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }; overloaded_operator(cx, expr, - method, + None, pass_args, lhs.to_ref(), vec![rhs]) @@ -370,7 +369,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprLit(..) => ExprKind::Literal { literal: cx.const_eval_literal(expr) }, hir::ExprBinary(op, ref lhs, ref rhs) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { @@ -378,7 +377,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }; overloaded_operator(cx, expr, - method, + None, pass_args, lhs.to_ref(), vec![rhs]) @@ -430,11 +429,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprIndex(ref lhs, ref index) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { overloaded_lvalue(cx, expr, expr_ty, - method, + None, PassArgs::ByValue, lhs.to_ref(), vec![index]) @@ -447,11 +446,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprUnary(hir::UnOp::UnDeref, ref arg) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { overloaded_lvalue(cx, expr, expr_ty, - method, + None, PassArgs::ByValue, arg.to_ref(), vec![]) @@ -461,10 +460,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprUnary(hir::UnOp::UnNot, ref arg) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { overloaded_operator(cx, expr, - method, + None, PassArgs::ByValue, arg.to_ref(), vec![]) @@ -477,10 +476,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => { - if let Some(&method) = cx.tables().method_map.get(&expr.id) { + if cx.tables().is_method_call(expr) { overloaded_operator(cx, expr, - method, + None, PassArgs::ByValue, arg.to_ref(), vec![]) @@ -699,17 +698,21 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &hir::Expr, - callee: ty::MethodCallee<'tcx>) + custom_callee: Option<ty::MethodCallee<'tcx>>) -> Expr<'tcx> { let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id); + let (def_id, substs) = custom_callee.map(|m| (m.def_id, m.substs)).unwrap_or_else(|| { + (cx.tables().type_dependent_defs[&expr.id].def_id(), + cx.tables().node_substs(expr.id)) + }); Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, - ty: cx.tcx.type_of(callee.def_id).subst(cx.tcx, callee.substs), + ty: cx.tcx.type_of(def_id).subst(cx.tcx, substs), span: expr.span, kind: ExprKind::Literal { literal: Literal::Value { - value: ConstVal::Function(callee.def_id, callee.substs), + value: ConstVal::Function(def_id, substs), }, }, } @@ -942,7 +945,7 @@ enum PassArgs { fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, - method: ty::MethodCallee<'tcx>, + custom_callee: Option<ty::MethodCallee<'tcx>>, pass_args: PassArgs, receiver: ExprRef<'tcx>, args: Vec<&'tcx P<hir::Expr>>) @@ -985,7 +988,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } // now create the call itself - let fun = method_callee(cx, expr, method); + let fun = method_callee(cx, expr, custom_callee); ExprKind::Call { ty: fun.ty, fun: fun.to_ref(), @@ -996,7 +999,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, lvalue_ty: Ty<'tcx>, - method: ty::MethodCallee<'tcx>, + custom_callee: Option<ty::MethodCallee<'tcx>>, pass_args: PassArgs, receiver: ExprRef<'tcx>, args: Vec<&'tcx P<hir::Expr>>) @@ -1025,7 +1028,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id); - let ref_kind = overloaded_operator(cx, expr, method, pass_args, receiver, args); + let ref_kind = overloaded_operator(cx, expr, custom_callee, pass_args, receiver, args); let ref_expr = Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 712f5f7ad39..f73ae9d42f6 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -283,7 +283,7 @@ 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.tables.method_map.contains_key(&e.id) => { + hir::ExprIndex(..) if v.tables.is_method_call(e) => { v.promotable = false; } hir::ExprBox(_) => { @@ -380,9 +380,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprMethodCall(..) => { - let method = v.tables.method_map[&e.id]; - match v.tcx.associated_item(method.def_id).container { - ty::ImplContainer(_) => v.handle_const_fn_call(method.def_id, node_ty), + let def_id = v.tables.type_dependent_defs[&e.id].def_id(); + match v.tcx.associated_item(def_id).container { + ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty), ty::TraitContainer(_) => v.promotable = false } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d0809f0f642..b4d74cfb160 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -564,7 +564,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } ast::ExprKind::MethodCall(..) => { - let method_id = self.tables.method_map[&expr.id].def_id; + let method_id = self.tables.type_dependent_defs[&expr.id].def_id(); let (def_id, decl_id) = match self.tcx.associated_item(method_id).container { ty::ImplContainer(_) => (Some(method_id), None), ty::TraitContainer(_) => (None, Some(method_id)), diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 5302ba00291..f8560550da4 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { TupleArgumentsFlag::TupleArguments, expected); - self.tables.borrow_mut().method_map.insert(call_expr.id, method_callee); + self.write_method_call(call_expr.id, method_callee); output_type } } @@ -363,7 +363,7 @@ impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> { target: method_sig.inputs()[0] }); - fcx.tables.borrow_mut().method_map.insert(self.call_expr.id, method_callee); + fcx.write_method_call(self.call_expr.id, method_callee); } None => { span_bug!(self.call_expr.span, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 71bcff84cc2..52ed6647994 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -475,7 +475,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { { debug!("convert_lvalue_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys); - if !self.tables.borrow().method_map.contains_key(&expr.id) { + if !self.tables.borrow().is_method_call(expr) { debug!("convert_lvalue_op_to_mutable - builtin, nothing to do"); return } @@ -497,7 +497,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { }; let (_, method) = self.register_infer_ok_obligations(ok); debug!("convert_lvalue_op_to_mutable: method={:?}", method); - self.tables.borrow_mut().method_map.insert(expr.id, method); + self.write_method_call(expr.id, method); // Convert the autoref in the base expr to mutable with the correct // region and mutability. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0b0233103ef..df5023fb7a6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1758,6 +1758,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } + pub fn write_method_call(&self, node_id: ast::NodeId, method: ty::MethodCallee<'tcx>) { + self.tables.borrow_mut().type_dependent_defs.insert(node_id, Def::Method(method.def_id)); + self.write_substs(node_id, method.substs); + } + pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) { if !substs.is_noop() { debug!("write_substs({}, {:?}) in fcx {}", @@ -2238,7 +2243,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { target: method.sig.inputs()[0] }); - self.tables.borrow_mut().method_map.insert(expr.id, method); + self.write_method_call(expr.id, method); (input_ty, self.make_overloaded_lvalue_return_type(method).ty) }); if result.is_some() { @@ -2777,7 +2782,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr, rcvr) { Ok(method) => { - self.tables.borrow_mut().method_map.insert(expr.id, method); + self.write_method_call(expr.id, method); Ok(method) } Err(error) => { @@ -3453,7 +3458,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { target: method.sig.inputs()[0] }); oprnd_t = self.make_overloaded_lvalue_return_type(method).ty; - self.tables.borrow_mut().method_map.insert(expr.id, method); + self.write_method_call(expr.id, method); } else { self.type_error_message(expr.span, |actual| { format!("type `{}` cannot be \ @@ -3918,7 +3923,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary. - // The newly resolved definition is written into `type_relative_path_defs`. + // The newly resolved definition is written into `type_dependent_defs`. fn finish_resolving_struct_path(&self, qpath: &hir::QPath, path_span: Span, @@ -3943,7 +3948,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty, def, segment); // Write back the new resolution. - self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def); + self.tables.borrow_mut().type_dependent_defs.insert(node_id, def); (def, ty) } @@ -3951,7 +3956,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Resolve associated value path into a base type and associated constant or method definition. - // The newly resolved definition is written into `type_relative_path_defs`. + // The newly resolved definition is written into `type_dependent_defs`. pub fn resolve_ty_and_def_ufcs<'b>(&self, qpath: &'b hir::QPath, node_id: ast::NodeId, @@ -3984,7 +3989,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Write back the new resolution. - self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def); + self.tables.borrow_mut().type_dependent_defs.insert(node_id, def); (def, Some(ty), slice::ref_slice(&**item_segment)) } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 267b2b00978..0c820d2404a 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -421,7 +421,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }, target: method.sig.inputs()[0] }); - self.tables.borrow_mut().method_map.insert(expr.id, method); + self.write_method_call(expr.id, method); Ok(method.sig.output()) } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 2fae9d8e70e..e1451139d6e 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -520,14 +520,13 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span), expr_ty, expr_region); - let opt_method_callee = self.tables.borrow().method_map.get(&expr.id).cloned(); - let has_method_map = opt_method_callee.is_some(); + let is_method_call = self.tables.borrow().is_method_call(expr); // If we are calling a method (either explicitly or via an // overloaded operator), check that all of the types provided as // arguments for its type parameters are well-formed, and all the regions // provided as arguments outlive the call. - if let Some(callee) = opt_method_callee { + if is_method_call { let origin = match expr.node { hir::ExprMethodCall(..) => infer::ParameterOrigin::MethodCall, @@ -537,7 +536,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { infer::ParameterOrigin::OverloadedOperator }; - self.substs_wf_in_scope(origin, &callee.substs, expr.span, expr_region); + let substs = self.tables.borrow().node_substs(expr.id); + self.substs_wf_in_scope(origin, substs, expr.span, expr_region); // Arguments (sub-expressions) are checked via `constrain_call`, below. } @@ -614,7 +614,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { } hir::ExprCall(ref callee, ref args) => { - if has_method_map { + if is_method_call { self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e), false); } else { @@ -634,7 +634,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { } hir::ExprAssignOp(_, ref lhs, ref rhs) => { - if has_method_map { + if is_method_call { self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter(), false); } @@ -642,14 +642,14 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { intravisit::walk_expr(self, expr); } - hir::ExprIndex(ref lhs, ref rhs) if has_method_map => { + hir::ExprIndex(ref lhs, ref rhs) if is_method_call => { self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter(), true); intravisit::walk_expr(self, expr); }, - hir::ExprBinary(op, ref lhs, ref rhs) if has_method_map => { + hir::ExprBinary(op, ref lhs, ref rhs) if is_method_call => { let implicitly_ref_args = !op.node.is_by_value(); // As `expr_method_call`, but the call is via an @@ -674,7 +674,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { intravisit::walk_expr(self, expr); } - hir::ExprUnary(op, ref lhs) if has_method_map => { + hir::ExprUnary(op, ref lhs) if is_method_call => { let implicitly_ref_args = !op.is_by_value(); // As above. @@ -686,7 +686,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { hir::ExprUnary(hir::UnDeref, ref base) => { // For *a, the lifetime of a must enclose the deref - if self.tables.borrow().is_method_call(expr.id) { + if self.tables.borrow().is_method_call(expr) { self.constrain_call(expr, Some(base), None::<hir::Expr>.iter(), true); } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index dcdfed6cbd8..4db0475a18b 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -106,7 +106,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty); if inner_ty.is_scalar() { - self.fcx.tables.borrow_mut().method_map.remove(&e.id); + let mut tables = self.fcx.tables.borrow_mut(); + tables.type_dependent_defs.remove(&e.id); + tables.node_substs.remove(&e.id); } } hir::ExprBinary(ref op, ref lhs, ref rhs) | @@ -118,7 +120,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty); if lhs_ty.is_scalar() && rhs_ty.is_scalar() { - self.fcx.tables.borrow_mut().method_map.remove(&e.id); + let mut tables = self.fcx.tables.borrow_mut(); + tables.type_dependent_defs.remove(&e.id); + tables.node_substs.remove(&e.id); // weird but true: the by-ref binops put an // adjustment on the lhs but not the rhs; the @@ -127,11 +131,11 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { match e.node { hir::ExprBinary(..) => { if !op.node.is_by_value() { - self.fcx.tables.borrow_mut().adjustments.remove(&lhs.id); + tables.adjustments.remove(&lhs.id); } }, hir::ExprAssignOp(..) => { - self.fcx.tables.borrow_mut().adjustments.remove(&lhs.id); + tables.adjustments.remove(&lhs.id); }, _ => {}, } @@ -164,7 +168,6 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { self.fix_scalar_builtin_expr(e); self.visit_node_id(e.span, e.id); - self.visit_method_map_entry(e.span, e.id); if let hir::ExprClosure(_, _, body, _) = e.node { let body = self.fcx.tcx.hir.body(body); @@ -280,9 +283,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } fn visit_node_id(&mut self, span: Span, node_id: ast::NodeId) { - // Export associated path extensions. - if let Some(def) = self.fcx.tables.borrow_mut().type_relative_path_defs.remove(&node_id) { - self.tables.type_relative_path_defs.insert(node_id, def); + // Export associated path extensions and method resultions. + if let Some(def) = self.fcx.tables.borrow_mut().type_dependent_defs.remove(&node_id) { + self.tables.type_dependent_defs.insert(node_id, def); } // Resolve any borrowings for the node with id `node_id` @@ -358,27 +361,6 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } - fn visit_method_map_entry(&mut self, - method_span: Span, - node_id: ast::NodeId) { - // Resolve any method map entry - let new_method = match self.fcx.tables.borrow_mut().method_map.remove(&node_id) { - Some(method) => { - Some(MethodCallee { - def_id: method.def_id, - substs: self.resolve(&method.substs, &method_span), - sig: self.resolve(&method.sig, &method_span), - }) - } - None => None - }; - - //NB(jroesch): We need to match twice to avoid a double borrow which would cause an ICE - if let Some(method) = new_method { - self.tables.method_map.insert(node_id, method); - } - } - fn visit_liberated_fn_sigs(&mut self) { for (&node_id, fn_sig) in self.fcx.tables.borrow().liberated_fn_sigs.iter() { let fn_sig = self.resolve(fn_sig, &node_id); |
