Skip to content

Commit 4d66986

Browse files
committed
Use larger span for adjustments on method calls
Currently, we use a relatively 'small' span for THIR expressions generated by an 'adjustment' (e.g. an autoderef, autoborrow, unsizing). As a result, if a borrow generated by an adustment ends up causing a borrowcheck error, for example: ```rust let mut my_var = String::new(); let my_ref = &my_var my_var.push('a'); my_ref; ``` then the span for the mutable borrow may end up referring to only the base expression (e.g. `my_var`), rather than the method call which triggered the mutable borrow (e.g. `my_var.push('a')`) Due to a quirk of the MIR borrowck implementation, this doesn't always get exposed in migration mode, but it does in many cases. This commit makes THIR building consistently use 'larger' spans for adjustment expressions The intent of this change it make it clearer to users when it's the specific way in which a variable is used (for example, in a method call) that produdes a borrowcheck error. For example, an error message claiming that a 'mutable borrow occurs here' might be confusing if it just points at a usage of a variable (e.g. `my_var`), when no `&mut` is in sight. Pointing at the entire expression should help to emphasize that the method call itself is responsible for the mutable borrow. In several cases, this makes the `#![feature(nll)]` diagnostic output match up exactly with the default (migration mode) output. As a result, several `.nll.stderr` files end up getting removed entirely.
1 parent 7342213 commit 4d66986

File tree

170 files changed

+453
-583
lines changed

Some content is hidden

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

170 files changed

+453
-583
lines changed

compiler/rustc_mir_build/src/thir/cx/expr.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,17 @@ impl<'tcx> Cx<'tcx> {
3939

4040
let mut expr = self.make_mirror_unadjusted(hir_expr);
4141

42+
let adjustment_span = match self.adjustment_span {
43+
Some((hir_id, span)) if hir_id == hir_expr.hir_id => Some(span),
44+
_ => None,
45+
};
46+
4247
// Now apply adjustments, if any.
4348
for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
4449
debug!("make_mirror: expr={:?} applying adjustment={:?}", expr, adjustment);
45-
expr = self.apply_adjustment(hir_expr, expr, adjustment);
50+
let span = expr.span;
51+
expr =
52+
self.apply_adjustment(hir_expr, expr, adjustment, adjustment_span.unwrap_or(span));
4653
}
4754

4855
// Next, wrap this up in the expr's scope.
@@ -82,8 +89,9 @@ impl<'tcx> Cx<'tcx> {
8289
hir_expr: &'tcx hir::Expr<'tcx>,
8390
mut expr: Expr<'tcx>,
8491
adjustment: &Adjustment<'tcx>,
92+
mut span: Span,
8593
) -> Expr<'tcx> {
86-
let Expr { temp_lifetime, mut span, .. } = expr;
94+
let Expr { temp_lifetime, .. } = expr;
8795

8896
// Adjust the span from the block, to the last expression of the
8997
// block. This is a better span when returning a mutable reference
@@ -150,14 +158,21 @@ impl<'tcx> Cx<'tcx> {
150158

151159
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
152160
let expr_ty = self.typeck_results().expr_ty(expr);
161+
let expr_span = expr.span;
153162
let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
154163

155164
let kind = match expr.kind {
156165
// Here comes the interesting stuff:
157166
hir::ExprKind::MethodCall(_, method_span, ref args, fn_span) => {
158167
// Rewrite a.b(c) into UFCS form like Trait::b(a, c)
159168
let expr = self.method_callee(expr, method_span, None);
169+
// When we apply adjustments to the receiver, use the span of
170+
// the overall method call for better diagnostics. args[0]
171+
// is guaranteed to exist, since a method call always has a receiver.
172+
let old_adjustment_span = self.adjustment_span.replace((args[0].hir_id, expr_span));
173+
tracing::info!("Using method span: {:?}", expr.span);
160174
let args = self.mirror_exprs(args);
175+
self.adjustment_span = old_adjustment_span;
161176
ExprKind::Call {
162177
ty: expr.ty,
163178
fun: self.thir.exprs.push(expr),

compiler/rustc_mir_build/src/thir/cx/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_ast as ast;
99
use rustc_data_structures::steal::Steal;
1010
use rustc_hir as hir;
1111
use rustc_hir::def_id::{DefId, LocalDefId};
12+
use rustc_hir::HirId;
1213
use rustc_hir::Node;
1314
use rustc_middle::middle::region;
1415
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
@@ -46,6 +47,14 @@ struct Cx<'tcx> {
4647
crate region_scope_tree: &'tcx region::ScopeTree,
4748
crate typeck_results: &'tcx ty::TypeckResults<'tcx>,
4849

50+
/// When applying adjustments to the expression
51+
/// with the given `HirId`, use the given `Span`,
52+
/// instead of the usual span. This is used to
53+
/// assign the span of an overall method call
54+
/// (e.g. `my_val.foo()`) to the adjustment expressions
55+
/// for the receiver.
56+
adjustment_span: Option<(HirId, Span)>,
57+
4958
/// The `DefId` of the owner of this body.
5059
body_owner: DefId,
5160
}
@@ -60,6 +69,7 @@ impl<'tcx> Cx<'tcx> {
6069
region_scope_tree: tcx.region_scope_tree(def.did),
6170
typeck_results,
6271
body_owner: def.did.to_def_id(),
72+
adjustment_span: None,
6373
}
6474
}
6575

src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// MIR for `BAR::promoted[0]` after SimplifyCfg-elaborate-drops
22

33
promoted[0] in BAR: &[&i32; 1] = {
4-
let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
4+
let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
55
let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
66
let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
77
let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
@@ -16,8 +16,8 @@ promoted[0] in BAR: &[&i32; 1] = {
1616
// + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
1717
_2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
1818
_1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
19-
_0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
20-
return; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
19+
_0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
20+
return; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
2121
}
2222
}
2323

src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33

44
static mut BAR: *const &i32 = {
55
let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:9:17: 9:28
6-
let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
7-
let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
6+
let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
7+
let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
88
let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
99
let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
1010
let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
11-
+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
11+
+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
1212

1313
bb0: {
14-
StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
15-
StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
14+
StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
15+
StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
1616
- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
1717
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
1818
- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
1919
- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
20-
+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
20+
+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
2121
// ty::Const
2222
- // + ty: &i32
2323
- // + val: Value(Scalar(alloc1))
@@ -28,11 +28,11 @@
2828
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
2929
- _4 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
3030
- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
31-
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
32-
+ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35
31+
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
32+
+ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:44
3333
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[55e6]::BAR), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) }
34-
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
35-
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
34+
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
35+
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
3636
- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35
3737
StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35
3838
_0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44

src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// MIR for `FOO::promoted[0]` after SimplifyCfg-elaborate-drops
22

33
promoted[0] in FOO: &[&i32; 1] = {
4-
let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
4+
let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
55
let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
66
let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
77
let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
@@ -16,8 +16,8 @@ promoted[0] in FOO: &[&i32; 1] = {
1616
// + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
1717
_2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
1818
_1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
19-
_0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
20-
return; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
19+
_0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
20+
return; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
2121
}
2222
}
2323

src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@
33

44
static mut FOO: *const &i32 = {
55
let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:13:17: 13:28
6-
let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
7-
let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
6+
let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
7+
let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
88
let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
99
let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
1010
let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
11-
+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
11+
+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
1212
scope 1 {
1313
}
1414

1515
bb0: {
16-
StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
17-
StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
16+
StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
17+
StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
1818
- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
1919
- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
2020
- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
2121
- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
22-
+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
22+
+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
2323
// ty::Const
2424
- // + ty: *const i32
2525
- // + val: Value(Scalar(alloc3))
@@ -30,11 +30,11 @@
3030
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
3131
- _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
3232
- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
33-
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
34-
+ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46
33+
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
34+
+ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:55
3535
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[55e6]::FOO), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) }
36-
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
37-
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
36+
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
37+
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
3838
- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46
3939
StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46
4040
_0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55

src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
debug s => _1; // in scope 0 at $DIR/deduplicate_blocks.rs:2:36: 2:37
66
let mut _0: bool; // return place in scope 0 at $DIR/deduplicate_blocks.rs:2:48: 2:52
77
let mut _2: &[u8]; // in scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:23
8-
let mut _3: &str; // in scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:12
8+
let mut _3: &str; // in scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:23
99
let mut _4: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:5:9: 5:31
1010
let mut _5: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:5:9: 5:31
1111
let mut _6: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:4:9: 4:37
@@ -19,8 +19,8 @@
1919

2020
bb0: {
2121
StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:23
22-
StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:12
23-
_3 = _1; // scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:12
22+
StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:23
23+
_3 = _1; // scope 0 at $DIR/deduplicate_blocks.rs:3:11: 3:23
2424
StorageLive(_8); // scope 2 at $DIR/deduplicate_blocks.rs:3:11: 3:23
2525
_8 = _3; // scope 2 at $DIR/deduplicate_blocks.rs:3:11: 3:23
2626
- _2 = transmute::<&str, &[u8]>(move _8) -> bb14; // scope 2 at $DIR/deduplicate_blocks.rs:3:11: 3:23

src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
debug upper => _3; // in scope 0 at $DIR/funky_arms.rs:11:69: 11:74
88
let mut _0: std::result::Result<(), std::fmt::Error>; // return place in scope 0 at $DIR/funky_arms.rs:11:85: 11:91
99
let _4: bool; // in scope 0 at $DIR/funky_arms.rs:15:9: 15:19
10-
let mut _5: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:15:22: 15:25
10+
let mut _5: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:15:22: 15:37
1111
let mut _7: std::option::Option<usize>; // in scope 0 at $DIR/funky_arms.rs:24:30: 24:45
12-
let mut _8: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:24:30: 24:33
12+
let mut _8: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:24:30: 24:45
1313
let mut _9: isize; // in scope 0 at $DIR/funky_arms.rs:24:12: 24:27
1414
let mut _11: &mut std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:26:43: 26:46
1515
let mut _12: &T; // in scope 0 at $DIR/funky_arms.rs:26:48: 26:51
@@ -36,8 +36,8 @@
3636

3737
bb0: {
3838
StorageLive(_4); // scope 0 at $DIR/funky_arms.rs:15:9: 15:19
39-
StorageLive(_5); // scope 0 at $DIR/funky_arms.rs:15:22: 15:25
40-
_5 = &(*_1); // scope 0 at $DIR/funky_arms.rs:15:22: 15:25
39+
StorageLive(_5); // scope 0 at $DIR/funky_arms.rs:15:22: 15:37
40+
_5 = &(*_1); // scope 0 at $DIR/funky_arms.rs:15:22: 15:37
4141
_4 = Formatter::sign_plus(move _5) -> bb1; // scope 0 at $DIR/funky_arms.rs:15:22: 15:37
4242
// mir::Constant
4343
// + span: $DIR/funky_arms.rs:15:26: 15:35
@@ -62,8 +62,8 @@
6262

6363
bb4: {
6464
StorageLive(_7); // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
65-
StorageLive(_8); // scope 2 at $DIR/funky_arms.rs:24:30: 24:33
66-
_8 = &(*_1); // scope 2 at $DIR/funky_arms.rs:24:30: 24:33
65+
StorageLive(_8); // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
66+
_8 = &(*_1); // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
6767
_7 = Formatter::precision(move _8) -> bb5; // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
6868
// mir::Constant
6969
// + span: $DIR/funky_arms.rs:24:34: 24:43

0 commit comments

Comments
 (0)