Skip to content

Commit 55ec104

Browse files
committed
Use the span of the user type for AscribeUserType
Also change the order of the fake read for let and the AscribeUserType, so that we use the better span and message from the fake read in errors.
1 parent 0e07c42 commit 55ec104

23 files changed

+94
-57
lines changed

src/librustc/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
710710
/// e.g. via `let x: T`, then we carry that type here. The MIR
711711
/// borrow checker needs this information since it can affect
712712
/// region inference.
713-
pub user_ty: Option<CanonicalTy<'tcx>>,
713+
pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,
714714

715715
/// Name of the local, used in debuginfo and pretty-printing.
716716
///

src/librustc/mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ macro_rules! make_mir_visitor {
735735
local,
736736
source_info: *source_info,
737737
});
738-
if let Some(user_ty) = user_ty {
738+
if let Some((user_ty, _)) = user_ty {
739739
self.visit_user_ty(user_ty);
740740
}
741741
self.visit_source_info(source_info);

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,12 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
310310
self.super_local_decl(local, local_decl);
311311
self.sanitize_type(local_decl, local_decl.ty);
312312

313-
if let Some(user_ty) = local_decl.user_ty {
313+
if let Some((user_ty, span)) = local_decl.user_ty {
314314
if let Err(terr) = self.cx.relate_type_and_user_type(
315315
local_decl.ty,
316316
ty::Variance::Invariant,
317317
user_ty,
318-
Locations::All(local_decl.source_info.span),
318+
Locations::All(span),
319319
ConstraintCategory::TypeAnnotation,
320320
) {
321321
span_mirbug!(

src/librustc_mir/build/matches/mod.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -292,30 +292,32 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
292292
..
293293
},
294294
user_ty: ascription_user_ty,
295+
user_ty_span,
295296
} => {
296297
let place =
297298
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard);
298299
unpack!(block = self.into(&place, block, initializer));
299300

300-
let source_info = self.source_info(irrefutable_pat.span);
301+
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
302+
let pattern_source_info = self.source_info(irrefutable_pat.span);
301303
self.cfg.push(
302304
block,
303305
Statement {
304-
source_info,
305-
kind: StatementKind::AscribeUserType(
306-
place.clone(),
307-
ty::Variance::Invariant,
308-
ascription_user_ty,
309-
),
306+
source_info: pattern_source_info,
307+
kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
310308
},
311309
);
312310

313-
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
311+
let ty_source_info = self.source_info(user_ty_span);
314312
self.cfg.push(
315313
block,
316314
Statement {
317-
source_info,
318-
kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
315+
source_info: ty_source_info,
316+
kind: StatementKind::AscribeUserType(
317+
place.clone(),
318+
ty::Variance::Invariant,
319+
ascription_user_ty,
320+
),
319321
},
320322
);
321323

@@ -489,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
489491
pub fn visit_bindings(
490492
&mut self,
491493
pattern: &Pattern<'tcx>,
492-
mut pattern_user_ty: Option<CanonicalTy<'tcx>>,
494+
mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
493495
f: &mut impl FnMut(
494496
&mut Self,
495497
Mutability,
@@ -498,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
498500
NodeId,
499501
Span,
500502
Ty<'tcx>,
501-
Option<CanonicalTy<'tcx>>,
503+
Option<(CanonicalTy<'tcx>, Span)>,
502504
),
503505
) {
504506
match *pattern.kind {
@@ -549,16 +551,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
549551
// FIXME(#47184): extract or handle `pattern_user_ty` somehow
550552
self.visit_bindings(subpattern, None, f);
551553
}
552-
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
554+
PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
553555
// This corresponds to something like
554556
//
555557
// ```
556-
// let (p1: T1): T2 = ...;
558+
// let A::<'a>(_): A<'static> = ...;
557559
// ```
558560
//
559-
// Not presently possible, though maybe someday.
560-
assert!(pattern_user_ty.is_none());
561-
self.visit_bindings(subpattern, Some(user_ty), f)
561+
// FIXME(#47184): handle `pattern_user_ty` somehow
562+
self.visit_bindings(subpattern, Some((user_ty, user_ty_span)), f)
562563
}
563564
PatternKind::Leaf { ref subpatterns }
564565
| PatternKind::Variant {
@@ -1469,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
14691470
num_patterns: usize,
14701471
var_id: NodeId,
14711472
var_ty: Ty<'tcx>,
1472-
user_var_ty: Option<CanonicalTy<'tcx>>,
1473+
user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
14731474
has_guard: ArmHasGuard,
14741475
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
14751476
pat_span: Span,

src/librustc_mir/build/matches/simplify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6363
candidate: &mut Candidate<'pat, 'tcx>)
6464
-> Result<(), MatchPair<'pat, 'tcx>> {
6565
match *match_pair.pattern.kind {
66-
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
66+
PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
6767
candidate.ascriptions.push(Ascription {
68-
span: match_pair.pattern.span,
68+
span: user_ty_span,
6969
user_ty,
7070
source: match_pair.place.clone(),
7171
});

src/librustc_mir/hair/cx/block.rs

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
9292
span: pattern.span,
9393
kind: Box::new(PatternKind::AscribeUserType {
9494
user_ty: *user_ty,
95+
user_ty_span: ty.span,
9596
subpattern: pattern
9697
})
9798
};

src/librustc_mir/hair/pattern/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub enum PatternKind<'tcx> {
7171
AscribeUserType {
7272
user_ty: CanonicalTy<'tcx>,
7373
subpattern: Pattern<'tcx>,
74+
user_ty_span: Span,
7475
},
7576

7677
/// x, ref x, x @ P, etc
@@ -692,6 +693,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
692693
kind = PatternKind::AscribeUserType {
693694
subpattern,
694695
user_ty,
696+
user_ty_span: span,
695697
};
696698
}
697699

@@ -1015,9 +1017,11 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
10151017
PatternKind::AscribeUserType {
10161018
ref subpattern,
10171019
user_ty,
1020+
user_ty_span,
10181021
} => PatternKind::AscribeUserType {
10191022
subpattern: subpattern.fold_with(folder),
10201023
user_ty: user_ty.fold_with(folder),
1024+
user_ty_span,
10211025
},
10221026
PatternKind::Binding {
10231027
mutability,

src/test/mir-opt/basic_assignment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ fn main() {
5555
// StorageDead(_3);
5656
// StorageLive(_4);
5757
// _4 = std::option::Option<std::boxed::Box<u32>>::None;
58-
// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
5958
// FakeRead(ForLet, _4);
59+
// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
6060
// StorageLive(_5);
6161
// StorageLive(_6);
6262
// _6 = move _4;

src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
55
| ^^^^^^^^^
66

77
error: higher-ranked subtype error
8-
--> $DIR/hr-fn-aaa-as-aba.rs:32:9
8+
--> $DIR/hr-fn-aaa-as-aba.rs:32:12
99
|
1010
LL | let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
11-
| ^
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/nll/user-annotations/patterns.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,12 @@ LL | y //~ ERROR
131131
| ^ returning this value requires that `'a` must outlive `'static`
132132

133133
error: unsatisfied lifetime constraints
134-
--> $DIR/patterns.rs:117:9
134+
--> $DIR/patterns.rs:117:18
135135
|
136136
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
137137
| -- lifetime `'a` defined here
138138
LL | let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
139-
| ^^^^^^^ type annotation requires that `'a` must outlive `'static`
139+
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
140140

141141
error: aborting due to 14 previous errors
142142

src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
error[E0621]: explicit lifetime required in the type of `v`
2-
--> $DIR/region-object-lifetime-in-coercion.rs:18:9
2+
--> $DIR/region-object-lifetime-in-coercion.rs:18:12
33
|
44
LL | fn a(v: &[u8]) -> Box<Foo + 'static> {
55
| ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
66
LL | let x: Box<Foo + 'static> = Box::new(v);
7-
| ^ lifetime `'static` required
7+
| ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
88

99
error[E0621]: explicit lifetime required in the type of `v`
1010
--> $DIR/region-object-lifetime-in-coercion.rs:24:5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-addr-of-self.rs:17:13
2+
--> $DIR/regions-addr-of-self.rs:17:16
33
|
44
LL | pub fn chase_cat(&mut self) {
55
| - let's call the lifetime of this reference `'1`
66
LL | let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
7-
| ^ type annotation requires that `'1` must outlive `'static`
7+
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
88

99
error: aborting due to previous error
1010

src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-addr-of-upvar-self.rs:20:17
2+
--> $DIR/regions-addr-of-upvar-self.rs:20:20
33
|
44
LL | let _f = || {
55
| -- lifetime `'1` represents this closure's body
66
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
7-
| ^ type annotation requires that `'1` must outlive `'static`
7+
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
88
|
99
= note: closure implements `FnMut`, so references to captured variables can't escape the closure
1010

1111
error: unsatisfied lifetime constraints
12-
--> $DIR/regions-addr-of-upvar-self.rs:20:17
12+
--> $DIR/regions-addr-of-upvar-self.rs:20:20
1313
|
1414
LL | pub fn chase_cat(&mut self) {
1515
| --------- lifetime `'2` appears in the type of `self`
1616
LL | let _f = || {
1717
| -- lifetime `'1` represents this closure's body
1818
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
19-
| ^ type annotation requires that `'1` must outlive `'2`
19+
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'2`
2020
|
2121
= note: closure implements `FnMut`, so references to captured variables can't escape the closure
2222

2323
error: unsatisfied lifetime constraints
24-
--> $DIR/regions-addr-of-upvar-self.rs:20:17
24+
--> $DIR/regions-addr-of-upvar-self.rs:20:20
2525
|
2626
LL | pub fn chase_cat(&mut self) {
2727
| - let's call the lifetime of this reference `'1`
2828
LL | let _f = || {
2929
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
30-
| ^ type annotation requires that `'1` must outlive `'static`
30+
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
3131

3232
error[E0597]: `self` does not live long enough
3333
--> $DIR/regions-addr-of-upvar-self.rs:20:46
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-infer-contravariance-due-to-decl.rs:35:9
2+
--> $DIR/regions-infer-contravariance-due-to-decl.rs:35:12
33
|
44
LL | fn use_<'short,'long>(c: Contravariant<'short>,
55
| ------ ----- lifetime `'long` defined here
66
| |
77
| lifetime `'short` defined here
88
...
99
LL | let _: Contravariant<'long> = c; //~ ERROR E0623
10-
| ^ type annotation requires that `'short` must outlive `'long`
10+
| ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
1111

1212
error: aborting due to previous error
1313

Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-infer-covariance-due-to-decl.rs:32:9
2+
--> $DIR/regions-infer-covariance-due-to-decl.rs:32:12
33
|
44
LL | fn use_<'short,'long>(c: Covariant<'long>,
55
| ------ ----- lifetime `'long` defined here
66
| |
77
| lifetime `'short` defined here
88
...
99
LL | let _: Covariant<'short> = c; //~ ERROR E0623
10-
| ^ type annotation requires that `'short` must outlive `'long`
10+
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
1111

1212
error: aborting due to previous error
1313

Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:9
2+
--> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:12
33
|
44
LL | fn use_<'short,'long>(c: S<'long, 'short>,
55
| ------ ----- lifetime `'long` defined here
66
| |
77
| lifetime `'short` defined here
88
...
99
LL | let _: S<'long, 'long> = c; //~ ERROR E0623
10-
| ^ type annotation requires that `'short` must outlive `'long`
10+
| ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
1111

1212
error: aborting due to previous error
1313

Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-variance-contravariant-use-covariant.rs:33:9
2+
--> $DIR/regions-variance-contravariant-use-covariant.rs:33:12
33
|
44
LL | fn use_<'short,'long>(c: Contravariant<'short>,
55
| ------ ----- lifetime `'long` defined here
66
| |
77
| lifetime `'short` defined here
88
...
99
LL | let _: Contravariant<'long> = c; //~ ERROR E0623
10-
| ^ type annotation requires that `'short` must outlive `'long`
10+
| ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
1111

1212
error: aborting due to previous error
1313

Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-variance-covariant-use-contravariant.rs:33:9
2+
--> $DIR/regions-variance-covariant-use-contravariant.rs:33:12
33
|
44
LL | fn use_<'short,'long>(c: Covariant<'long>,
55
| ------ ----- lifetime `'long` defined here
66
| |
77
| lifetime `'short` defined here
88
...
99
LL | let _: Covariant<'short> = c; //~ ERROR E0623
10-
| ^ type annotation requires that `'short` must outlive `'long`
10+
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
1111

1212
error: aborting due to previous error
1313

Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-variance-invariant-use-contravariant.rs:30:9
2+
--> $DIR/regions-variance-invariant-use-contravariant.rs:30:12
33
|
44
LL | fn use_<'short,'long>(c: Invariant<'long>,
55
| ------ ----- lifetime `'long` defined here
66
| |
77
| lifetime `'short` defined here
88
...
99
LL | let _: Invariant<'short> = c; //~ ERROR E0623
10-
| ^ type annotation requires that `'short` must outlive `'long`
10+
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
1111

1212
error: aborting due to previous error
1313

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: unsatisfied lifetime constraints
2-
--> $DIR/regions-variance-invariant-use-covariant.rs:27:9
2+
--> $DIR/regions-variance-invariant-use-covariant.rs:27:12
33
|
44
LL | fn use_<'b>(c: Invariant<'b>) {
55
| -- lifetime `'b` defined here
66
...
77
LL | let _: Invariant<'static> = c; //~ ERROR mismatched types
8-
| ^ type annotation requires that `'b` must outlive `'static`
8+
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static`
99

1010
error: aborting due to previous error
1111

src/test/ui/try-block/try-block-bad-lifetime.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0597]: `my_string` does not live long enough
22
--> $DIR/try-block-bad-lifetime.rs:25:33
33
|
44
LL | let result: Result<(), &str> = try {
5-
| ------ borrow later used here
5+
| ------ borrow later stored here
66
LL | let my_string = String::from("");
77
LL | let my_str: & str = & my_string;
88
| ^^^^^^^^^^^ borrowed value does not live long enough

0 commit comments

Comments
 (0)