Skip to content

Commit 4ed2eda

Browse files
committed
Auto merge of #42281 - eddyb:well-adjusted, r=nikomatsakis
Decompose Adjustment into smaller steps and remove the method map. The method map held method callee information for: * actual method calls (`x.f(...)`) * overloaded unary, binary, indexing and call operators * *every overloaded deref adjustment* (many can exist for each expression) That last one was a historical ~~accident~~ hack, and part of the motivation for this PR, along with: * a desire to compose adjustments more freely * containing the autoderef logic better to avoid mutation within an inference snapshot * not creating `TyFnDef` types which are incompatible with the original one * i.e. we used to take a`TyFnDef`'s `for<'a> &'a T -> &'a U` signature and instantiate `'a` using a region inference variable, *then* package the resulting `&'b T -> &'b U` signature in another `TyFnDef`, while keeping *the same* `DefId` and `Substs` * to fix #3548 by explicitly writing autorefs for the RHS of comparison operators Individual commits tell their own story, of "atomic" changes avoiding breaking semantics. Future work based on this PR could include: * removing the signature from `TyFnDef`, now that it's always "canonical" * some questions of variance remain, as subtyping *still* treats the signature differently * moving part of the typeck logic for methods, autoderef and coercion into `rustc::traits` * allowing LUB coercions (joining multiple expressions) to "stack up" many adjustments * transitive coercions (e.g. reify or unsize after multiple steps of autoderef) r? @nikomatsakis
2 parents afd4b81 + 5fb37be commit 4ed2eda

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1479
-2147
lines changed

Diff for: src/libcollections/tests/binary_heap.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,22 @@ fn test_push() {
134134
fn test_push_unique() {
135135
let mut heap = BinaryHeap::<Box<_>>::from(vec![box 2, box 4, box 9]);
136136
assert_eq!(heap.len(), 3);
137-
assert!(*heap.peek().unwrap() == box 9);
137+
assert!(**heap.peek().unwrap() == 9);
138138
heap.push(box 11);
139139
assert_eq!(heap.len(), 4);
140-
assert!(*heap.peek().unwrap() == box 11);
140+
assert!(**heap.peek().unwrap() == 11);
141141
heap.push(box 5);
142142
assert_eq!(heap.len(), 5);
143-
assert!(*heap.peek().unwrap() == box 11);
143+
assert!(**heap.peek().unwrap() == 11);
144144
heap.push(box 27);
145145
assert_eq!(heap.len(), 6);
146-
assert!(*heap.peek().unwrap() == box 27);
146+
assert!(**heap.peek().unwrap() == 27);
147147
heap.push(box 3);
148148
assert_eq!(heap.len(), 7);
149-
assert!(*heap.peek().unwrap() == box 27);
149+
assert!(**heap.peek().unwrap() == 27);
150150
heap.push(box 103);
151151
assert_eq!(heap.len(), 8);
152-
assert!(*heap.peek().unwrap() == box 103);
152+
assert!(**heap.peek().unwrap() == 103);
153153
}
154154

155155
fn check_to_vec(mut data: Vec<i32>) {

Diff for: src/librustc/cfg/construct.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
355355
}
356356

357357
hir::ExprIndex(ref l, ref r) |
358-
hir::ExprBinary(_, ref l, ref r) if self.tables.is_method_call(expr.id) => {
358+
hir::ExprBinary(_, ref l, ref r) if self.tables.is_method_call(expr) => {
359359
self.call(expr, pred, &l, Some(&**r).into_iter())
360360
}
361361

362-
hir::ExprUnary(_, ref e) if self.tables.is_method_call(expr.id) => {
362+
hir::ExprUnary(_, ref e) if self.tables.is_method_call(expr) => {
363363
self.call(expr, pred, &e, None::<hir::Expr>.iter())
364364
}
365365

@@ -412,16 +412,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
412412
pred: CFGIndex,
413413
func_or_rcvr: &hir::Expr,
414414
args: I) -> CFGIndex {
415-
let method_call = ty::MethodCall::expr(call_expr.id);
416-
let fn_ty = match self.tables.method_map.get(&method_call) {
417-
Some(method) => method.ty,
418-
None => self.tables.expr_ty_adjusted(func_or_rcvr),
419-
};
420-
421415
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
422416
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
423417
// FIXME(canndrew): This is_never should probably be an is_uninhabited.
424-
if fn_ty.fn_ret().0.is_never() {
418+
if self.tables.expr_ty(call_expr).is_never() {
425419
self.add_unreachable_node()
426420
} else {
427421
ret

Diff for: src/librustc/ich/impls_ty.rs

+11-24
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ use std::mem;
1919
use syntax_pos::symbol::InternedString;
2020
use ty;
2121

22-
impl_stable_hash_for!(struct ty::ItemSubsts<'tcx> { substs });
23-
2422
impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for &'tcx ty::Slice<T>
2523
where T: HashStable<StableHashingContext<'a, 'tcx>> {
2624
fn hash_stable<W: StableHasherResult>(&self,
@@ -101,19 +99,20 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::Ad
10199
ty::adjustment::Adjust::ReifyFnPointer |
102100
ty::adjustment::Adjust::UnsafeFnPointer |
103101
ty::adjustment::Adjust::ClosureFnPointer |
104-
ty::adjustment::Adjust::MutToConstPointer => {}
105-
ty::adjustment::Adjust::DerefRef { autoderefs, ref autoref, unsize } => {
106-
autoderefs.hash_stable(hcx, hasher);
102+
ty::adjustment::Adjust::MutToConstPointer |
103+
ty::adjustment::Adjust::Unsize => {}
104+
ty::adjustment::Adjust::Deref(ref overloaded) => {
105+
overloaded.hash_stable(hcx, hasher);
106+
}
107+
ty::adjustment::Adjust::Borrow(ref autoref) => {
107108
autoref.hash_stable(hcx, hasher);
108-
unsize.hash_stable(hcx, hasher);
109109
}
110110
}
111111
}
112112
}
113113

114114
impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
115-
impl_stable_hash_for!(struct ty::MethodCall { expr_id, autoderef });
116-
impl_stable_hash_for!(struct ty::MethodCallee<'tcx> { def_id, ty, substs });
115+
impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
117116
impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
118117
impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
119118

@@ -601,11 +600,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<'
601600
hcx: &mut StableHashingContext<'a, 'tcx>,
602601
hasher: &mut StableHasher<W>) {
603602
let ty::TypeckTables {
604-
ref type_relative_path_defs,
603+
ref type_dependent_defs,
605604
ref node_types,
606-
ref item_substs,
605+
ref node_substs,
607606
ref adjustments,
608-
ref method_map,
609607
ref upvar_capture_map,
610608
ref closure_tys,
611609
ref closure_kinds,
@@ -622,21 +620,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<'
622620
} = *self;
623621

624622
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
625-
ich::hash_stable_nodemap(hcx, hasher, type_relative_path_defs);
623+
ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs);
626624
ich::hash_stable_nodemap(hcx, hasher, node_types);
627-
ich::hash_stable_nodemap(hcx, hasher, item_substs);
625+
ich::hash_stable_nodemap(hcx, hasher, node_substs);
628626
ich::hash_stable_nodemap(hcx, hasher, adjustments);
629-
630-
ich::hash_stable_hashmap(hcx, hasher, method_map, |hcx, method_call| {
631-
let ty::MethodCall {
632-
expr_id,
633-
autoderef
634-
} = *method_call;
635-
636-
let def_id = hcx.tcx().hir.local_def_id(expr_id);
637-
(hcx.def_path_hash(def_id), autoderef)
638-
});
639-
640627
ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
641628
let ty::UpvarId {
642629
var_id,

Diff for: src/librustc/infer/mod.rs

+13-27
Original file line numberDiff line numberDiff line change
@@ -564,13 +564,14 @@ impl<'tcx, T> InferOk<'tcx, T> {
564564
}
565565

566566
#[must_use = "once you start a snapshot, you should always consume it"]
567-
pub struct CombinedSnapshot {
567+
pub struct CombinedSnapshot<'a, 'tcx:'a> {
568568
projection_cache_snapshot: traits::ProjectionCacheSnapshot,
569569
type_snapshot: type_variable::Snapshot,
570570
int_snapshot: unify::Snapshot<ty::IntVid>,
571571
float_snapshot: unify::Snapshot<ty::FloatVid>,
572572
region_vars_snapshot: RegionSnapshot,
573573
was_in_snapshot: bool,
574+
_in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
574575
}
575576

576577
/// Helper trait for shortening the lifetimes inside a
@@ -888,7 +889,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
888889
result
889890
}
890891

891-
fn start_snapshot(&self) -> CombinedSnapshot {
892+
fn start_snapshot<'b>(&'b self) -> CombinedSnapshot<'b, 'tcx> {
892893
debug!("start_snapshot()");
893894

894895
let in_snapshot = self.in_snapshot.get();
@@ -901,6 +902,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
901902
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
902903
region_vars_snapshot: self.region_vars.start_snapshot(),
903904
was_in_snapshot: in_snapshot,
905+
// Borrow tables "in progress" (i.e. during typeck)
906+
// to ban writes from within a snapshot to them.
907+
_in_progress_tables: match self.tables {
908+
InferTables::InProgress(ref tables) => tables.try_borrow().ok(),
909+
_ => None
910+
}
904911
}
905912
}
906913

@@ -911,7 +918,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
911918
int_snapshot,
912919
float_snapshot,
913920
region_vars_snapshot,
914-
was_in_snapshot } = snapshot;
921+
was_in_snapshot,
922+
_in_progress_tables } = snapshot;
915923

916924
self.in_snapshot.set(was_in_snapshot);
917925

@@ -938,7 +946,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
938946
int_snapshot,
939947
float_snapshot,
940948
region_vars_snapshot,
941-
was_in_snapshot } = snapshot;
949+
was_in_snapshot,
950+
_in_progress_tables } = snapshot;
942951

943952
self.in_snapshot.set(was_in_snapshot);
944953

@@ -1645,29 +1654,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16451654
!traits::type_known_to_meet_bound(self, ty, copy_def_id, span)
16461655
}
16471656

1648-
pub fn node_method_ty(&self, method_call: ty::MethodCall)
1649-
-> Option<Ty<'tcx>> {
1650-
self.tables
1651-
.borrow()
1652-
.method_map
1653-
.get(&method_call)
1654-
.map(|method| method.ty)
1655-
.map(|ty| self.resolve_type_vars_if_possible(&ty))
1656-
}
1657-
1658-
pub fn node_method_id(&self, method_call: ty::MethodCall)
1659-
-> Option<DefId> {
1660-
self.tables
1661-
.borrow()
1662-
.method_map
1663-
.get(&method_call)
1664-
.map(|method| method.def_id)
1665-
}
1666-
1667-
pub fn is_method_call(&self, id: ast::NodeId) -> bool {
1668-
self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
1669-
}
1670-
16711657
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
16721658
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
16731659
}

Diff for: src/librustc/middle/dead.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
9595
}
9696

9797
fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
98-
let method_call = ty::MethodCall::expr(id);
99-
let method = self.tables.method_map[&method_call];
100-
self.check_def_id(method.def_id);
98+
self.check_def_id(self.tables.type_dependent_defs[&id].def_id());
10199
}
102100

103101
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {

Diff for: src/librustc/middle/effect.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use self::RootUnsafeContext::*;
1414

1515
use ty::{self, Ty, TyCtxt};
16-
use ty::MethodCall;
1716
use lint;
1817

1918
use syntax::ast;
@@ -174,8 +173,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
174173
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
175174
match expr.node {
176175
hir::ExprMethodCall(..) => {
177-
let method_call = MethodCall::expr(expr.id);
178-
let base_type = self.tables.method_map[&method_call].ty;
176+
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
177+
let base_type = self.tcx.type_of(def_id);
179178
debug!("effect: method call case, base type is {:?}",
180179
base_type);
181180
if type_is_unsafe_function(base_type) {

0 commit comments

Comments
 (0)