Skip to content

Commit 1a09632

Browse files
authored
Rollup merge of rust-lang#37408 - eddyb:lazy-5, r=nikomatsakis
[5/n] rustc: record the target type of every adjustment. _This is part of a series ([prev](rust-lang#37404) | [next](rust-lang#37412)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments._ <hr> The first commit rearranges `tcx.tables` so that all users go through `tcx.tables()`. This in preparation for per-body `Tables` where they will be requested for a specific `DefId`. Included to minimize churn. The rest of the changes focus on adjustments, there are some renamings, but the main addition is the target type, always available in all cases (as opposed to just for unsizing where it was previously needed). Possibly the most significant effect of this change is that figuring out the final type of an expression is now _always_ just one successful `HashMap` lookup (either the adjustment or, if that doesn't exist, the node type).
2 parents 0f6a71e + 0d7201e commit 1a09632

File tree

47 files changed

+631
-802
lines changed

Some content is hidden

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

47 files changed

+631
-802
lines changed

src/librustc/cfg/construct.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
311311
}
312312

313313
hir::ExprIndex(ref l, ref r) |
314-
hir::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => {
314+
hir::ExprBinary(_, ref l, ref r) if self.tcx.tables().is_method_call(expr.id) => {
315315
self.call(expr, pred, &l, Some(&**r).into_iter())
316316
}
317317

318-
hir::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => {
318+
hir::ExprUnary(_, ref e) if self.tcx.tables().is_method_call(expr.id) => {
319319
self.call(expr, pred, &e, None::<hir::Expr>.iter())
320320
}
321321

@@ -372,9 +372,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
372372
func_or_rcvr: &hir::Expr,
373373
args: I) -> CFGIndex {
374374
let method_call = ty::MethodCall::expr(call_expr.id);
375-
let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
375+
let fn_ty = match self.tcx.tables().method_map.get(&method_call) {
376376
Some(method) => method.ty,
377-
None => self.tcx.expr_ty_adjusted(func_or_rcvr)
377+
None => self.tcx.tables().expr_ty_adjusted(func_or_rcvr)
378378
};
379379

380380
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);

src/librustc/infer/mod.rs

+3-23
Original file line numberDiff line numberDiff line change
@@ -1266,26 +1266,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12661266
self.region_vars.new_bound(debruijn)
12671267
}
12681268

1269-
/// Apply `adjustment` to the type of `expr`
1270-
pub fn adjust_expr_ty(&self,
1271-
expr: &hir::Expr,
1272-
adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1273-
-> Ty<'tcx>
1274-
{
1275-
let raw_ty = self.expr_ty(expr);
1276-
let raw_ty = self.shallow_resolve(raw_ty);
1277-
let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
1278-
raw_ty.adjust(self.tcx,
1279-
expr.span,
1280-
expr.id,
1281-
adjustment,
1282-
|method_call| self.tables
1283-
.borrow()
1284-
.method_map
1285-
.get(&method_call)
1286-
.map(|method| resolve_ty(method.ty)))
1287-
}
1288-
12891269
/// True if errors have been reported since this infcx was
12901270
/// created. This is sometimes used as a heuristic to skip
12911271
/// reporting errors that often occur as a result of earlier
@@ -1622,7 +1602,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16221602
}
16231603

16241604
pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
1625-
let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
1605+
let ty = self.tables.borrow().expr_ty_adjusted(expr);
16261606
self.resolve_type_vars_or_error(&ty)
16271607
}
16281608

@@ -1666,9 +1646,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16661646
.map(|method| method.def_id)
16671647
}
16681648

1669-
pub fn adjustments(&self) -> Ref<NodeMap<adjustment::AutoAdjustment<'tcx>>> {
1649+
pub fn adjustments(&self) -> Ref<NodeMap<adjustment::Adjustment<'tcx>>> {
16701650
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1671-
-> &'a NodeMap<adjustment::AutoAdjustment<'tcx>> {
1651+
-> &'a NodeMap<adjustment::Adjustment<'tcx>> {
16721652
&tables.adjustments
16731653
}
16741654

src/librustc/middle/dead.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
9292
match def {
9393
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
9494
if self.tcx.trait_of_item(def.def_id()).is_some() => {
95-
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
95+
if let Some(substs) = self.tcx.tables().item_substs.get(&id) {
9696
if let ty::TyAdt(tyid, _) = substs.substs.type_at(0).sty {
9797
self.check_def_id(tyid.did);
9898
}
@@ -123,12 +123,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
123123

124124
fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
125125
let method_call = ty::MethodCall::expr(id);
126-
let method = self.tcx.tables.borrow().method_map[&method_call];
126+
let method = self.tcx.tables().method_map[&method_call];
127127
self.check_def_id(method.def_id);
128128
}
129129

130130
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
131-
match self.tcx.expr_ty_adjusted(lhs).sty {
131+
match self.tcx.tables().expr_ty_adjusted(lhs).sty {
132132
ty::TyAdt(def, _) => {
133133
self.insert_def_id(def.struct_variant().field_named(name).did);
134134
}
@@ -137,7 +137,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
137137
}
138138

139139
fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
140-
match self.tcx.expr_ty_adjusted(lhs).sty {
140+
match self.tcx.tables().expr_ty_adjusted(lhs).sty {
141141
ty::TyAdt(def, _) => {
142142
self.insert_def_id(def.struct_variant().fields[idx].did);
143143
}
@@ -148,7 +148,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
148148

149149
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat,
150150
pats: &[codemap::Spanned<hir::FieldPat>]) {
151-
let variant = match self.tcx.node_id_to_type(lhs.id).sty {
151+
let variant = match self.tcx.tables().node_id_to_type(lhs.id).sty {
152152
ty::TyAdt(adt, _) => {
153153
adt.variant_of_def(self.tcx.expect_def(lhs.id))
154154
}
@@ -433,7 +433,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
433433
}
434434

435435
fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
436-
let field_type = self.tcx.node_id_to_type(field.id);
436+
let field_type = self.tcx.tables().node_id_to_type(field.id);
437437
let is_marker_field = match field_type.ty_to_def_id() {
438438
Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)),
439439
_ => false

src/librustc/middle/effect.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
159159
match expr.node {
160160
hir::ExprMethodCall(..) => {
161161
let method_call = MethodCall::expr(expr.id);
162-
let base_type = self.tcx.tables.borrow().method_map[&method_call].ty;
162+
let base_type = self.tcx.tables().method_map[&method_call].ty;
163163
debug!("effect: method call case, base type is {:?}",
164164
base_type);
165165
if type_is_unsafe_function(base_type) {
@@ -168,15 +168,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
168168
}
169169
}
170170
hir::ExprCall(ref base, _) => {
171-
let base_type = self.tcx.expr_ty_adjusted(base);
171+
let base_type = self.tcx.tables().expr_ty_adjusted(base);
172172
debug!("effect: call case, base type is {:?}",
173173
base_type);
174174
if type_is_unsafe_function(base_type) {
175175
self.require_unsafe(expr.span, "call to unsafe function")
176176
}
177177
}
178178
hir::ExprUnary(hir::UnDeref, ref base) => {
179-
let base_type = self.tcx.expr_ty_adjusted(base);
179+
let base_type = self.tcx.tables().expr_ty_adjusted(base);
180180
debug!("effect: unary case, base type is {:?}",
181181
base_type);
182182
if let ty::TyRawPtr(_) = base_type.sty {
@@ -200,7 +200,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
200200
}
201201
}
202202
hir::ExprField(ref base_expr, field) => {
203-
if let ty::TyAdt(adt, ..) = self.tcx.expr_ty_adjusted(base_expr).sty {
203+
if let ty::TyAdt(adt, ..) = self.tcx.tables().expr_ty_adjusted(base_expr).sty {
204204
if adt.is_union() {
205205
self.require_unsafe(field.span, "access to union field");
206206
}
@@ -214,7 +214,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
214214

215215
fn visit_pat(&mut self, pat: &hir::Pat) {
216216
if let PatKind::Struct(_, ref fields, _) = pat.node {
217-
if let ty::TyAdt(adt, ..) = self.tcx.pat_ty(pat).sty {
217+
if let ty::TyAdt(adt, ..) = self.tcx.tables().pat_ty(pat).sty {
218218
if adt.is_union() {
219219
for field in fields {
220220
self.require_unsafe(field.span, "matching on union field");

src/librustc/middle/expr_use_visitor.rs

+23-32
Original file line numberDiff line numberDiff line change
@@ -720,20 +720,33 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
720720
//NOTE(@jroesch): mixed RefCell borrow causes crash
721721
let adj = infcx.adjustments().get(&expr.id).map(|x| x.clone());
722722
if let Some(adjustment) = adj {
723-
match adjustment {
724-
adjustment::AdjustNeverToAny(..) |
725-
adjustment::AdjustReifyFnPointer |
726-
adjustment::AdjustUnsafeFnPointer |
727-
adjustment::AdjustMutToConstPointer => {
723+
match adjustment.kind {
724+
adjustment::Adjust::NeverToAny |
725+
adjustment::Adjust::ReifyFnPointer |
726+
adjustment::Adjust::UnsafeFnPointer |
727+
adjustment::Adjust::MutToConstPointer => {
728728
// Creating a closure/fn-pointer or unsizing consumes
729729
// the input and stores it into the resulting rvalue.
730730
debug!("walk_adjustment: trivial adjustment");
731731
let cmt_unadjusted =
732732
return_if_err!(self.mc.cat_expr_unadjusted(expr));
733733
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
734734
}
735-
adjustment::AdjustDerefRef(ref adj) => {
736-
self.walk_autoderefref(expr, adj);
735+
adjustment::Adjust::DerefRef { autoderefs, autoref, unsize } => {
736+
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
737+
738+
self.walk_autoderefs(expr, autoderefs);
739+
740+
let cmt_derefd =
741+
return_if_err!(self.mc.cat_expr_autoderefd(expr, autoderefs));
742+
743+
let cmt_refd =
744+
self.walk_autoref(expr, cmt_derefd, autoref);
745+
746+
if unsize {
747+
// Unsizing consumes the thin pointer and produces a fat one.
748+
self.delegate_consume(expr.id, expr.span, cmt_refd);
749+
}
737750
}
738751
}
739752
}
@@ -770,28 +783,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
770783
}
771784
}
772785

773-
fn walk_autoderefref(&mut self,
774-
expr: &hir::Expr,
775-
adj: &adjustment::AutoDerefRef<'tcx>) {
776-
debug!("walk_autoderefref expr={:?} adj={:?}",
777-
expr,
778-
adj);
779-
780-
self.walk_autoderefs(expr, adj.autoderefs);
781-
782-
let cmt_derefd =
783-
return_if_err!(self.mc.cat_expr_autoderefd(expr, adj.autoderefs));
784-
785-
let cmt_refd =
786-
self.walk_autoref(expr, cmt_derefd, adj.autoref);
787-
788-
if adj.unsize.is_some() {
789-
// Unsizing consumes the thin pointer and produces a fat one.
790-
self.delegate_consume(expr.id, expr.span, cmt_refd);
791-
}
792-
}
793-
794-
795786
/// Walks the autoref `opt_autoref` applied to the autoderef'd
796787
/// `expr`. `cmt_derefd` is the mem-categorized form of `expr`
797788
/// after all relevant autoderefs have occurred. Because AutoRefs
@@ -803,7 +794,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
803794
fn walk_autoref(&mut self,
804795
expr: &hir::Expr,
805796
cmt_base: mc::cmt<'tcx>,
806-
opt_autoref: Option<adjustment::AutoRef<'tcx>>)
797+
opt_autoref: Option<adjustment::AutoBorrow<'tcx>>)
807798
-> mc::cmt<'tcx>
808799
{
809800
debug!("walk_autoref(expr.id={} cmt_derefd={:?} opt_autoref={:?})",
@@ -822,7 +813,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
822813
};
823814

824815
match *autoref {
825-
adjustment::AutoPtr(r, m) => {
816+
adjustment::AutoBorrow::Ref(r, m) => {
826817
self.delegate.borrow(expr.id,
827818
expr.span,
828819
cmt_base,
@@ -831,7 +822,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
831822
AutoRef);
832823
}
833824

834-
adjustment::AutoUnsafe(m) => {
825+
adjustment::AutoBorrow::RawPtr(m) => {
835826
debug!("walk_autoref: expr.id={} cmt_base={:?}",
836827
expr.id,
837828
cmt_base);

src/librustc/middle/intrinsicck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> {
163163
if let hir::ExprPath(..) = expr.node {
164164
match self.infcx.tcx.expect_def(expr.id) {
165165
Def::Fn(did) if self.def_id_is_transmute(did) => {
166-
let typ = self.infcx.tcx.node_id_to_type(expr.id);
166+
let typ = self.infcx.tcx.tables().node_id_to_type(expr.id);
167167
match typ.sty {
168168
ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
169169
let from = bare_fn_ty.sig.0.inputs[0];

src/librustc/middle/liveness.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
10811081

10821082
hir::ExprAssignOp(_, ref l, ref r) => {
10831083
// an overloaded assign op is like a method call
1084-
if self.ir.tcx.is_method_call(expr.id) {
1084+
if self.ir.tcx.tables().is_method_call(expr.id) {
10851085
let succ = self.propagate_through_expr(&l, succ);
10861086
self.propagate_through_expr(&r, succ)
10871087
} else {
@@ -1113,8 +1113,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11131113

11141114
hir::ExprCall(ref f, ref args) => {
11151115
// FIXME(canndrew): This is_never should really be an is_uninhabited
1116-
let diverges = !self.ir.tcx.is_method_call(expr.id) &&
1117-
self.ir.tcx.expr_ty_adjusted(&f).fn_ret().0.is_never();
1116+
let diverges = !self.ir.tcx.tables().is_method_call(expr.id) &&
1117+
self.ir.tcx.tables().expr_ty_adjusted(&f).fn_ret().0.is_never();
11181118
let succ = if diverges {
11191119
self.s.exit_ln
11201120
} else {
@@ -1126,7 +1126,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11261126

11271127
hir::ExprMethodCall(.., ref args) => {
11281128
let method_call = ty::MethodCall::expr(expr.id);
1129-
let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
1129+
let method_ty = self.ir.tcx.tables().method_map[&method_call].ty;
11301130
// FIXME(canndrew): This is_never should really be an is_uninhabited
11311131
let succ = if method_ty.fn_ret().0.is_never() {
11321132
self.s.exit_ln
@@ -1409,7 +1409,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
14091409
}
14101410

14111411
hir::ExprAssignOp(_, ref l, _) => {
1412-
if !this.ir.tcx.is_method_call(expr.id) {
1412+
if !this.ir.tcx.tables().is_method_call(expr.id) {
14131413
this.check_lvalue(&l);
14141414
}
14151415

@@ -1459,7 +1459,7 @@ fn check_fn(_v: &Liveness,
14591459

14601460
impl<'a, 'tcx> Liveness<'a, 'tcx> {
14611461
fn fn_ret(&self, id: NodeId) -> ty::Binder<Ty<'tcx>> {
1462-
let fn_ty = self.ir.tcx.node_id_to_type(id);
1462+
let fn_ty = self.ir.tcx.tables().node_id_to_type(id);
14631463
match fn_ty.sty {
14641464
ty::TyClosure(closure_def_id, substs) =>
14651465
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
@@ -1502,7 +1502,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
15021502
None if !body.stmts.is_empty() =>
15031503
match body.stmts.last().unwrap().node {
15041504
hir::StmtSemi(ref e, _) => {
1505-
self.ir.tcx.expr_ty(&e) == fn_ret
1505+
self.ir.tcx.tables().expr_ty(&e) == fn_ret
15061506
},
15071507
_ => false
15081508
},

src/librustc/middle/mem_categorization.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
354354
}
355355

356356
fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
357-
let unadjusted_ty = self.expr_ty(expr)?;
358-
Ok(unadjusted_ty.adjust(
359-
self.tcx(), expr.span, expr.id,
360-
self.infcx.adjustments().get(&expr.id),
361-
|method_call| self.infcx.node_method_ty(method_call)))
357+
self.infcx.expr_ty_adjusted(expr)
362358
}
363359

364360
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
@@ -396,19 +392,21 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
396392
}
397393

398394
Some(adjustment) => {
399-
match *adjustment {
400-
adjustment::AdjustDerefRef(
401-
adjustment::AutoDerefRef {
402-
autoref: None, unsize: None, autoderefs, ..}) => {
395+
match adjustment.kind {
396+
adjustment::Adjust::DerefRef {
397+
autoderefs,
398+
autoref: None,
399+
unsize: false
400+
} => {
403401
// Equivalent to *expr or something similar.
404402
self.cat_expr_autoderefd(expr, autoderefs)
405403
}
406404

407-
adjustment::AdjustNeverToAny(..) |
408-
adjustment::AdjustReifyFnPointer |
409-
adjustment::AdjustUnsafeFnPointer |
410-
adjustment::AdjustMutToConstPointer |
411-
adjustment::AdjustDerefRef(_) => {
405+
adjustment::Adjust::NeverToAny |
406+
adjustment::Adjust::ReifyFnPointer |
407+
adjustment::Adjust::UnsafeFnPointer |
408+
adjustment::Adjust::MutToConstPointer |
409+
adjustment::Adjust::DerefRef {..} => {
412410
debug!("cat_expr({:?}): {:?}",
413411
adjustment,
414412
expr);

src/librustc/middle/reachable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
116116
}
117117
hir::ExprMethodCall(..) => {
118118
let method_call = ty::MethodCall::expr(expr.id);
119-
let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
119+
let def_id = self.tcx.tables().method_map[&method_call].def_id;
120120

121121
// Mark the trait item (and, possibly, its default impl) as reachable
122122
// Or mark inherent impl item as reachable

0 commit comments

Comments
 (0)