rustc: replace method_map with Def::Method and node_substs entries.
This commit is contained in:
parent
9eae6ba7fa
commit
552ab37a10
20 changed files with 120 additions and 119 deletions
|
@ -355,11 +355,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprIndex(ref l, ref r) |
|
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())
|
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())
|
self.call(expr, pred, &e, None::<hir::Expr>.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -598,11 +598,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<'
|
||||||
hcx: &mut StableHashingContext<'a, 'tcx>,
|
hcx: &mut StableHashingContext<'a, 'tcx>,
|
||||||
hasher: &mut StableHasher<W>) {
|
hasher: &mut StableHasher<W>) {
|
||||||
let ty::TypeckTables {
|
let ty::TypeckTables {
|
||||||
ref type_relative_path_defs,
|
ref type_dependent_defs,
|
||||||
ref node_types,
|
ref node_types,
|
||||||
ref node_substs,
|
ref node_substs,
|
||||||
ref adjustments,
|
ref adjustments,
|
||||||
ref method_map,
|
|
||||||
ref upvar_capture_map,
|
ref upvar_capture_map,
|
||||||
ref closure_tys,
|
ref closure_tys,
|
||||||
ref closure_kinds,
|
ref closure_kinds,
|
||||||
|
@ -619,11 +618,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<'
|
||||||
} = *self;
|
} = *self;
|
||||||
|
|
||||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
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_types);
|
||||||
ich::hash_stable_nodemap(hcx, hasher, node_substs);
|
ich::hash_stable_nodemap(hcx, hasher, node_substs);
|
||||||
ich::hash_stable_nodemap(hcx, hasher, adjustments);
|
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| {
|
ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
|
||||||
let ty::UpvarId {
|
let ty::UpvarId {
|
||||||
var_id,
|
var_id,
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
|
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) {
|
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
|
||||||
|
|
|
@ -173,8 +173,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
|
||||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
hir::ExprMethodCall(..) => {
|
hir::ExprMethodCall(..) => {
|
||||||
let method = self.tables.method_map[&expr.id];
|
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
|
||||||
let base_type = self.tcx.type_of(method.def_id);
|
let base_type = self.tcx.type_of(def_id);
|
||||||
debug!("effect: method call case, base type is {:?}",
|
debug!("effect: method call case, base type is {:?}",
|
||||||
base_type);
|
base_type);
|
||||||
if type_is_unsafe_function(base_type) {
|
if type_is_unsafe_function(base_type) {
|
||||||
|
|
|
@ -563,8 +563,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::TyError => { }
|
ty::TyError => { }
|
||||||
_ => {
|
_ => {
|
||||||
let method = self.mc.infcx.tables.borrow().method_map[&call.id];
|
let def_id = self.mc.infcx.tables.borrow().type_dependent_defs[&call.id].def_id();
|
||||||
match OverloadedCallType::from_method_id(self.tcx(), method.def_id) {
|
match OverloadedCallType::from_method_id(self.tcx(), def_id) {
|
||||||
FnMutOverloadedCall => {
|
FnMutOverloadedCall => {
|
||||||
let call_scope_r = self.tcx().node_scope_region(call.id);
|
let call_scope_r = self.tcx().node_scope_region(call.id);
|
||||||
self.borrow_expr(callee,
|
self.borrow_expr(callee,
|
||||||
|
@ -849,7 +849,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
pass_args: PassArgs)
|
pass_args: PassArgs)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
if !self.mc.infcx.tables.borrow().is_method_call(expr.id) {
|
if !self.mc.infcx.tables.borrow().is_method_call(expr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1045,7 +1045,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
|
|
||||||
hir::ExprAssignOp(_, ref l, ref r) => {
|
hir::ExprAssignOp(_, ref l, ref r) => {
|
||||||
// an overloaded assign op is like a method call
|
// 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);
|
let succ = self.propagate_through_expr(&l, succ);
|
||||||
self.propagate_through_expr(&r, succ)
|
self.propagate_through_expr(&r, succ)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1366,7 +1366,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprAssignOp(_, ref l, _) => {
|
hir::ExprAssignOp(_, ref l, _) => {
|
||||||
if !this.tables.is_method_call(expr.id) {
|
if !this.tables.is_method_call(expr) {
|
||||||
this.check_lvalue(&l);
|
this.check_lvalue(&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
let expr_ty = self.expr_ty(expr)?;
|
let expr_ty = self.expr_ty(expr)?;
|
||||||
match expr.node {
|
match expr.node {
|
||||||
hir::ExprUnary(hir::UnDeref, ref e_base) => {
|
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)
|
self.cat_overloaded_lvalue(expr, e_base, false)
|
||||||
} else {
|
} else {
|
||||||
let base_cmt = self.cat_expr(&e_base)?;
|
let base_cmt = self.cat_expr(&e_base)?;
|
||||||
|
@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprIndex(ref base, _) => {
|
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
|
// If this is an index implemented by a method call, then it
|
||||||
// will include an implicit deref of the result.
|
// will include an implicit deref of the result.
|
||||||
// The call to index() returns a `&T` value, which
|
// The call to index() returns a `&T` value, which
|
||||||
|
|
|
@ -110,8 +110,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
|
||||||
Some(self.tables.qpath_def(qpath, expr.id))
|
Some(self.tables.qpath_def(qpath, expr.id))
|
||||||
}
|
}
|
||||||
hir::ExprMethodCall(..) => {
|
hir::ExprMethodCall(..) => {
|
||||||
let def_id = self.tables.method_map[&expr.id].def_id;
|
Some(self.tables.type_dependent_defs[&expr.id])
|
||||||
Some(Def::Method(def_id))
|
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
|
|
|
@ -206,8 +206,9 @@ pub struct CommonTypes<'tcx> {
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct TypeckTables<'tcx> {
|
pub struct TypeckTables<'tcx> {
|
||||||
/// Resolved definitions for `<T>::X` associated paths.
|
/// Resolved definitions for `<T>::X` associated paths and
|
||||||
pub type_relative_path_defs: NodeMap<Def>,
|
/// 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
|
/// Stores the types for various nodes in the AST. Note that this table
|
||||||
/// is not guaranteed to be populated until after typeck. See
|
/// 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 adjustments: NodeMap<ty::adjustment::Adjustment<'tcx>>,
|
||||||
|
|
||||||
pub method_map: NodeMap<ty::MethodCallee<'tcx>>,
|
|
||||||
|
|
||||||
/// Borrows
|
/// Borrows
|
||||||
pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
|
pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
|
||||||
|
|
||||||
|
@ -271,11 +270,10 @@ pub struct TypeckTables<'tcx> {
|
||||||
impl<'tcx> TypeckTables<'tcx> {
|
impl<'tcx> TypeckTables<'tcx> {
|
||||||
pub fn empty() -> TypeckTables<'tcx> {
|
pub fn empty() -> TypeckTables<'tcx> {
|
||||||
TypeckTables {
|
TypeckTables {
|
||||||
type_relative_path_defs: NodeMap(),
|
type_dependent_defs: NodeMap(),
|
||||||
node_types: FxHashMap(),
|
node_types: FxHashMap(),
|
||||||
node_substs: NodeMap(),
|
node_substs: NodeMap(),
|
||||||
adjustments: NodeMap(),
|
adjustments: NodeMap(),
|
||||||
method_map: FxHashMap(),
|
|
||||||
upvar_capture_map: FxHashMap(),
|
upvar_capture_map: FxHashMap(),
|
||||||
closure_tys: NodeMap(),
|
closure_tys: NodeMap(),
|
||||||
closure_kinds: NodeMap(),
|
closure_kinds: NodeMap(),
|
||||||
|
@ -294,7 +292,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
||||||
match *qpath {
|
match *qpath {
|
||||||
hir::QPath::Resolved(_, ref path) => path.def,
|
hir::QPath::Resolved(_, ref path) => path.def,
|
||||||
hir::QPath::TypeRelative(..) => {
|
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))
|
.map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_method_call(&self, expr_id: NodeId) -> bool {
|
pub fn is_method_call(&self, expr: &hir::Expr) -> bool {
|
||||||
self.method_map.contains_key(&expr_id)
|
// 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>> {
|
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
|
||||||
|
|
|
@ -141,8 +141,6 @@ pub enum TypeVariants<'tcx> {
|
||||||
TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>),
|
TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>),
|
||||||
|
|
||||||
/// A pointer to a function. Written as `fn() -> i32`.
|
/// 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>),
|
TyFnPtr(PolyFnSig<'tcx>),
|
||||||
|
|
||||||
/// A trait, defined with `trait`.
|
/// A trait, defined with `trait`.
|
||||||
|
|
|
@ -881,17 +881,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
|
||||||
-> bool {
|
-> bool {
|
||||||
use rustc::ty::adjustment::*;
|
use rustc::ty::adjustment::*;
|
||||||
|
|
||||||
// Check for method calls and overloaded operators.
|
// Ignore non-expressions.
|
||||||
if let Some(m) = cx.tables.method_map.get(&id).cloned() {
|
let expr = if let hir_map::NodeExpr(e) = cx.tcx.hir.get(id) {
|
||||||
if method_call_refers_to_method(cx.tcx, method, m.def_id, m.substs, id) {
|
e
|
||||||
return true;
|
} else {
|
||||||
}
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check for overloaded autoderef method calls.
|
// Check for overloaded autoderef method calls.
|
||||||
if let Some(Adjustment {
|
if let Some(&Adjustment {
|
||||||
kind: Adjust::DerefRef { ref autoderefs, .. }, ..
|
kind: Adjust::DerefRef { ref autoderefs, .. }, ..
|
||||||
}) = cx.tables.adjustments.get(&id).cloned() {
|
}) = cx.tables.adjustments.get(&id) {
|
||||||
for &overloaded in autoderefs {
|
for &overloaded in autoderefs {
|
||||||
if let Some(m) = overloaded {
|
if let Some(m) = overloaded {
|
||||||
if method_call_refers_to_method(cx.tcx, method, m.def_id, m.substs, id) {
|
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()`).
|
// Check for calls to methods via explicit paths (e.g. `T::method()`).
|
||||||
match cx.tcx.hir.get(id) {
|
match expr.node {
|
||||||
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
|
hir::ExprCall(ref callee, _) => {
|
||||||
let def = if let hir::ExprPath(ref qpath) = callee.node {
|
let def = if let hir::ExprPath(ref qpath) = callee.node {
|
||||||
cx.tables.qpath_def(qpath, callee.id)
|
cx.tables.qpath_def(qpath, callee.id)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -118,7 +118,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||||
overloaded_lvalue(cx,
|
overloaded_lvalue(cx,
|
||||||
self,
|
self,
|
||||||
mt.ty,
|
mt.ty,
|
||||||
method,
|
Some(method),
|
||||||
PassArgs::ByRef,
|
PassArgs::ByRef,
|
||||||
expr.to_ref(),
|
expr.to_ref(),
|
||||||
vec![])
|
vec![])
|
||||||
|
@ -244,8 +244,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
// Here comes the interesting stuff:
|
// Here comes the interesting stuff:
|
||||||
hir::ExprMethodCall(.., ref args) => {
|
hir::ExprMethodCall(.., ref args) => {
|
||||||
// Rewrite a.b(c) into UFCS form like Trait::b(a, c)
|
// 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, None);
|
||||||
let expr = method_callee(cx, expr, method);
|
|
||||||
let args = args.iter()
|
let args = args.iter()
|
||||||
.map(|e| e.to_ref())
|
.map(|e| e.to_ref())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -257,7 +256,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprCall(ref fun, ref args) => {
|
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.
|
// The callee is something implementing Fn, FnMut, or FnOnce.
|
||||||
// Find the actual method implementation being called and
|
// Find the actual method implementation being called and
|
||||||
// build the appropriate UFCS call expression with the
|
// 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))
|
// 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 arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e));
|
||||||
let tupled_args = Expr {
|
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) => {
|
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() {
|
let pass_args = if op.node.is_by_value() {
|
||||||
PassArgs::ByValue
|
PassArgs::ByValue
|
||||||
} else {
|
} else {
|
||||||
|
@ -354,7 +353,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
};
|
};
|
||||||
overloaded_operator(cx,
|
overloaded_operator(cx,
|
||||||
expr,
|
expr,
|
||||||
method,
|
None,
|
||||||
pass_args,
|
pass_args,
|
||||||
lhs.to_ref(),
|
lhs.to_ref(),
|
||||||
vec![rhs])
|
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::ExprLit(..) => ExprKind::Literal { literal: cx.const_eval_literal(expr) },
|
||||||
|
|
||||||
hir::ExprBinary(op, ref lhs, ref rhs) => {
|
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() {
|
let pass_args = if op.node.is_by_value() {
|
||||||
PassArgs::ByValue
|
PassArgs::ByValue
|
||||||
} else {
|
} else {
|
||||||
|
@ -378,7 +377,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
};
|
};
|
||||||
overloaded_operator(cx,
|
overloaded_operator(cx,
|
||||||
expr,
|
expr,
|
||||||
method,
|
None,
|
||||||
pass_args,
|
pass_args,
|
||||||
lhs.to_ref(),
|
lhs.to_ref(),
|
||||||
vec![rhs])
|
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) => {
|
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,
|
overloaded_lvalue(cx,
|
||||||
expr,
|
expr,
|
||||||
expr_ty,
|
expr_ty,
|
||||||
method,
|
None,
|
||||||
PassArgs::ByValue,
|
PassArgs::ByValue,
|
||||||
lhs.to_ref(),
|
lhs.to_ref(),
|
||||||
vec![index])
|
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) => {
|
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,
|
overloaded_lvalue(cx,
|
||||||
expr,
|
expr,
|
||||||
expr_ty,
|
expr_ty,
|
||||||
method,
|
None,
|
||||||
PassArgs::ByValue,
|
PassArgs::ByValue,
|
||||||
arg.to_ref(),
|
arg.to_ref(),
|
||||||
vec![])
|
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) => {
|
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,
|
overloaded_operator(cx,
|
||||||
expr,
|
expr,
|
||||||
method,
|
None,
|
||||||
PassArgs::ByValue,
|
PassArgs::ByValue,
|
||||||
arg.to_ref(),
|
arg.to_ref(),
|
||||||
vec![])
|
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) => {
|
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,
|
overloaded_operator(cx,
|
||||||
expr,
|
expr,
|
||||||
method,
|
None,
|
||||||
PassArgs::ByValue,
|
PassArgs::ByValue,
|
||||||
arg.to_ref(),
|
arg.to_ref(),
|
||||||
vec![])
|
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>,
|
fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
expr: &hir::Expr,
|
expr: &hir::Expr,
|
||||||
callee: ty::MethodCallee<'tcx>)
|
custom_callee: Option<ty::MethodCallee<'tcx>>)
|
||||||
-> Expr<'tcx> {
|
-> Expr<'tcx> {
|
||||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id);
|
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 {
|
Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
temp_lifetime_was_shrunk: was_shrunk,
|
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,
|
span: expr.span,
|
||||||
kind: ExprKind::Literal {
|
kind: ExprKind::Literal {
|
||||||
literal: Literal::Value {
|
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>,
|
fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
expr: &'tcx hir::Expr,
|
expr: &'tcx hir::Expr,
|
||||||
method: ty::MethodCallee<'tcx>,
|
custom_callee: Option<ty::MethodCallee<'tcx>>,
|
||||||
pass_args: PassArgs,
|
pass_args: PassArgs,
|
||||||
receiver: ExprRef<'tcx>,
|
receiver: ExprRef<'tcx>,
|
||||||
args: Vec<&'tcx P<hir::Expr>>)
|
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
|
// now create the call itself
|
||||||
let fun = method_callee(cx, expr, method);
|
let fun = method_callee(cx, expr, custom_callee);
|
||||||
ExprKind::Call {
|
ExprKind::Call {
|
||||||
ty: fun.ty,
|
ty: fun.ty,
|
||||||
fun: fun.to_ref(),
|
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>,
|
fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
expr: &'tcx hir::Expr,
|
expr: &'tcx hir::Expr,
|
||||||
lvalue_ty: Ty<'tcx>,
|
lvalue_ty: Ty<'tcx>,
|
||||||
method: ty::MethodCallee<'tcx>,
|
custom_callee: Option<ty::MethodCallee<'tcx>>,
|
||||||
pass_args: PassArgs,
|
pass_args: PassArgs,
|
||||||
receiver: ExprRef<'tcx>,
|
receiver: ExprRef<'tcx>,
|
||||||
args: Vec<&'tcx P<hir::Expr>>)
|
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,
|
// construct the complete expression `foo()` for the overloaded call,
|
||||||
// which will yield the &T type
|
// which will yield the &T type
|
||||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id);
|
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 {
|
let ref_expr = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
temp_lifetime_was_shrunk: was_shrunk,
|
temp_lifetime_was_shrunk: was_shrunk,
|
||||||
|
|
|
@ -283,7 +283,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
||||||
match e.node {
|
match e.node {
|
||||||
hir::ExprUnary(..) |
|
hir::ExprUnary(..) |
|
||||||
hir::ExprBinary(..) |
|
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;
|
v.promotable = false;
|
||||||
}
|
}
|
||||||
hir::ExprBox(_) => {
|
hir::ExprBox(_) => {
|
||||||
|
@ -380,9 +380,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprMethodCall(..) => {
|
hir::ExprMethodCall(..) => {
|
||||||
let method = v.tables.method_map[&e.id];
|
let def_id = v.tables.type_dependent_defs[&e.id].def_id();
|
||||||
match v.tcx.associated_item(method.def_id).container {
|
match v.tcx.associated_item(def_id).container {
|
||||||
ty::ImplContainer(_) => v.handle_const_fn_call(method.def_id, node_ty),
|
ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty),
|
||||||
ty::TraitContainer(_) => v.promotable = false
|
ty::TraitContainer(_) => v.promotable = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,7 +564,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::MethodCall(..) => {
|
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 {
|
let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
|
||||||
ty::ImplContainer(_) => (Some(method_id), None),
|
ty::ImplContainer(_) => (Some(method_id), None),
|
||||||
ty::TraitContainer(_) => (None, Some(method_id)),
|
ty::TraitContainer(_) => (None, Some(method_id)),
|
||||||
|
|
|
@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
TupleArgumentsFlag::TupleArguments,
|
TupleArgumentsFlag::TupleArguments,
|
||||||
expected);
|
expected);
|
||||||
|
|
||||||
self.tables.borrow_mut().method_map.insert(call_expr.id, method_callee);
|
self.write_method_call(call_expr.id, method_callee);
|
||||||
output_type
|
output_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,7 @@ impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> {
|
||||||
target: method_sig.inputs()[0]
|
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 => {
|
None => {
|
||||||
span_bug!(self.call_expr.span,
|
span_bug!(self.call_expr.span,
|
||||||
|
|
|
@ -475,7 +475,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||||
{
|
{
|
||||||
debug!("convert_lvalue_op_to_mutable({:?}, {:?}, {:?}, {:?})",
|
debug!("convert_lvalue_op_to_mutable({:?}, {:?}, {:?}, {:?})",
|
||||||
op, expr, base_expr, arg_tys);
|
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");
|
debug!("convert_lvalue_op_to_mutable - builtin, nothing to do");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
let (_, method) = self.register_infer_ok_obligations(ok);
|
let (_, method) = self.register_infer_ok_obligations(ok);
|
||||||
debug!("convert_lvalue_op_to_mutable: method={:?}", method);
|
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
|
// Convert the autoref in the base expr to mutable with the correct
|
||||||
// region and mutability.
|
// region and mutability.
|
||||||
|
|
|
@ -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>) {
|
pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) {
|
||||||
if !substs.is_noop() {
|
if !substs.is_noop() {
|
||||||
debug!("write_substs({}, {:?}) in fcx {}",
|
debug!("write_substs({}, {:?}) in fcx {}",
|
||||||
|
@ -2238,7 +2243,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
target: method.sig.inputs()[0]
|
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)
|
(input_ty, self.make_overloaded_lvalue_return_type(method).ty)
|
||||||
});
|
});
|
||||||
if result.is_some() {
|
if result.is_some() {
|
||||||
|
@ -2777,7 +2782,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
expr,
|
expr,
|
||||||
rcvr) {
|
rcvr) {
|
||||||
Ok(method) => {
|
Ok(method) => {
|
||||||
self.tables.borrow_mut().method_map.insert(expr.id, method);
|
self.write_method_call(expr.id, method);
|
||||||
Ok(method)
|
Ok(method)
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
@ -3453,7 +3458,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
target: method.sig.inputs()[0]
|
target: method.sig.inputs()[0]
|
||||||
});
|
});
|
||||||
oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
|
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 {
|
} else {
|
||||||
self.type_error_message(expr.span, |actual| {
|
self.type_error_message(expr.span, |actual| {
|
||||||
format!("type `{}` cannot be \
|
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.
|
// 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,
|
fn finish_resolving_struct_path(&self,
|
||||||
qpath: &hir::QPath,
|
qpath: &hir::QPath,
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
|
@ -3943,7 +3948,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
ty, def, segment);
|
ty, def, segment);
|
||||||
|
|
||||||
// Write back the new resolution.
|
// 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)
|
(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.
|
// 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,
|
pub fn resolve_ty_and_def_ufcs<'b>(&self,
|
||||||
qpath: &'b hir::QPath,
|
qpath: &'b hir::QPath,
|
||||||
node_id: ast::NodeId,
|
node_id: ast::NodeId,
|
||||||
|
@ -3984,7 +3989,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write back the new resolution.
|
// 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))
|
(def, Some(ty), slice::ref_slice(&**item_segment))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -421,7 +421,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
},
|
},
|
||||||
target: method.sig.inputs()[0]
|
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())
|
Ok(method.sig.output())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span),
|
||||||
expr_ty, expr_region);
|
expr_ty, expr_region);
|
||||||
|
|
||||||
let opt_method_callee = self.tables.borrow().method_map.get(&expr.id).cloned();
|
let is_method_call = self.tables.borrow().is_method_call(expr);
|
||||||
let has_method_map = opt_method_callee.is_some();
|
|
||||||
|
|
||||||
// If we are calling a method (either explicitly or via an
|
// If we are calling a method (either explicitly or via an
|
||||||
// overloaded operator), check that all of the types provided as
|
// overloaded operator), check that all of the types provided as
|
||||||
// arguments for its type parameters are well-formed, and all the regions
|
// arguments for its type parameters are well-formed, and all the regions
|
||||||
// provided as arguments outlive the call.
|
// provided as arguments outlive the call.
|
||||||
if let Some(callee) = opt_method_callee {
|
if is_method_call {
|
||||||
let origin = match expr.node {
|
let origin = match expr.node {
|
||||||
hir::ExprMethodCall(..) =>
|
hir::ExprMethodCall(..) =>
|
||||||
infer::ParameterOrigin::MethodCall,
|
infer::ParameterOrigin::MethodCall,
|
||||||
|
@ -537,7 +536,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
|
||||||
infer::ParameterOrigin::OverloadedOperator
|
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.
|
// 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) => {
|
hir::ExprCall(ref callee, ref args) => {
|
||||||
if has_method_map {
|
if is_method_call {
|
||||||
self.constrain_call(expr, Some(&callee),
|
self.constrain_call(expr, Some(&callee),
|
||||||
args.iter().map(|e| &*e), false);
|
args.iter().map(|e| &*e), false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -634,7 +634,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprAssignOp(_, ref lhs, ref rhs) => {
|
hir::ExprAssignOp(_, ref lhs, ref rhs) => {
|
||||||
if has_method_map {
|
if is_method_call {
|
||||||
self.constrain_call(expr, Some(&lhs),
|
self.constrain_call(expr, Some(&lhs),
|
||||||
Some(&**rhs).into_iter(), false);
|
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);
|
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),
|
self.constrain_call(expr, Some(&lhs),
|
||||||
Some(&**rhs).into_iter(), true);
|
Some(&**rhs).into_iter(), true);
|
||||||
|
|
||||||
intravisit::walk_expr(self, expr);
|
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();
|
let implicitly_ref_args = !op.node.is_by_value();
|
||||||
|
|
||||||
// As `expr_method_call`, but the call is via an
|
// 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);
|
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();
|
let implicitly_ref_args = !op.is_by_value();
|
||||||
|
|
||||||
// As above.
|
// As above.
|
||||||
|
@ -686,7 +686,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
hir::ExprUnary(hir::UnDeref, ref base) => {
|
hir::ExprUnary(hir::UnDeref, ref base) => {
|
||||||
// For *a, the lifetime of a must enclose the deref
|
// 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),
|
self.constrain_call(expr, Some(base),
|
||||||
None::<hir::Expr>.iter(), true);
|
None::<hir::Expr>.iter(), true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||||
let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
|
let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
|
||||||
|
|
||||||
if inner_ty.is_scalar() {
|
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) |
|
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);
|
let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty);
|
||||||
|
|
||||||
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
|
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
|
// weird but true: the by-ref binops put an
|
||||||
// adjustment on the lhs but not the rhs; the
|
// adjustment on the lhs but not the rhs; the
|
||||||
|
@ -127,11 +131,11 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||||
match e.node {
|
match e.node {
|
||||||
hir::ExprBinary(..) => {
|
hir::ExprBinary(..) => {
|
||||||
if !op.node.is_by_value() {
|
if !op.node.is_by_value() {
|
||||||
self.fcx.tables.borrow_mut().adjustments.remove(&lhs.id);
|
tables.adjustments.remove(&lhs.id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hir::ExprAssignOp(..) => {
|
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.fix_scalar_builtin_expr(e);
|
||||||
|
|
||||||
self.visit_node_id(e.span, e.id);
|
self.visit_node_id(e.span, e.id);
|
||||||
self.visit_method_map_entry(e.span, e.id);
|
|
||||||
|
|
||||||
if let hir::ExprClosure(_, _, body, _) = e.node {
|
if let hir::ExprClosure(_, _, body, _) = e.node {
|
||||||
let body = self.fcx.tcx.hir.body(body);
|
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) {
|
fn visit_node_id(&mut self, span: Span, node_id: ast::NodeId) {
|
||||||
// Export associated path extensions.
|
// Export associated path extensions and method resultions.
|
||||||
if let Some(def) = self.fcx.tables.borrow_mut().type_relative_path_defs.remove(&node_id) {
|
if let Some(def) = self.fcx.tables.borrow_mut().type_dependent_defs.remove(&node_id) {
|
||||||
self.tables.type_relative_path_defs.insert(node_id, def);
|
self.tables.type_dependent_defs.insert(node_id, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve any borrowings for the node with id `node_id`
|
// 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) {
|
fn visit_liberated_fn_sigs(&mut self) {
|
||||||
for (&node_id, fn_sig) in self.fcx.tables.borrow().liberated_fn_sigs.iter() {
|
for (&node_id, fn_sig) in self.fcx.tables.borrow().liberated_fn_sigs.iter() {
|
||||||
let fn_sig = self.resolve(fn_sig, &node_id);
|
let fn_sig = self.resolve(fn_sig, &node_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue