best_blame_constraint
: avoid blaming assignments without user-provided types
This commit is contained in:
parent
31e4d8175a
commit
50222dba2e
19 changed files with 88 additions and 64 deletions
|
@ -2911,7 +2911,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
(
|
(
|
||||||
name,
|
name,
|
||||||
BorrowExplanation::MustBeValidFor {
|
BorrowExplanation::MustBeValidFor {
|
||||||
category: ConstraintCategory::Assignment,
|
category: ConstraintCategory::Assignment { .. },
|
||||||
from_closure: false,
|
from_closure: false,
|
||||||
region_name:
|
region_name:
|
||||||
RegionName {
|
RegionName {
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
|
||||||
fn description(&self) -> &'static str {
|
fn description(&self) -> &'static str {
|
||||||
// Must end with a space. Allows for empty names to be provided.
|
// Must end with a space. Allows for empty names to be provided.
|
||||||
match self {
|
match self {
|
||||||
ConstraintCategory::Assignment => "assignment ",
|
ConstraintCategory::Assignment { .. } => "assignment ",
|
||||||
ConstraintCategory::Return(_) => "returning this value ",
|
ConstraintCategory::Return(_) => "returning this value ",
|
||||||
ConstraintCategory::Yield => "yielding this value ",
|
ConstraintCategory::Yield => "yielding this value ",
|
||||||
ConstraintCategory::UseAsConst => "using this value as a constant ",
|
ConstraintCategory::UseAsConst => "using this value as a constant ",
|
||||||
|
@ -481,7 +481,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
(ConstraintCategory::Return(kind), true, false) if self.is_closure_fn_mut(fr) => {
|
(ConstraintCategory::Return(kind), true, false) if self.is_closure_fn_mut(fr) => {
|
||||||
self.report_fnmut_error(&errci, kind)
|
self.report_fnmut_error(&errci, kind)
|
||||||
}
|
}
|
||||||
(ConstraintCategory::Assignment, true, false)
|
(ConstraintCategory::Assignment { .. }, true, false)
|
||||||
| (ConstraintCategory::CallArgument(_), true, false) => {
|
| (ConstraintCategory::CallArgument(_), true, false) => {
|
||||||
let mut db = self.report_escaping_data_error(&errci);
|
let mut db = self.report_escaping_data_error(&errci);
|
||||||
|
|
||||||
|
@ -672,7 +672,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
// Revert to the normal error in these cases.
|
// Revert to the normal error in these cases.
|
||||||
// Assignments aren't "escapes" in function items.
|
// Assignments aren't "escapes" in function items.
|
||||||
if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none())
|
if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none())
|
||||||
|| (*category == ConstraintCategory::Assignment
|
|| (matches!(category, ConstraintCategory::Assignment { .. })
|
||||||
&& self.regioncx.universal_regions().defining_ty.is_fn_def())
|
&& self.regioncx.universal_regions().defining_ty.is_fn_def())
|
||||||
|| self.regioncx.universal_regions().defining_ty.is_const()
|
|| self.regioncx.universal_regions().defining_ty.is_const()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2034,6 +2034,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
| ConstraintCategory::BoringNoLocation
|
| ConstraintCategory::BoringNoLocation
|
||||||
| ConstraintCategory::Internal
|
| ConstraintCategory::Internal
|
||||||
| ConstraintCategory::Predicate(_)
|
| ConstraintCategory::Predicate(_)
|
||||||
|
| ConstraintCategory::Assignment { has_interesting_ty: false }
|
||||||
) && constraint.span.desugaring_kind().is_none_or(|kind| {
|
) && constraint.span.desugaring_kind().is_none_or(|kind| {
|
||||||
// Try to avoid blaming constraints from desugarings, since they may not clearly
|
// Try to avoid blaming constraints from desugarings, since they may not clearly
|
||||||
// clearly match what users have written. As an exception, allow blaming returns
|
// clearly match what users have written. As an exception, allow blaming returns
|
||||||
|
|
|
@ -892,7 +892,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
Some(l) if !body.local_decls[l].is_user_variable() => {
|
Some(l) if !body.local_decls[l].is_user_variable() => {
|
||||||
ConstraintCategory::Boring
|
ConstraintCategory::Boring
|
||||||
}
|
}
|
||||||
_ => ConstraintCategory::Assignment,
|
Some(l) => ConstraintCategory::Assignment {
|
||||||
|
has_interesting_ty: body.local_decls[l].user_ty.is_some()
|
||||||
|
|| matches!(
|
||||||
|
body.local_decls[l].local_info(),
|
||||||
|
LocalInfo::User(BindingForm::Var(VarBindingForm {
|
||||||
|
opt_ty_info: Some(_),
|
||||||
|
..
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// Assignments to projections should be considered interesting.
|
||||||
|
_ => ConstraintCategory::Assignment { has_interesting_ty: true },
|
||||||
};
|
};
|
||||||
debug!(
|
debug!(
|
||||||
"assignment category: {:?} {:?}",
|
"assignment category: {:?} {:?}",
|
||||||
|
@ -1226,7 +1237,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
Some(l) if !body.local_decls[l].is_user_variable() => {
|
Some(l) if !body.local_decls[l].is_user_variable() => {
|
||||||
ConstraintCategory::Boring
|
ConstraintCategory::Boring
|
||||||
}
|
}
|
||||||
_ => ConstraintCategory::Assignment,
|
// The return type of a call is interesting for diagnostics.
|
||||||
|
_ => ConstraintCategory::Assignment { has_interesting_ty: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
let locations = term_location.to_locations();
|
let locations = term_location.to_locations();
|
||||||
|
|
|
@ -250,7 +250,12 @@ pub enum ConstraintCategory<'tcx> {
|
||||||
CallArgument(#[derive_where(skip)] Option<Ty<'tcx>>),
|
CallArgument(#[derive_where(skip)] Option<Ty<'tcx>>),
|
||||||
CopyBound,
|
CopyBound,
|
||||||
SizedBound,
|
SizedBound,
|
||||||
Assignment,
|
Assignment {
|
||||||
|
/// Whether this assignment is likely to be interesting to refer to in diagnostics.
|
||||||
|
/// Currently, this is true when it's assigning to a projection, when it's assigning from
|
||||||
|
/// the return value of a call, and when it has a user-provided type annotation.
|
||||||
|
has_interesting_ty: bool,
|
||||||
|
},
|
||||||
/// A constraint that came from a usage of a variable (e.g. in an ADT expression
|
/// A constraint that came from a usage of a variable (e.g. in an ADT expression
|
||||||
/// like `Foo { field: my_val }`)
|
/// like `Foo { field: my_val }`)
|
||||||
Usage,
|
Usage,
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
| '?2 live at {bb1[0]}
|
| '?2 live at {bb1[0]}
|
||||||
| '?3 live at {bb1[1..=3]}
|
| '?3 live at {bb1[1..=3]}
|
||||||
| '?4 live at {bb1[4..=7], bb2[0..=2]}
|
| '?4 live at {bb1[4..=7], bb2[0..=2]}
|
||||||
| '?2: '?3 due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0)
|
| '?2: '?3 due to Assignment { has_interesting_ty: false } at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0)
|
||||||
| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0)
|
| '?3: '?4 due to Assignment { has_interesting_ty: false } at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0)
|
||||||
|
|
|
|
||||||
| Borrows
|
| Borrows
|
||||||
| bw0: issued at bb1[0] in '?2
|
| bw0: issued at bb1[0] in '?2
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
| '?2 live at {bb1[0]}
|
| '?2 live at {bb1[0]}
|
||||||
| '?3 live at {bb1[1..=3]}
|
| '?3 live at {bb1[1..=3]}
|
||||||
| '?4 live at {bb1[4..=7], bb2[0..=2]}
|
| '?4 live at {bb1[4..=7], bb2[0..=2]}
|
||||||
| '?2: '?3 due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0)
|
| '?2: '?3 due to Assignment { has_interesting_ty: false } at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0)
|
||||||
| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0)
|
| '?3: '?4 due to Assignment { has_interesting_ty: false } at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0)
|
||||||
|
|
|
|
||||||
| Borrows
|
| Borrows
|
||||||
| bw0: issued at bb1[0] in '?2
|
| bw0: issued at bb1[0] in '?2
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
| '?1 live at {bb0[0..=22]}
|
| '?1 live at {bb0[0..=22]}
|
||||||
| '?2 live at {bb0[10]}
|
| '?2 live at {bb0[10]}
|
||||||
| '?3 live at {bb0[11]}
|
| '?3 live at {bb0[11]}
|
||||||
| '?2: '?3 due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:7:17: 7:25 (#0)
|
| '?2: '?3 due to Assignment { has_interesting_ty: false } at Single(bb0[10]) ($DIR/storage_ranges.rs:7:17: 7:25 (#0)
|
||||||
|
|
|
|
||||||
| Borrows
|
| Borrows
|
||||||
| bw0: issued at bb0[10] in '?2
|
| bw0: issued at bb0[10] in '?2
|
||||||
|
|
|
@ -46,12 +46,12 @@ fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
|
|
||||||
fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
let x = match true {
|
let x = match true {
|
||||||
true => foo::<&'c ()>, //~ ERROR lifetime may not live long enough
|
true => foo::<&'c ()>,
|
||||||
false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough
|
false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough
|
||||||
};
|
};
|
||||||
|
|
||||||
x(a);
|
x(a);
|
||||||
x(b);
|
x(b); //~ ERROR lifetime may not live long enough
|
||||||
x(c);
|
x(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let mut x = foo::<&'a ()>;
|
LL | let mut x = foo::<&'a ()>;
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -22,9 +22,9 @@ LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let mut x = foo::<&'a ()>;
|
LL | let mut x = foo::<&'a ()>;
|
||||||
LL | x = foo::<&'b ()>;
|
LL | x = foo::<&'b ()>;
|
||||||
| ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -53,9 +53,9 @@ LL | fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let mut x = foo::<&'c ()>;
|
LL | let mut x = foo::<&'c ()>;
|
||||||
LL | x = foo::<&'b ()>;
|
LL | x = foo::<&'b ()>;
|
||||||
| ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -69,9 +69,9 @@ LL | fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | x = foo::<&'a ()>;
|
LL | x = foo::<&'a ()>;
|
||||||
| ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -89,9 +89,9 @@ LL | fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let x = match true {
|
LL | let x = match true {
|
||||||
LL | true => foo::<&'b ()>,
|
LL | true => foo::<&'b ()>,
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -105,9 +105,9 @@ LL | fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | false => foo::<&'a ()>,
|
LL | false => foo::<&'a ()>,
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -117,15 +117,15 @@ help: `'a` and `'b` must be the same: replace one with the other
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/fn_def_coercion.rs:49:17
|
--> $DIR/fn_def_coercion.rs:50:18
|
||||||
|
|
|
|
||||||
LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| -- -- lifetime `'c` defined here
|
| -- -- lifetime `'c` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let x = match true {
|
...
|
||||||
LL | true => foo::<&'c ()>,
|
LL | false => foo::<&'a ()>,
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c`
|
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'c`
|
= help: consider adding the following bound: `'a: 'c`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
|
@ -133,20 +133,17 @@ LL | true => foo::<&'c ()>,
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/fn_def_coercion.rs:50:18
|
--> $DIR/fn_def_coercion.rs:54:5
|
||||||
|
|
|
|
||||||
LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | false => foo::<&'a ()>,
|
LL | x(b);
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
|
||||||
|
|
||||||
help: the following changes may resolve your lifetime errors
|
help: the following changes may resolve your lifetime errors
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
|
fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
*v = x;
|
*v = x;
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ex3-both-anon-regions-2.rs:1:14
|
--> $DIR/ex3-both-anon-regions-2.rs:2:5
|
||||||
|
|
|
|
||||||
LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
|
LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
|
||||||
| ^^^^^^^^^ - - let's call the lifetime of this reference `'1`
|
| - - let's call the lifetime of this reference `'1`
|
||||||
| | |
|
| |
|
||||||
| | let's call the lifetime of this reference `'2`
|
| let's call the lifetime of this reference `'2`
|
||||||
| assignment requires that `'1` must outlive `'2`
|
LL | *v = x;
|
||||||
|
| ^^^^^^ assignment requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
= note: requirement occurs because of a mutable reference to `&u8`
|
|
||||||
= note: mutable references are invariant over their type parameter
|
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
|
||||||
help: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) {
|
LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/match-ref-mut-invariance.rs:10:24
|
--> $DIR/match-ref-mut-invariance.rs:10:9
|
||||||
|
|
|
|
||||||
LL | impl<'b> S<'b> {
|
LL | impl<'b> S<'b> {
|
||||||
| -- lifetime `'b` defined here
|
| -- lifetime `'b` defined here
|
||||||
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
|
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | match self.0 { ref mut x => x }
|
LL | match self.0 { ref mut x => x }
|
||||||
| ^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a mutable reference to `&i32`
|
= note: requirement occurs because of a mutable reference to `&i32`
|
||||||
|
|
|
@ -8,8 +8,8 @@ struct S<'b>(&'b i32);
|
||||||
impl<'b> S<'b> {
|
impl<'b> S<'b> {
|
||||||
fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
|
fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
|
||||||
let ref mut x = self.0;
|
let ref mut x = self.0;
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
x
|
x
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/match-ref-mut-let-invariance.rs:10:13
|
--> $DIR/match-ref-mut-let-invariance.rs:11:9
|
||||||
|
|
|
|
||||||
LL | impl<'b> S<'b> {
|
LL | impl<'b> S<'b> {
|
||||||
| -- lifetime `'b` defined here
|
| -- lifetime `'b` defined here
|
||||||
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
|
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let ref mut x = self.0;
|
LL | let ref mut x = self.0;
|
||||||
| ^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
LL | x
|
||||||
|
| ^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a mutable reference to `&i32`
|
= note: requirement occurs because of a mutable reference to `&i32`
|
||||||
|
|
|
@ -4,9 +4,11 @@ error[E0597]: `c` does not live long enough
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | let f = SomeStruct::<&'static u32>;
|
LL | let f = SomeStruct::<&'static u32>;
|
||||||
| -------------------------- assignment requires that `c` is borrowed for `'static`
|
|
||||||
LL | f(&c);
|
LL | f(&c);
|
||||||
| ^^ borrowed value does not live long enough
|
| --^^-
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `c` is borrowed for `'static`
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -18,9 +20,11 @@ LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | let f = SomeStruct::<&'a u32>;
|
LL | let f = SomeStruct::<&'a u32>;
|
||||||
| --------------------- assignment requires that `c` is borrowed for `'a`
|
|
||||||
LL | f(&c);
|
LL | f(&c);
|
||||||
| ^^ borrowed value does not live long enough
|
| --^^-
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `c` is borrowed for `'a`
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -33,9 +37,11 @@ LL | let _closure = || {
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | let f = SomeStruct::<&'a u32>;
|
LL | let f = SomeStruct::<&'a u32>;
|
||||||
| --------------------- assignment requires that `c` is borrowed for `'a`
|
|
||||||
LL | f(&c);
|
LL | f(&c);
|
||||||
| ^^ borrowed value does not live long enough
|
| --^^-
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `c` is borrowed for `'a`
|
||||||
LL | };
|
LL | };
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,11 @@ error[E0597]: `a` does not live long enough
|
||||||
LL | let a = 22;
|
LL | let a = 22;
|
||||||
| - binding `a` declared here
|
| - binding `a` declared here
|
||||||
...
|
...
|
||||||
LL | let x = <&'static u32 as Bazoom<_>>::method;
|
|
||||||
| ----------------------------------- assignment requires that `a` is borrowed for `'static`
|
|
||||||
LL | x(&a, b, c);
|
LL | x(&a, b, c);
|
||||||
| ^^ borrowed value does not live long enough
|
| --^^-------
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `a` is borrowed for `'static`
|
||||||
LL | }
|
LL | }
|
||||||
| - `a` dropped here while still borrowed
|
| - `a` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,11 @@ error[E0597]: `a` does not live long enough
|
||||||
LL | let a = 22;
|
LL | let a = 22;
|
||||||
| - binding `a` declared here
|
| - binding `a` declared here
|
||||||
...
|
...
|
||||||
LL | let x = <&'static u32 as Bazoom<_>>::method;
|
|
||||||
| ----------------------------------- assignment requires that `a` is borrowed for `'static`
|
|
||||||
LL | x(&a, b, c);
|
LL | x(&a, b, c);
|
||||||
| ^^ borrowed value does not live long enough
|
| --^^-------
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `a` is borrowed for `'static`
|
||||||
LL | }
|
LL | }
|
||||||
| - `a` dropped here while still borrowed
|
| - `a` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,11 @@ LL | fn foo<'a>() {
|
||||||
LL | let x = 0;
|
LL | let x = 0;
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
LL | let f = &drop::<&'a i32>;
|
LL | let f = &drop::<&'a i32>;
|
||||||
| ---------------- assignment requires that `x` is borrowed for `'a`
|
|
||||||
LL | f(&x);
|
LL | f(&x);
|
||||||
| ^^ borrowed value does not live long enough
|
| --^^-
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `x` is borrowed for `'a`
|
||||||
LL |
|
LL |
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue