From 55ec10431318bb6b4ed0a01744c93a683918d592 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Tue, 9 Oct 2018 22:59:46 +0100 Subject: [PATCH 1/2] 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. --- src/librustc/mir/mod.rs | 2 +- src/librustc/mir/visit.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 4 +- src/librustc_mir/build/matches/mod.rs | 37 ++++++++++--------- src/librustc_mir/build/matches/simplify.rs | 4 +- src/librustc_mir/hair/cx/block.rs | 1 + src/librustc_mir/hair/pattern/mod.rs | 4 ++ src/test/mir-opt/basic_assignment.rs | 2 +- .../ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr | 4 +- .../ui/nll/user-annotations/patterns.stderr | 4 +- ...ion-object-lifetime-in-coercion.nll.stderr | 4 +- .../regions/regions-addr-of-self.nll.stderr | 4 +- .../regions-addr-of-upvar-self.nll.stderr | 12 +++--- ...nfer-contravariance-due-to-decl.nll.stderr | 4 +- ...ns-infer-covariance-due-to-decl.nll.stderr | 4 +- ...se-covariant-in-second-position.nll.stderr | 4 +- ...nce-contravariant-use-covariant.nll.stderr | 4 +- ...nce-covariant-use-contravariant.nll.stderr | 4 +- ...nce-invariant-use-contravariant.nll.stderr | 4 +- ...ariance-invariant-use-covariant.nll.stderr | 4 +- .../try-block/try-block-bad-lifetime.stderr | 2 +- .../variance-cell-is-invariant.nll.stderr | 4 +- src/test/ui/wf/wf-static-method.nll.stderr | 33 ++++++++++++++++- 23 files changed, 94 insertions(+), 57 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ea4eb761964eb..2587e19b1cb62 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -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>, + pub user_ty: Option<(CanonicalTy<'tcx>, Span)>, /// Name of the local, used in debuginfo and pretty-printing. /// diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index d2b0a6a37a74a..920dc88d6a8fc 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -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); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 36eb695186c67..1f3498b7ae01a 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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!( diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index c2a7172d54cca..394fa4e077c1b 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -292,30 +292,32 @@ 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, - kind: StatementKind::AscribeUserType( - place.clone(), - ty::Variance::Invariant, - ascription_user_ty, - ), + source_info: pattern_source_info, + kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()), }, ); - // Inject a fake read, see comments on `FakeReadCause::ForLet`. + let ty_source_info = self.source_info(user_ty_span); self.cfg.push( block, Statement { - source_info, - kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()), + source_info: ty_source_info, + kind: StatementKind::AscribeUserType( + place.clone(), + ty::Variance::Invariant, + ascription_user_ty, + ), }, ); @@ -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>, + 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>, + 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>, + user_var_ty: Option<(CanonicalTy<'tcx>, Span)>, has_guard: ArmHasGuard, opt_match_place: Option<(Option>, Span)>, pat_span: Span, diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 14da8e9083892..494e7c03c3e68 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -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(), }); diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 2ab0a57a85541..022c606a0f819 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -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 }) }; diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 04090e5087ffc..0238a23895e50 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -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, diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index b474e1a0d6cae..1abe63afa8014 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -55,8 +55,8 @@ fn main() { // StorageDead(_3); // StorageLive(_4); // _4 = std::option::Option>::None; -// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option> }); // FakeRead(ForLet, _4); +// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option> }); // StorageLive(_5); // StorageLive(_6); // _6 = move _4; diff --git a/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr index 9a83872b965c9..a4d47eed6fb0a 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr +++ b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr @@ -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 diff --git a/src/test/ui/nll/user-annotations/patterns.stderr b/src/test/ui/nll/user-annotations/patterns.stderr index b01dc65fc5f9a..0b0848e99137e 100644 --- a/src/test/ui/nll/user-annotations/patterns.stderr +++ b/src/test/ui/nll/user-annotations/patterns.stderr @@ -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 diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr index 53d3b2d5323c2..8fd195639fec3 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr @@ -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 { | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` LL | let x: Box = 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 diff --git a/src/test/ui/regions/regions-addr-of-self.nll.stderr b/src/test/ui/regions/regions-addr-of-self.nll.stderr index 0e38abef668ca..1454c856f9785 100644 --- a/src/test/ui/regions/regions-addr-of-self.nll.stderr +++ b/src/test/ui/regions/regions-addr-of-self.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr index fd52494b49947..0e48192eaffc8 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr index 2f3c716686746..aba285d427b47 100644 --- a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr index 835438e9e5d26..8bc6d565cf1b2 100644 --- a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr +++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr index 706d00a842403..668b75f5733a2 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr index 144aa67f9057a..5d787e6dab699 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr index c9789f8555e8a..3fb290096686d 100644 --- a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr index 488b70b5f0f80..fb59ec1ca1008 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr @@ -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 diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr index fa7cfc33dc0a9..daf6a79136a54 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr @@ -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 diff --git a/src/test/ui/try-block/try-block-bad-lifetime.stderr b/src/test/ui/try-block/try-block-bad-lifetime.stderr index ebf56dc9835f4..061bc19cec997 100644 --- a/src/test/ui/try-block/try-block-bad-lifetime.stderr +++ b/src/test/ui/try-block/try-block-bad-lifetime.stderr @@ -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 diff --git a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr index 0172fcdc8f156..eb01c2bbb05b1 100644 --- a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr +++ b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr @@ -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 diff --git a/src/test/ui/wf/wf-static-method.nll.stderr b/src/test/ui/wf/wf-static-method.nll.stderr index 51aec2a949f99..bfcb16c654ff1 100644 --- a/src/test/ui/wf/wf-static-method.nll.stderr +++ b/src/test/ui/wf/wf-static-method.nll.stderr @@ -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 | ::static_evil(b) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + +error: aborting due to 5 previous errors From c312e04d45fc6254cc25f7277b2d84ff3128c036 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 10 Oct 2018 08:38:17 +0100 Subject: [PATCH 2/2] Check user types are well-formed in MIR borrow check Also update some tests so that they don't have user types on `_` in unreachable code. --- .../borrow_check/nll/type_check/mod.rs | 10 +++- .../borrow_check/nll/type_check/relate_tys.rs | 21 ++++++-- .../associated-types-subtyping-1.nll.stderr | 24 ++++++++++ .../associated-types-subtyping-1.rs | 20 ++++---- ...n-supertrait-outlives-container.nll.stderr | 13 +++++ ...c-type-in-supertrait-outlives-container.rs | 7 +-- ...pe-in-supertrait-outlives-container.stderr | 14 +++--- ...ons-free-region-ordering-caller.nll.stderr | 33 +++++++++++++ .../regions-free-region-ordering-caller.rs | 2 - ...regions-free-region-ordering-caller.stderr | 6 +-- ...ns-free-region-ordering-caller1.nll.stderr | 20 +++++++- ...implied-bounds-projection-gap-1.nll.stderr | 11 +++++ ...regions-implied-bounds-projection-gap-1.rs | 2 - ...ons-implied-bounds-projection-gap-1.stderr | 4 +- ...utlives-projection-container-wc.nll.stderr | 13 +++++ ...egions-outlives-projection-container-wc.rs | 6 +-- ...ns-outlives-projection-container-wc.stderr | 14 +++--- ...s-outlives-projection-container.nll.stderr | 46 ++++++++++++++++++ .../regions-outlives-projection-container.rs | 12 +++-- ...gions-outlives-projection-container.stderr | 48 +++++++++---------- 20 files changed, 249 insertions(+), 77 deletions(-) create mode 100644 src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr create mode 100644 src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr create mode 100644 src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container.nll.stderr diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 1f3498b7ae01a..e11f452e16be1 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -970,7 +970,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { locations: Locations, category: ConstraintCategory, ) -> Fallible<()> { - relate_tys::relate_type_and_user_type( + let ty = relate_tys::relate_type_and_user_type( self.infcx, a, v, @@ -978,7 +978,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { locations, category, self.borrowck_context.as_mut().map(|x| &mut **x), - ) + )?; + self.prove_predicate( + ty::Predicate::WellFormed(ty), + locations, + category, + ); + Ok(()) } fn eq_opaque_type_and_type( diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 41aab02d1e826..1e279aef07981 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -10,7 +10,7 @@ use borrow_check::nll::constraints::OutlivesConstraint; use borrow_check::nll::type_check::{BorrowCheckContext, Locations}; -use rustc::infer::canonical::{Canonical, CanonicalVarInfos}; +use rustc::infer::canonical::{Canonical, CanonicalVarInfos, CanonicalVarValues}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::mir::ConstraintCategory; use rustc::traits::query::Fallible; @@ -70,7 +70,7 @@ pub(super) fn relate_type_and_user_type<'tcx>( locations: Locations, category: ConstraintCategory, borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>, -) -> Fallible<()> { +) -> Fallible> { debug!( "sub_type_and_user_type(a={:?}, b={:?}, locations={:?})", a, b, locations @@ -85,13 +85,24 @@ pub(super) fn relate_type_and_user_type<'tcx>( // variance to get the right relationship. let v1 = ty::Contravariant.xform(v); - TypeRelating::new( + let mut type_relating = TypeRelating::new( infcx.tcx, NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category), v1, b_variables, - ).relate(&b_value, &a)?; - Ok(()) + ); + type_relating.relate(&b_value, &a)?; + + Ok(b.substitute( + infcx.tcx, + &CanonicalVarValues { + var_values: type_relating + .canonical_var_values + .into_iter() + .map(|x| x.expect("unsubstituted canonical variable")) + .collect(), + }, + )) } struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D> diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr b/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr new file mode 100644 index 0000000000000..1156c773b8c5a --- /dev/null +++ b/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr @@ -0,0 +1,24 @@ +error: unsatisfied lifetime constraints + --> $DIR/associated-types-subtyping-1.rs:36:13 + | +LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _c: >::Type = a; //~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: unsatisfied lifetime constraints + --> $DIR/associated-types-subtyping-1.rs:44:12 + | +LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let b: >::Type = make_any(); + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.rs b/src/test/ui/associated-types/associated-types-subtyping-1.rs index c3acffff240b5..479cb359a781f 100644 --- a/src/test/ui/associated-types/associated-types-subtyping-1.rs +++ b/src/test/ui/associated-types/associated-types-subtyping-1.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - #![allow(unused_variables)] +fn make_any() -> T { loop {} } + trait Trait<'a> { type Type; @@ -22,8 +22,8 @@ fn method1<'a,'b,T>(x: &'a T, y: &'b T) where T : for<'z> Trait<'z>, 'a : 'b { // Note that &'static T <: &'a T. - let a: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::Type = a; } @@ -31,8 +31,8 @@ fn method2<'a,'b,T>(x: &'a T, y: &'b T) where T : for<'z> Trait<'z>, 'a : 'b { // Note that &'static T <: &'a T. - let a: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::Type = a; //~ ERROR E0623 } @@ -40,8 +40,8 @@ fn method3<'a,'b,T>(x: &'a T, y: &'b T) where T : for<'z> Trait<'z>, 'a : 'b { // Note that &'static T <: &'a T. - let a: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::Type = b; //~ ERROR E0623 } @@ -49,8 +49,8 @@ fn method4<'a,'b,T>(x: &'a T, y: &'b T) where T : for<'z> Trait<'z>, 'a : 'b { // Note that &'static T <: &'a T. - let a: >::Type = loop { }; - let b: >::Type = loop { }; + let a: >::Type = make_any(); + let b: >::Type = make_any(); let _c: >::Type = b; } diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr new file mode 100644 index 0000000000000..f711541fbd5c2 --- /dev/null +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr @@ -0,0 +1,13 @@ +error: unsatisfied lifetime constraints + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:52:13 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs index 96eb65daaffef..741feb1f9eaf4 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Test that we are imposing the requirement that every associated // type of a bound that appears in the where clause on a struct must // outlive the location in which the type appears, even when the @@ -49,7 +47,10 @@ fn with_assoc<'a,'b>() { // outlive 'a. In this case, that means TheType<'b>::TheAssocType, // which is &'b (), must outlive 'a. - let _: &'a WithAssoc> = loop { }; //~ ERROR reference has a longer lifetime + // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if + // `_x` is changed to `_` + let _x: &'a WithAssoc> = loop { }; + //~^ ERROR reference has a longer lifetime } fn main() { diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr index 7b7881d6ea7ca..7959d1b6c2300 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.stderr @@ -1,16 +1,16 @@ error[E0491]: in type `&'a WithAssoc>`, reference has a longer lifetime than the data it references - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:52:12 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:52:13 | -LL | let _: &'a WithAssoc> = loop { }; //~ ERROR reference has a longer lifetime - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 46:15 - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:46:15 +note: the pointer is valid for the lifetime 'a as defined on the function body at 44:15 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 46:18 - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:46:18 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 44:18 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:18 | LL | fn with_assoc<'a,'b>() { | ^^ diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr new file mode 100644 index 0000000000000..8d4f3d1e87fba --- /dev/null +++ b/src/test/ui/regions/regions-free-region-ordering-caller.nll.stderr @@ -0,0 +1,33 @@ +error: unsatisfied lifetime constraints + --> $DIR/regions-free-region-ordering-caller.rs:18:12 + | +LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let z: Option<&'b &'a usize> = None;//~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: unsatisfied lifetime constraints + --> $DIR/regions-free-region-ordering-caller.rs:23:12 + | +LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let y: Paramd<'a> = Paramd { x: a }; +LL | let z: Option<&'b Paramd<'a>> = None;//~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: unsatisfied lifetime constraints + --> $DIR/regions-free-region-ordering-caller.rs:27:12 + | +LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let z: Option<&'a &'b usize> = None;//~ ERROR E0623 + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.rs b/src/test/ui/regions/regions-free-region-ordering-caller.rs index ee6cd6c4b1523..66b16744cc7df 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller.rs +++ b/src/test/ui/regions/regions-free-region-ordering-caller.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Test various ways to construct a pointer with a longer lifetime // than the thing it points at and ensure that they result in // errors. See also regions-free-region-ordering-callee.rs diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.stderr index 96502b69c0819..a3645995b5ea2 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-caller.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-free-region-ordering-caller.rs:20:12 + --> $DIR/regions-free-region-ordering-caller.rs:18:12 | LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { | --------- --------- @@ -9,7 +9,7 @@ LL | let z: Option<&'b &'a usize> = None;//~ ERROR E0623 | ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here error[E0623]: lifetime mismatch - --> $DIR/regions-free-region-ordering-caller.rs:25:12 + --> $DIR/regions-free-region-ordering-caller.rs:23:12 | LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { | --------- --------- @@ -20,7 +20,7 @@ LL | let z: Option<&'b Paramd<'a>> = None;//~ ERROR E0623 | ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here error[E0623]: lifetime mismatch - --> $DIR/regions-free-region-ordering-caller.rs:29:12 + --> $DIR/regions-free-region-ordering-caller.rs:27:12 | LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { | --------- --------- these two types are declared with different lifetimes... diff --git a/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr index 75758206d6b48..9747602f1ba48 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-caller1.nll.stderr @@ -13,6 +13,22 @@ note: borrowed value must be valid for the lifetime 'a as defined on the functio LL | fn call1<'a>(x: &'a usize) { | ^^ -error: aborting due to previous error +error[E0597]: `y` does not live long enough + --> $DIR/regions-free-region-ordering-caller1.rs:19:27 + | +LL | let z: &'a & usize = &(&y); + | ^^^^ borrowed value does not live long enough +... +LL | } + | - `y` dropped here while still borrowed + | +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 15:10... + --> $DIR/regions-free-region-ordering-caller1.rs:15:10 + | +LL | fn call1<'a>(x: &'a usize) { + | ^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0716`. +Some errors occurred: E0597, E0716. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr new file mode 100644 index 0000000000000..2eb4ccf1c35f3 --- /dev/null +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr @@ -0,0 +1,11 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regions-implied-bounds-projection-gap-1.rs:26:5 + | +LL | wf::<&'x T>(); + | ^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'x`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs index 01de3ddcdf8d9..65594ab8f2e29 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Illustrates the "projection gap": in this test, even though we know // that `T::Foo: 'x`, that does not tell us that `T: 'x`, because // there might be other ways for the caller of `func` to show that diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr index e6efb4d5c6b5d..41ae515bb9a16 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr @@ -1,5 +1,5 @@ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-implied-bounds-projection-gap-1.rs:28:10 + --> $DIR/regions-implied-bounds-projection-gap-1.rs:26:10 | LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo) | -- help: consider adding an explicit lifetime bound `T: 'x`... @@ -8,7 +8,7 @@ LL | wf::<&'x T>(); | ^^^^^ | note: ...so that the reference type `&'x T` does not outlive the data it points at - --> $DIR/regions-implied-bounds-projection-gap-1.rs:28:10 + --> $DIR/regions-implied-bounds-projection-gap-1.rs:26:10 | LL | wf::<&'x T>(); | ^^^^^ diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr new file mode 100644 index 0000000000000..836f8c28a737a --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr @@ -0,0 +1,13 @@ +error: unsatisfied lifetime constraints + --> $DIR/regions-outlives-projection-container-wc.rs:46:13 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.rs b/src/test/ui/regions/regions-outlives-projection-container-wc.rs index 79300d5176ecc..22ec58d1367bc 100644 --- a/src/test/ui/regions/regions-outlives-projection-container-wc.rs +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Test that we are imposing the requirement that every associated // type of a bound that appears in the where clause on a struct must // outlive the location in which the type appears, even when the @@ -43,7 +41,9 @@ fn with_assoc<'a,'b>() { // outlive 'a. In this case, that means TheType<'b>::TheAssocType, // which is &'b (), must outlive 'a. - let _: &'a WithAssoc> = loop { }; + // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if + // `_x` is changed to `_` + let _x: &'a WithAssoc> = loop { }; //~^ ERROR reference has a longer lifetime } diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.stderr index d0680ecbb99a2..e5bc52d7b663f 100644 --- a/src/test/ui/regions/regions-outlives-projection-container-wc.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.stderr @@ -1,16 +1,16 @@ error[E0491]: in type `&'a WithAssoc>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container-wc.rs:46:12 + --> $DIR/regions-outlives-projection-container-wc.rs:46:13 | -LL | let _: &'a WithAssoc> = loop { }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 40:15 - --> $DIR/regions-outlives-projection-container-wc.rs:40:15 +note: the pointer is valid for the lifetime 'a as defined on the function body at 38:15 + --> $DIR/regions-outlives-projection-container-wc.rs:38:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 40:18 - --> $DIR/regions-outlives-projection-container-wc.rs:40:18 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 38:18 + --> $DIR/regions-outlives-projection-container-wc.rs:38:18 | LL | fn with_assoc<'a,'b>() { | ^^ diff --git a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr new file mode 100644 index 0000000000000..126f50577c84f --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr @@ -0,0 +1,46 @@ +error: unsatisfied lifetime constraints + --> $DIR/regions-outlives-projection-container.rs:50:13 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: unsatisfied lifetime constraints + --> $DIR/regions-outlives-projection-container.rs:68:13 + | +LL | fn without_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithoutAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: unsatisfied lifetime constraints + --> $DIR/regions-outlives-projection-container.rs:77:5 + | +LL | fn call_with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | call::<&'a WithAssoc>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + +error: unsatisfied lifetime constraints + --> $DIR/regions-outlives-projection-container.rs:84:5 + | +LL | fn call_without_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | call::<&'a WithoutAssoc>>(); //~ ERROR reference has a longer lifetime + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/regions/regions-outlives-projection-container.rs b/src/test/ui/regions/regions-outlives-projection-container.rs index e4b7a0f82db39..08fd7080e52c6 100644 --- a/src/test/ui/regions/regions-outlives-projection-container.rs +++ b/src/test/ui/regions/regions-outlives-projection-container.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Test that we are imposing the requirement that every associated // type of a bound that appears in the where clause on a struct must // outlive the location in which the type appears. Issue #22246. @@ -47,7 +45,10 @@ fn with_assoc<'a,'b>() { // outlive 'a. In this case, that means TheType<'b>::TheAssocType, // which is &'b (), must outlive 'a. - let _: &'a WithAssoc> = loop { }; //~ ERROR reference has a longer lifetime + // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if + // `_x` is changed to `_` + let _x: &'a WithAssoc> = loop { }; + //~^ ERROR reference has a longer lifetime } fn with_assoc1<'a,'b>() where 'b : 'a { @@ -57,14 +58,15 @@ fn with_assoc1<'a,'b>() where 'b : 'a { // which is &'b (), must outlive 'a, so 'b : 'a must hold, and // that is in the where clauses, so we're fine. - let _: &'a WithAssoc> = loop { }; + let _x: &'a WithAssoc> = loop { }; } fn without_assoc<'a,'b>() { // Here there are no associated types but there is a requirement // that `'b:'a` holds because the `'b` appears in `TheType<'b>`. - let _: &'a WithoutAssoc> = loop { }; //~ ERROR reference has a longer lifetime + let _x: &'a WithoutAssoc> = loop { }; + //~^ ERROR reference has a longer lifetime } fn call_with_assoc<'a,'b>() { diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.stderr index 2a698f9bff5a4..2c37d94361603 100644 --- a/src/test/ui/regions/regions-outlives-projection-container.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container.stderr @@ -1,67 +1,67 @@ error[E0491]: in type `&'a WithAssoc>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:50:12 + --> $DIR/regions-outlives-projection-container.rs:50:13 | -LL | let _: &'a WithAssoc> = loop { }; //~ ERROR reference has a longer lifetime - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 44:15 - --> $DIR/regions-outlives-projection-container.rs:44:15 +note: the pointer is valid for the lifetime 'a as defined on the function body at 42:15 + --> $DIR/regions-outlives-projection-container.rs:42:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 44:18 - --> $DIR/regions-outlives-projection-container.rs:44:18 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 42:18 + --> $DIR/regions-outlives-projection-container.rs:42:18 | LL | fn with_assoc<'a,'b>() { | ^^ error[E0491]: in type `&'a WithoutAssoc>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:67:12 + --> $DIR/regions-outlives-projection-container.rs:68:13 | -LL | let _: &'a WithoutAssoc> = loop { }; //~ ERROR reference has a longer lifetime - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _x: &'a WithoutAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 63:18 - --> $DIR/regions-outlives-projection-container.rs:63:18 +note: the pointer is valid for the lifetime 'a as defined on the function body at 64:18 + --> $DIR/regions-outlives-projection-container.rs:64:18 | LL | fn without_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 63:21 - --> $DIR/regions-outlives-projection-container.rs:63:21 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 64:21 + --> $DIR/regions-outlives-projection-container.rs:64:21 | LL | fn without_assoc<'a,'b>() { | ^^ error[E0491]: in type `&'a WithAssoc>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:75:12 + --> $DIR/regions-outlives-projection-container.rs:77:12 | LL | call::<&'a WithAssoc>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 70:20 - --> $DIR/regions-outlives-projection-container.rs:70:20 +note: the pointer is valid for the lifetime 'a as defined on the function body at 72:20 + --> $DIR/regions-outlives-projection-container.rs:72:20 | LL | fn call_with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 70:23 - --> $DIR/regions-outlives-projection-container.rs:70:23 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 72:23 + --> $DIR/regions-outlives-projection-container.rs:72:23 | LL | fn call_with_assoc<'a,'b>() { | ^^ error[E0491]: in type `&'a WithoutAssoc>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:82:12 + --> $DIR/regions-outlives-projection-container.rs:84:12 | LL | call::<&'a WithoutAssoc>>(); //~ ERROR reference has a longer lifetime | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 79:23 - --> $DIR/regions-outlives-projection-container.rs:79:23 +note: the pointer is valid for the lifetime 'a as defined on the function body at 81:23 + --> $DIR/regions-outlives-projection-container.rs:81:23 | LL | fn call_without_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 79:26 - --> $DIR/regions-outlives-projection-container.rs:79:26 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 81:26 + --> $DIR/regions-outlives-projection-container.rs:81:26 | LL | fn call_without_assoc<'a,'b>() { | ^^