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.
This commit is contained in:
Matthew Jasper 2018-10-09 22:59:46 +01:00
parent 0e07c4281c
commit 55ec104313
23 changed files with 95 additions and 58 deletions

View File

@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
/// e.g. via `let x: T`, then we carry that type here. The MIR
/// borrow checker needs this information since it can affect
/// region inference.
pub user_ty: Option<CanonicalTy<'tcx>>,
pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,
/// Name of the local, used in debuginfo and pretty-printing.
///

View File

@ -735,7 +735,7 @@ macro_rules! make_mir_visitor {
local,
source_info: *source_info,
});
if let Some(user_ty) = user_ty {
if let Some((user_ty, _)) = user_ty {
self.visit_user_ty(user_ty);
}
self.visit_source_info(source_info);

View File

@ -310,12 +310,12 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
self.super_local_decl(local, local_decl);
self.sanitize_type(local_decl, local_decl.ty);
if let Some(user_ty) = local_decl.user_ty {
if let Some((user_ty, span)) = local_decl.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
local_decl.ty,
ty::Variance::Invariant,
user_ty,
Locations::All(local_decl.source_info.span),
Locations::All(span),
ConstraintCategory::TypeAnnotation,
) {
span_mirbug!(

View File

@ -292,16 +292,27 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
..
},
user_ty: ascription_user_ty,
user_ty_span,
} => {
let place =
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard);
unpack!(block = self.into(&place, block, initializer));
let source_info = self.source_info(irrefutable_pat.span);
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let pattern_source_info = self.source_info(irrefutable_pat.span);
self.cfg.push(
block,
Statement {
source_info,
source_info: pattern_source_info,
kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
},
);
let ty_source_info = self.source_info(user_ty_span);
self.cfg.push(
block,
Statement {
source_info: ty_source_info,
kind: StatementKind::AscribeUserType(
place.clone(),
ty::Variance::Invariant,
@ -310,15 +321,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
},
);
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
self.cfg.push(
block,
Statement {
source_info,
kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
},
);
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
block.unit()
}
@ -489,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub fn visit_bindings(
&mut self,
pattern: &Pattern<'tcx>,
mut pattern_user_ty: Option<CanonicalTy<'tcx>>,
mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
f: &mut impl FnMut(
&mut Self,
Mutability,
@ -498,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
NodeId,
Span,
Ty<'tcx>,
Option<CanonicalTy<'tcx>>,
Option<(CanonicalTy<'tcx>, Span)>,
),
) {
match *pattern.kind {
@ -549,16 +551,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// FIXME(#47184): extract or handle `pattern_user_ty` somehow
self.visit_bindings(subpattern, None, f);
}
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
// This corresponds to something like
//
// ```
// let (p1: T1): T2 = ...;
// let A::<'a>(_): A<'static> = ...;
// ```
//
// Not presently possible, though maybe someday.
assert!(pattern_user_ty.is_none());
self.visit_bindings(subpattern, Some(user_ty), f)
// FIXME(#47184): handle `pattern_user_ty` somehow
self.visit_bindings(subpattern, Some((user_ty, user_ty_span)), f)
}
PatternKind::Leaf { ref subpatterns }
| PatternKind::Variant {
@ -1469,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
num_patterns: usize,
var_id: NodeId,
var_ty: Ty<'tcx>,
user_var_ty: Option<CanonicalTy<'tcx>>,
user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
has_guard: ArmHasGuard,
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
pat_span: Span,

View File

@ -63,9 +63,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>)
-> Result<(), MatchPair<'pat, 'tcx>> {
match *match_pair.pattern.kind {
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
candidate.ascriptions.push(Ascription {
span: match_pair.pattern.span,
span: user_ty_span,
user_ty,
source: match_pair.place.clone(),
});

View File

@ -92,6 +92,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
span: pattern.span,
kind: Box::new(PatternKind::AscribeUserType {
user_ty: *user_ty,
user_ty_span: ty.span,
subpattern: pattern
})
};

View File

@ -71,6 +71,7 @@ pub enum PatternKind<'tcx> {
AscribeUserType {
user_ty: CanonicalTy<'tcx>,
subpattern: Pattern<'tcx>,
user_ty_span: Span,
},
/// x, ref x, x @ P, etc
@ -692,6 +693,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
kind = PatternKind::AscribeUserType {
subpattern,
user_ty,
user_ty_span: span,
};
}
@ -1015,9 +1017,11 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
PatternKind::AscribeUserType {
ref subpattern,
user_ty,
user_ty_span,
} => PatternKind::AscribeUserType {
subpattern: subpattern.fold_with(folder),
user_ty: user_ty.fold_with(folder),
user_ty_span,
},
PatternKind::Binding {
mutability,

View File

@ -55,8 +55,8 @@ fn main() {
// StorageDead(_3);
// StorageLive(_4);
// _4 = std::option::Option<std::boxed::Box<u32>>::None;
// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
// FakeRead(ForLet, _4);
// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
// StorageLive(_5);
// StorageLive(_6);
// _6 = move _4;

View File

@ -5,10 +5,10 @@ LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
| ^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/hr-fn-aaa-as-aba.rs:32:9
--> $DIR/hr-fn-aaa-as-aba.rs:32:12
|
LL | let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
| ^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View File

@ -131,12 +131,12 @@ LL | y //~ ERROR
| ^ returning this value requires that `'a` must outlive `'static`
error: unsatisfied lifetime constraints
--> $DIR/patterns.rs:117:9
--> $DIR/patterns.rs:117:18
|
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
| -- lifetime `'a` defined here
LL | let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
| ^^^^^^^ type annotation requires that `'a` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: aborting due to 14 previous errors

View File

@ -1,10 +1,10 @@
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:18:9
--> $DIR/region-object-lifetime-in-coercion.rs:18:12
|
LL | fn a(v: &[u8]) -> Box<Foo + 'static> {
| ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
LL | let x: Box<Foo + 'static> = Box::new(v);
| ^ lifetime `'static` required
| ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:24:5

View File

@ -1,10 +1,10 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-self.rs:17:13
--> $DIR/regions-addr-of-self.rs:17:16
|
LL | pub fn chase_cat(&mut self) {
| - let's call the lifetime of this reference `'1`
LL | let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
error: aborting due to previous error

View File

@ -1,33 +1,33 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-upvar-self.rs:20:17
--> $DIR/regions-addr-of-upvar-self.rs:20:20
|
LL | let _f = || {
| -- lifetime `'1` represents this closure's body
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure
error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-upvar-self.rs:20:17
--> $DIR/regions-addr-of-upvar-self.rs:20:20
|
LL | pub fn chase_cat(&mut self) {
| --------- lifetime `'2` appears in the type of `self`
LL | let _f = || {
| -- lifetime `'1` represents this closure's body
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'2`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'2`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure
error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-upvar-self.rs:20:17
--> $DIR/regions-addr-of-upvar-self.rs:20:20
|
LL | pub fn chase_cat(&mut self) {
| - let's call the lifetime of this reference `'1`
LL | let _f = || {
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
error[E0597]: `self` does not live long enough
--> $DIR/regions-addr-of-upvar-self.rs:20:46

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-infer-contravariance-due-to-decl.rs:35:9
--> $DIR/regions-infer-contravariance-due-to-decl.rs:35:12
|
LL | fn use_<'short,'long>(c: Contravariant<'short>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Contravariant<'short>,
| lifetime `'short` defined here
...
LL | let _: Contravariant<'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-infer-covariance-due-to-decl.rs:32:9
--> $DIR/regions-infer-covariance-due-to-decl.rs:32:12
|
LL | fn use_<'short,'long>(c: Covariant<'long>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Covariant<'long>,
| lifetime `'short` defined here
...
LL | let _: Covariant<'short> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:9
--> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:12
|
LL | fn use_<'short,'long>(c: S<'long, 'short>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: S<'long, 'short>,
| lifetime `'short` defined here
...
LL | let _: S<'long, 'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-contravariant-use-covariant.rs:33:9
--> $DIR/regions-variance-contravariant-use-covariant.rs:33:12
|
LL | fn use_<'short,'long>(c: Contravariant<'short>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Contravariant<'short>,
| lifetime `'short` defined here
...
LL | let _: Contravariant<'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-covariant-use-contravariant.rs:33:9
--> $DIR/regions-variance-covariant-use-contravariant.rs:33:12
|
LL | fn use_<'short,'long>(c: Covariant<'long>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Covariant<'long>,
| lifetime `'short` defined here
...
LL | let _: Covariant<'short> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-invariant-use-contravariant.rs:30:9
--> $DIR/regions-variance-invariant-use-contravariant.rs:30:12
|
LL | fn use_<'short,'long>(c: Invariant<'long>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Invariant<'long>,
| lifetime `'short` defined here
...
LL | let _: Invariant<'short> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -1,11 +1,11 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-invariant-use-covariant.rs:27:9
--> $DIR/regions-variance-invariant-use-covariant.rs:27:12
|
LL | fn use_<'b>(c: Invariant<'b>) {
| -- lifetime `'b` defined here
...
LL | let _: Invariant<'static> = c; //~ ERROR mismatched types
| ^ type annotation requires that `'b` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static`
error: aborting due to previous error

View File

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

View File

@ -1,5 +1,5 @@
error: unsatisfied lifetime constraints
--> $DIR/variance-cell-is-invariant.rs:24:9
--> $DIR/variance-cell-is-invariant.rs:24:12
|
LL | fn use_<'short,'long>(c: Foo<'short>,
| ------ ----- lifetime `'long` defined here
@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Foo<'short>,
| lifetime `'short` defined here
...
LL | let _: Foo<'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
error: aborting due to previous error

View File

@ -9,6 +9,17 @@ LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
LL | u //~ ERROR E0312
| ^ returning this value requires that `'b` must outlive `'a`
error: unsatisfied lifetime constraints
--> $DIR/wf-static-method.rs:36:18
|
LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | let me = Self::make_me(); //~ ERROR lifetime bound not satisfied
| ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
error: unsatisfied lifetime constraints
--> $DIR/wf-static-method.rs:43:9
|
@ -20,5 +31,25 @@ LL | fn inherent_evil(u: &'b u32) -> &'a u32 {
LL | u //~ ERROR E0312
| ^ returning this value requires that `'b` must outlive `'a`
error: aborting due to 2 previous errors
error: unsatisfied lifetime constraints
--> $DIR/wf-static-method.rs:51:5
|
LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | <()>::static_evil(b) //~ ERROR cannot infer an appropriate lifetime
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
error: unsatisfied lifetime constraints
--> $DIR/wf-static-method.rs:55:5
|
LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | <IndirectEvil>::static_evil(b)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
error: aborting due to 5 previous errors