diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2d993a3fd16..8a43e4b54b1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2911,7 +2911,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ( name, BorrowExplanation::MustBeValidFor { - category: ConstraintCategory::Assignment, + category: ConstraintCategory::Assignment { .. }, from_closure: false, region_name: RegionName { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 481b8d41f10..78809908180 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -41,7 +41,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { fn description(&self) -> &'static str { // Must end with a space. Allows for empty names to be provided. match self { - ConstraintCategory::Assignment => "assignment ", + ConstraintCategory::Assignment { .. } => "assignment ", ConstraintCategory::Return(_) => "returning this value ", ConstraintCategory::Yield => "yielding this value ", 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) => { self.report_fnmut_error(&errci, kind) } - (ConstraintCategory::Assignment, true, false) + (ConstraintCategory::Assignment { .. }, true, false) | (ConstraintCategory::CallArgument(_), true, false) => { 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. // Assignments aren't "escapes" in function items. 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_const() { diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 4ceb2fcd8d7..7e8fad8698a 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2034,6 +2034,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { | ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal | ConstraintCategory::Predicate(_) + | ConstraintCategory::Assignment { has_interesting_ty: false } ) && constraint.span.desugaring_kind().is_none_or(|kind| { // Try to avoid blaming constraints from desugarings, since they may not clearly // clearly match what users have written. As an exception, allow blaming returns diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 10fb8a399a2..a436edd85d9 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -892,7 +892,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Some(l) if !body.local_decls[l].is_user_variable() => { 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!( "assignment category: {:?} {:?}", @@ -1226,7 +1237,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Some(l) if !body.local_decls[l].is_user_variable() => { 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(); diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 429be9bc725..c2bb95a91c4 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -250,7 +250,12 @@ pub enum ConstraintCategory<'tcx> { CallArgument(#[derive_where(skip)] Option>), CopyBound, 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 /// like `Foo { field: my_val }`) Usage, diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 35e44b2314a..7f4a2bbbb5c 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -17,8 +17,8 @@ | '?2 live at {bb1[0]} | '?3 live at {bb1[1..=3]} | '?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) -| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#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 { has_interesting_ty: false } at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0) | | Borrows | bw0: issued at bb1[0] in '?2 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 6d415f42d06..1d80df76b3f 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -17,8 +17,8 @@ | '?2 live at {bb1[0]} | '?3 live at {bb1[1..=3]} | '?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) -| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#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 { has_interesting_ty: false } at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0) | | Borrows | bw0: issued at bb1[0] in '?2 diff --git a/tests/mir-opt/storage_ranges.main.nll.0.mir b/tests/mir-opt/storage_ranges.main.nll.0.mir index ae8cd0c894d..291e3bbc873 100644 --- a/tests/mir-opt/storage_ranges.main.nll.0.mir +++ b/tests/mir-opt/storage_ranges.main.nll.0.mir @@ -15,7 +15,7 @@ | '?1 live at {bb0[0..=22]} | '?2 live at {bb0[10]} | '?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 | bw0: issued at bb0[10] in '?2 diff --git a/tests/ui/fn/fn_def_coercion.rs b/tests/ui/fn/fn_def_coercion.rs index 31c8fa41de1..313be6f28cd 100644 --- a/tests/ui/fn/fn_def_coercion.rs +++ b/tests/ui/fn/fn_def_coercion.rs @@ -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 ()) { 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 }; x(a); - x(b); + x(b); //~ ERROR lifetime may not live long enough x(c); } diff --git a/tests/ui/fn/fn_def_coercion.stderr b/tests/ui/fn/fn_def_coercion.stderr index c2776887b79..ec4a1bde7fd 100644 --- a/tests/ui/fn/fn_def_coercion.stderr +++ b/tests/ui/fn/fn_def_coercion.stderr @@ -6,9 +6,9 @@ LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { | | | lifetime `'a` defined here 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: the function `foo` is invariant over the parameter `T` = help: see 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 LL | let mut x = foo::<&'a ()>; 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: the function `foo` is invariant over the parameter `T` = help: see 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 LL | let mut x = foo::<&'c ()>; 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: the function `foo` is invariant over the parameter `T` = help: see 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 ... 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: the function `foo` is invariant over the parameter `T` = help: see 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 LL | let x = match true { 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: the function `foo` is invariant over the parameter `T` = help: see 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 ... 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: the function `foo` is invariant over the parameter `T` = help: see 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` 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 ()) { | -- -- lifetime `'c` defined here | | | lifetime `'a` defined here -LL | let x = match true { -LL | true => foo::<&'c ()>, - | ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c` +... +LL | false => foo::<&'a ()>, + | ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c` | = help: consider adding the following bound: `'a: 'c` = note: requirement occurs because of a function pointer to `foo` @@ -133,20 +133,17 @@ LL | true => foo::<&'c ()>, = help: see for more information about variance 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 ()) { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here ... -LL | false => foo::<&'a ()>, - | ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a` +LL | x(b); + | ^^^^ argument requires that `'b` must outlive `'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 for more information about variance help: the following changes may resolve your lifetime errors | diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs index 66e6eb91a22..09ee9accccd 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs @@ -1,6 +1,6 @@ fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) { - //~^ ERROR lifetime may not live long enough *v = x; + //~^ ERROR lifetime may not live long enough } fn main() { } diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr index e7cab52084d..30083b5ef54 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr @@ -1,15 +1,13 @@ 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) { - | ^^^^^^^^^ - - let's call the lifetime of this reference `'1` - | | | - | | let's call the lifetime of this reference `'2` - | assignment requires that `'1` must outlive `'2` + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'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 for more information about variance help: consider introducing a named lifetime parameter | LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) { diff --git a/tests/ui/match/match-ref-mut-invariance.stderr b/tests/ui/match/match-ref-mut-invariance.stderr index 93844d34b41..b9878a19532 100644 --- a/tests/ui/match/match-ref-mut-invariance.stderr +++ b/tests/ui/match/match-ref-mut-invariance.stderr @@ -1,12 +1,12 @@ 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> { | -- lifetime `'b` defined here LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | -- lifetime `'a` defined here 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` = note: requirement occurs because of a mutable reference to `&i32` diff --git a/tests/ui/match/match-ref-mut-let-invariance.rs b/tests/ui/match/match-ref-mut-let-invariance.rs index 2c1f865b6d7..a33be09ac8b 100644 --- a/tests/ui/match/match-ref-mut-let-invariance.rs +++ b/tests/ui/match/match-ref-mut-let-invariance.rs @@ -8,8 +8,8 @@ struct S<'b>(&'b i32); impl<'b> S<'b> { fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { let ref mut x = self.0; - //~^ ERROR lifetime may not live long enough x + //~^ ERROR lifetime may not live long enough } } diff --git a/tests/ui/match/match-ref-mut-let-invariance.stderr b/tests/ui/match/match-ref-mut-let-invariance.stderr index 3c5d73bb4f7..27968239a8e 100644 --- a/tests/ui/match/match-ref-mut-let-invariance.stderr +++ b/tests/ui/match/match-ref-mut-let-invariance.stderr @@ -1,12 +1,13 @@ 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> { | -- lifetime `'b` defined here LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | -- lifetime `'a` defined here 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` = note: requirement occurs because of a mutable reference to `&i32` diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr index 1478ad1431b..2084697e7e2 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr @@ -4,9 +4,11 @@ error[E0597]: `c` does not live long enough LL | let c = 66; | - binding `c` declared here LL | let f = SomeStruct::<&'static u32>; - | -------------------------- assignment requires that `c` is borrowed for `'static` 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 | } | - `c` dropped here while still borrowed @@ -18,9 +20,11 @@ LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { LL | let c = 66; | - binding `c` declared here LL | let f = SomeStruct::<&'a u32>; - | --------------------- assignment requires that `c` is borrowed for `'a` 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 | } | - `c` dropped here while still borrowed @@ -33,9 +37,11 @@ LL | let _closure = || { LL | let c = 66; | - binding `c` declared here LL | let f = SomeStruct::<&'a u32>; - | --------------------- assignment requires that `c` is borrowed for `'a` 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 | }; | - `c` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/method-ufcs-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-1.stderr index 087e270c70f..c42ea0172cf 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-1.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-1.stderr @@ -4,10 +4,11 @@ error[E0597]: `a` does not live long enough LL | let a = 22; | - 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); - | ^^ borrowed value does not live long enough + | --^^------- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'static` LL | } | - `a` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/method-ufcs-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-2.stderr index c89bed3b1b1..287337c7d52 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-2.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-2.stderr @@ -4,10 +4,11 @@ error[E0597]: `a` does not live long enough LL | let a = 22; | - 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); - | ^^ borrowed value does not live long enough + | --^^------- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'static` LL | } | - `a` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/promoted-annotation.stderr b/tests/ui/nll/user-annotations/promoted-annotation.stderr index ca99e531870..39993475796 100644 --- a/tests/ui/nll/user-annotations/promoted-annotation.stderr +++ b/tests/ui/nll/user-annotations/promoted-annotation.stderr @@ -6,9 +6,11 @@ LL | fn foo<'a>() { LL | let x = 0; | - binding `x` declared here LL | let f = &drop::<&'a i32>; - | ---------------- assignment requires that `x` is borrowed for `'a` 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 | } | - `x` dropped here while still borrowed