提交 2c2e2c57 编写于 作者: B bors

Auto merge of #54942 - matthewjasper:wf-type-annotations, r=nikomatsakis

[NLL] Check user types are well-formed

Also contains a change of span for AscribeUserType.
I'm not quite sure if this was what @nikomatsakis was thinking.

Closes #54620

r? @nikomatsakis
......@@ -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.
///
......
......@@ -735,7 +735,7 @@ fn super_local_decl(&mut self,
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);
......
......@@ -310,12 +310,12 @@ fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'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!(
......@@ -970,7 +970,7 @@ fn relate_type_and_user_type(
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 @@ fn relate_type_and_user_type(
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(
......
......@@ -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<Ty<'tcx>> {
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>
......
......@@ -292,30 +292,32 @@ pub fn expr_into_pattern(
..
},
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 @@ pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span, for_guard:
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 @@ pub fn visit_bindings(
NodeId,
Span,
Ty<'tcx>,
Option<CanonicalTy<'tcx>>,
Option<(CanonicalTy<'tcx>, Span)>,
),
) {
match *pattern.kind {
......@@ -549,16 +551,15 @@ pub fn visit_bindings(
// 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 @@ fn declare_binding(
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,
......
......@@ -63,9 +63,9 @@ fn simplify_match_pair<'pat>(&mut self,
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(),
});
......
......@@ -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
})
};
......
......@@ -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 @@ fn lower_variant_or_leaf(
kind = PatternKind::AscribeUserType {
subpattern,
user_ty,
user_ty_span: span,
};
}
......@@ -1015,9 +1017,11 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
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,
......
......@@ -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;
......
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: <T as Trait<'b>>::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: <T as Trait<'b>>::Type = make_any();
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: aborting due to 2 previous errors
......@@ -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>() -> 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: <T as Trait<'a>>::Type = loop { };
let b: <T as Trait<'b>>::Type = loop { };
let a: <T as Trait<'a>>::Type = make_any();
let b: <T as Trait<'b>>::Type = make_any();
let _c: <T as Trait<'a>>::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: <T as Trait<'a>>::Type = loop { };
let b: <T as Trait<'b>>::Type = loop { };
let a: <T as Trait<'a>>::Type = make_any();
let b: <T as Trait<'b>>::Type = make_any();
let _c: <T as Trait<'b>>::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: <T as Trait<'a>>::Type = loop { };
let b: <T as Trait<'b>>::Type = loop { };
let a: <T as Trait<'a>>::Type = make_any();
let b: <T as Trait<'b>>::Type = make_any();
let _c: <T as Trait<'a>>::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: <T as Trait<'a>>::Type = loop { };
let b: <T as Trait<'b>>::Type = loop { };
let a: <T as Trait<'a>>::Type = make_any();
let b: <T as Trait<'b>>::Type = make_any();
let _c: <T as Trait<'b>>::Type = b;
}
......
......@@ -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
......@@ -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
......
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
......
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
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
......
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<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: aborting due to previous error
......@@ -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<TheType<'b>> = 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<TheType<'b>> = loop { };
//~^ ERROR reference has a longer lifetime
}
fn main() {
......
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, 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<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | let _x: &'a WithAssoc<TheType<'b>> = 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>() {
| ^^
......
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
......@@ -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
......
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...
......
......@@ -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`.
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`.
......@@ -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
......
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>();
| ^^^^^
......
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
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
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<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: aborting due to previous error
......@@ -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<TheType<'b>> = loop { };
// FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if
// `_x` is changed to `_`
let _x: &'a WithAssoc<TheType<'b>> = loop { };
//~^ ERROR reference has a longer lifetime
}
......
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, 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<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | let _x: &'a WithAssoc<TheType<'b>> = 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>() {
| ^^
......
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<TheType<'b>> = 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<TheType<'b>> = 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<TheType<'b>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<TheType<'b>>>(); //~ ERROR reference has a longer lifetime
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
error: aborting due to 4 previous errors
......@@ -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<TheType<'b>> = 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<TheType<'b>> = 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<TheType<'b>> = loop { };
let _x: &'a WithAssoc<TheType<'b>> = 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<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
//~^ ERROR reference has a longer lifetime
}
fn call_with_assoc<'a,'b>() {
......
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, 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<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | let _x: &'a WithAssoc<TheType<'b>> = 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<TheType<'b>>`, 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<TheType<'b>> = loop { }; //~ ERROR reference has a longer lifetime
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | let _x: &'a WithoutAssoc<TheType<'b>> = 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<TheType<'b>>`, 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<TheType<'b>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
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<TheType<'b>>`, 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<TheType<'b>>>(); //~ 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>() {
| ^^
......
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
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
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
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
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
......@@ -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
......
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
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册