From c3e0b29e79f347edf7e0ae559bfec2d3cdf353d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 Aug 2025 19:35:22 +0000 Subject: [PATCH 1/5] Point at fn bound that introduced lifetime obligation ``` error[E0597]: `c` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:19:20 | LL | fn simple<'a>(x: &'a i32) { | -- lifetime `'a` defined here ... LL | let c = async move || { println!("{}", *x); }; | - binding `c` declared here LL | outlives::<'a>(c()); | ---------------^--- | | | | | borrowed value does not live long enough | argument requires that `c` is borrowed for `'a` LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | note: requirement that `c` is borrowed for `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} | ^^ ``` When encountering a `ConstraintCategory::Predicate` in a funtion call, point at the `Span` for that `Predicate` to explain where the lifetime obligation originates from. --- .../rustc_borrowck/src/borrowck_errors.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 9 +++ ...thout-precise-captures-we-are-powerless.rs | 14 +++++ ...t-precise-captures-we-are-powerless.stderr | 57 ++++++++++++++++++- ...ation-not-general-enough-ice-133252.stderr | 6 ++ .../precise-capturing/migration-note.rs | 2 + .../precise-capturing/migration-note.stderr | 54 +++++++++++------- ...er-to-static-comparing-against-free.stderr | 6 ++ .../propagate-multiple-requirements.stderr | 6 ++ .../nll/local-outlives-static-via-hrtb.stderr | 10 ++++ ...insensitive-scopes-issue-117146.nll.stderr | 5 ++ ...sitive-scopes-issue-117146.polonius.stderr | 5 ++ .../regions-infer-proc-static-upvar.stderr | 6 ++ .../regions-pattern-typing-issue-19552.stderr | 6 ++ tests/ui/static/static-lifetime-bound.stderr | 6 ++ 15 files changed, 170 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index c9be5575da5ce..bc985cbe13353 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -426,7 +426,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { } pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> { - struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) + struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path) } pub(crate) fn cannot_return_reference_to_local( diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7e20a5133e07f..3b268f538cf2d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3031,6 +3031,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut err = self.path_does_not_live_long_enough(borrow_span, &name); + if let BorrowExplanation::MustBeValidFor { ref path, region_name, .. } = explanation { + for constraint in path { + if let ConstraintCategory::Predicate(pred) = constraint.category + && !pred.is_dummy() + { + err.span_note(pred, format!("requirement that {name} is borrowed for `{region_name}` introduced here")); + } + } + } if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { let region_name = annotation.emit(self, &mut err); diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index 19a31d1889b84..f97ec779b32cf 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -44,4 +44,18 @@ fn through_field_and_ref_move<'a>(x: &S<'a>) { outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` } +struct T; +impl T { + fn outlives<'a>(&'a self, _: impl Sized + 'a) {} +} +fn through_method<'a>(x: &'a i32) { + let c = async || { println!("{}", *x); }; //~ ERROR `x` does not live long enough + T.outlives::<'a>(c()); + T.outlives::<'a>(call_once(c)); + + let c = async move || { println!("{}", *x); }; + T.outlives::<'a>(c()); //~ ERROR `c` does not live long enough + T.outlives::<'a>(call_once(c)); +} + fn main() {} diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index b7259074bf64b..e99ff763b9a2d 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -28,6 +28,12 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed + | +note: requirement that `c` is borrowed for `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0597]: `x` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:26:13 @@ -73,6 +79,12 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed + | +note: requirement that `c` is borrowed for `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0505]: cannot move out of `c` because it is borrowed --> $DIR/without-precise-captures-we-are-powerless.rs:32:30 @@ -129,6 +141,12 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed + | +note: requirement that `c` is borrowed for `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/without-precise-captures-we-are-powerless.rs:44:5 @@ -141,7 +159,44 @@ help: add explicit lifetime `'a` to the type of `x` LL | fn through_field_and_ref_move<'a>(x: &'a S<'a>) { | ++ -error: aborting due to 10 previous errors +error[E0597]: `x` does not live long enough + --> $DIR/without-precise-captures-we-are-powerless.rs:52:13 + | +LL | fn through_method<'a>(x: &'a i32) { + | -- lifetime `'a` defined here +LL | let c = async || { println!("{}", *x); }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough +LL | T.outlives::<'a>(c()); +LL | T.outlives::<'a>(call_once(c)); + | ------------------------------ argument requires that `x` is borrowed for `'a` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/without-precise-captures-we-are-powerless.rs:57:22 + | +LL | fn through_method<'a>(x: &'a i32) { + | -- lifetime `'a` defined here +... +LL | let c = async move || { println!("{}", *x); }; + | - binding `c` declared here +LL | T.outlives::<'a>(c()); + | -----------------^--- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | T.outlives::<'a>(call_once(c)); +LL | } + | - `c` dropped here while still borrowed + | +note: requirement that `c` is borrowed for `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:49:47 + | +LL | fn outlives<'a>(&'a self, _: impl Sized + 'a) {} + | ^^ + +error: aborting due to 12 previous errors Some errors have detailed explanations: E0505, E0597, E0621. For more information about an error, try `rustc --explain E0505`. diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr index 5389226f7a7a4..393f7b1a61dfa 100644 --- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -22,6 +22,12 @@ LL | force_send(async_load(¬_static)); ... LL | } | - `not_static` dropped here while still borrowed + | +note: requirement that `not_static` is borrowed for `'1` introduced here + --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18 + | +LL | fn force_send(_: T) {} + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs index 7587e89409aaa..25b594e9b1ec7 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.rs +++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs @@ -32,6 +32,7 @@ fn needs_static() { //~| NOTE borrowed value does not live long enoug fn needs_static(_: impl Sized + 'static) {} + //~^ NOTE requirement that `x` is borrowed for `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } @@ -79,6 +80,7 @@ fn needs_static_mut() { //~| NOTE borrowed value does not live long enough fn needs_static(_: impl Sized + 'static) {} + //~^ NOTE requirement that `x` is borrowed for `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index aa0f640009158..e42a6f15c7e58 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:182:17 + --> $DIR/migration-note.rs:184:17 | LL | let x = vec![0]; | - binding `x` declared here @@ -50,6 +50,11 @@ LL | LL | } | - `x` dropped here while still borrowed | +note: requirement that `x` is borrowed for `'static` introduced here + --> $DIR/migration-note.rs:34:37 + | +LL | fn needs_static(_: impl Sized + 'static) {} + | ^^^^^^^ note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:29:13 | @@ -61,7 +66,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:48:8 + --> $DIR/migration-note.rs:49:8 | LL | let x = vec![1]; | - binding `x` declared here @@ -76,7 +81,7 @@ LL | } | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:43:13 + --> $DIR/migration-note.rs:44:13 | LL | let a = display_len(&x); | ^^^^^^^^^^^^^^^ @@ -90,7 +95,7 @@ LL | let a = display_len(&x.clone()); | ++++++++ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/migration-note.rs:66:5 + --> $DIR/migration-note.rs:67:5 | LL | let a = display_len_mut(&mut x); | ------ first mutable borrow occurs here @@ -102,7 +107,7 @@ LL | println!("{a}"); | - first borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:63:13 + --> $DIR/migration-note.rs:64:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +117,7 @@ LL | fn display_len_mut(x: &mut Vec) -> impl Display + use { | ++++++++ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:76:29 + --> $DIR/migration-note.rs:77:29 | LL | let mut x = vec![1]; | ----- binding `x` declared here @@ -126,8 +131,13 @@ LL | LL | } | - `x` dropped here while still borrowed | +note: requirement that `x` is borrowed for `'static` introduced here + --> $DIR/migration-note.rs:82:37 + | +LL | fn needs_static(_: impl Sized + 'static) {} + | ^^^^^^^ note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:76:13 + --> $DIR/migration-note.rs:77:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +147,7 @@ LL | fn display_len_mut(x: &mut Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:95:8 + --> $DIR/migration-note.rs:97:8 | LL | let mut x = vec![1]; | ----- binding `x` declared here @@ -152,7 +162,7 @@ LL | } | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:90:13 + --> $DIR/migration-note.rs:92:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +176,7 @@ LL | let a = display_len_mut(&mut x.clone()); | ++++++++ error[E0506]: cannot assign to `s.f` because it is borrowed - --> $DIR/migration-note.rs:115:5 + --> $DIR/migration-note.rs:117:5 | LL | let a = display_field(&s.f); | ---- `s.f` is borrowed here @@ -178,7 +188,7 @@ LL | println!("{a}"); | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:112:13 + --> $DIR/migration-note.rs:114:13 | LL | let a = display_field(&s.f); | ^^^^^^^^^^^^^^^^^^^ @@ -188,7 +198,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0506]: cannot assign to `s.f` because it is borrowed - --> $DIR/migration-note.rs:131:5 + --> $DIR/migration-note.rs:133:5 | LL | let a = display_field(&mut s.f); | -------- `s.f` is borrowed here @@ -200,7 +210,7 @@ LL | println!("{a}"); | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:128:13 + --> $DIR/migration-note.rs:130:13 | LL | let a = display_field(&mut s.f); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +220,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0503]: cannot use `s.f` because it was mutably borrowed - --> $DIR/migration-note.rs:143:5 + --> $DIR/migration-note.rs:145:5 | LL | let a = display_field(&mut s.f); | -------- `s.f` is borrowed here @@ -222,7 +232,7 @@ LL | println!("{a}"); | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:140:13 + --> $DIR/migration-note.rs:142:13 | LL | let a = display_field(&mut s.f); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +242,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0597]: `z.f` does not live long enough - --> $DIR/migration-note.rs:159:25 + --> $DIR/migration-note.rs:161:25 | LL | let z = Z { f: vec![1] }; | - binding `z` declared here @@ -248,7 +258,7 @@ LL | } | = note: values in a scope are dropped in the opposite order they are defined note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:159:13 + --> $DIR/migration-note.rs:161:13 | LL | x = display_len(&z.f); | ^^^^^^^^^^^^^^^^^ @@ -258,7 +268,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0716]: temporary value dropped while borrowed - --> $DIR/migration-note.rs:170:40 + --> $DIR/migration-note.rs:172:40 | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^ - - borrow later used here @@ -268,7 +278,7 @@ LL | let x = { let x = display_len(&mut vec![0]); x }; | = note: consider using a `let` binding to create a longer lived value note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:170:23 + --> $DIR/migration-note.rs:172:23 | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +289,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:198:10 + --> $DIR/migration-note.rs:200:10 | LL | let x = String::new(); | - binding `x` declared here @@ -294,12 +304,12 @@ LL | } | - borrow might be used here, when `y` is dropped and runs the destructor for type `impl Sized` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:195:13 + --> $DIR/migration-note.rs:197:13 | LL | let y = capture_apit(&x); | ^^^^^^^^^^^^^^^^ note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable - --> $DIR/migration-note.rs:189:21 + --> $DIR/migration-note.rs:191:21 | LL | fn capture_apit(x: &impl Sized) -> impl Sized {} | ^^^^^^^^^^ diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index e13653f342342..136da57daec1b 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -69,6 +69,12 @@ LL | cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> LL | }) LL | } | - `a` dropped here while still borrowed + | +note: requirement that `a` is borrowed for `'static` introduced here + --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:13:8 + | +LL | F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr index 15f48d88c379b..8e18f546ebd4d 100644 --- a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr +++ b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr @@ -13,6 +13,12 @@ LL | z = &local_arr; ... LL | } | - `local_arr` dropped here while still borrowed + | +note: requirement that `local_arr` is borrowed for `'static` introduced here + --> $DIR/propagate-multiple-requirements.rs:4:21 + | +LL | fn once U>(f: F, s: S, t: T) -> U { + | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/nll/local-outlives-static-via-hrtb.stderr b/tests/ui/nll/local-outlives-static-via-hrtb.stderr index a98f11ce51363..cc01a3cfc0b90 100644 --- a/tests/ui/nll/local-outlives-static-via-hrtb.stderr +++ b/tests/ui/nll/local-outlives-static-via-hrtb.stderr @@ -12,6 +12,11 @@ LL | assert_static_via_hrtb_with_assoc_type(&&local); LL | } | - `local` dropped here while still borrowed | +note: requirement that `local` is borrowed for `'static` introduced here + --> $DIR/local-outlives-static-via-hrtb.rs:15:53 + | +LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} + | ^^^^^^^^^^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/local-outlives-static-via-hrtb.rs:15:42 | @@ -32,6 +37,11 @@ LL | assert_static_via_hrtb_with_assoc_type(&&local); LL | } | - `local` dropped here while still borrowed | +note: requirement that `local` is borrowed for `'static` introduced here + --> $DIR/local-outlives-static-via-hrtb.rs:19:30 + | +LL | for<'a> &'a T: Reference, + | ^^^^^^^^^^^^^^^^^^^^^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/local-outlives-static-via-hrtb.rs:19:5 | diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr index 6e47b8e59f5c6..56ad78ba4b424 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr @@ -13,6 +13,11 @@ LL | let b = |_| &a; LL | } | - `a` dropped here while still borrowed | +note: requirement that `a` is borrowed for `'static` introduced here + --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 + | +LL | fn bad &()>(_: F) {} + | ^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/location-insensitive-scopes-issue-117146.rs:20:11 | diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr index 6e47b8e59f5c6..56ad78ba4b424 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr @@ -13,6 +13,11 @@ LL | let b = |_| &a; LL | } | - `a` dropped here while still borrowed | +note: requirement that `a` is borrowed for `'static` introduced here + --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 + | +LL | fn bad &()>(_: F) {} + | ^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/location-insensitive-scopes-issue-117146.rs:20:11 | diff --git a/tests/ui/regions/regions-infer-proc-static-upvar.stderr b/tests/ui/regions/regions-infer-proc-static-upvar.stderr index 919fcffdc531e..1a76b5f00f943 100644 --- a/tests/ui/regions/regions-infer-proc-static-upvar.stderr +++ b/tests/ui/regions/regions-infer-proc-static-upvar.stderr @@ -11,6 +11,12 @@ LL | | }); | |______- argument requires that `x` is borrowed for `'static` LL | } | - `x` dropped here while still borrowed + | +note: requirement that `x` is borrowed for `'static` introduced here + --> $DIR/regions-infer-proc-static-upvar.rs:4:19 + | +LL | fn foo(_p: F) { } + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr index 1d3d5e831c39c..2c8ce20f09e46 100644 --- a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr +++ b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr @@ -10,6 +10,12 @@ LL | [ word ] => { assert_static(word); } LL | } LL | } | - `line` dropped here while still borrowed + | +note: requirement that `line` is borrowed for `'static` introduced here + --> $DIR/regions-pattern-typing-issue-19552.rs:1:21 + | +LL | fn assert_static(_t: T) {} + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr index 8b0d3a0bf4cf4..e530e4669d7f6 100644 --- a/tests/ui/static/static-lifetime-bound.stderr +++ b/tests/ui/static/static-lifetime-bound.stderr @@ -10,6 +10,12 @@ LL | f(&x); | argument requires that `x` is borrowed for `'static` LL | } | - `x` dropped here while still borrowed + | +note: requirement that `x` is borrowed for `'static` introduced here + --> $DIR/static-lifetime-bound.rs:1:10 + | +LL | fn f<'a: 'static>(_: &'a i32) {} + | ^^^^^^^ error: aborting due to 1 previous error From 7a0319f01d08e541c8e16febaa68c5fa8b66b586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 Aug 2025 20:14:01 +0000 Subject: [PATCH 2/5] Point at lifetime requirement origin in more cases --- .../rustc_borrowck/src/borrowck_errors.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 17 +--------------- .../src/diagnostics/explain_borrow.rs | 13 ++++++++++++ ...t-precise-captures-we-are-powerless.stderr | 14 +++++++++---- .../borrowck/fn-item-check-type-params.stderr | 12 +++++++++++ ...ation-not-general-enough-ice-133252.stderr | 2 +- tests/ui/borrowck/issue-17545.stderr | 3 +++ .../bugs/hrtb-implied-1.stderr | 5 +++++ .../precise-capturing/migration-note.rs | 4 ++-- .../precise-capturing/migration-note.stderr | 4 ++-- ...er-to-static-comparing-against-free.stderr | 2 +- .../propagate-multiple-requirements.stderr | 2 +- .../nll/local-outlives-static-via-hrtb.stderr | 20 +++++++++---------- ...insensitive-scopes-issue-117146.nll.stderr | 10 +++++----- ...sitive-scopes-issue-117146.polonius.stderr | 10 +++++----- .../regions-infer-proc-static-upvar.stderr | 2 +- .../regions-pattern-typing-issue-19552.stderr | 2 +- tests/ui/static/static-lifetime-bound.stderr | 2 +- tests/ui/static/static-region-bound.stderr | 6 ++++++ .../wf-in-where-clause-static.current.stderr | 6 ++++++ .../wf/wf-in-where-clause-static.next.stderr | 6 ++++++ 21 files changed, 93 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index bc985cbe13353..7c9011505d64c 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -480,7 +480,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { } pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> { - struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) + struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed") } } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3b268f538cf2d..efb622e2155ca 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2992,6 +2992,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.buffer_error(err); } + #[tracing::instrument(level = "debug", skip(self, explanation))] fn report_local_value_does_not_live_long_enough( &self, location: Location, @@ -3001,13 +3002,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, ) -> Diag<'infcx> { - debug!( - "report_local_value_does_not_live_long_enough(\ - {:?}, {:?}, {:?}, {:?}, {:?}\ - )", - location, name, borrow, drop_span, borrow_spans - ); - let borrow_span = borrow_spans.var_or_use_path_span(); if let BorrowExplanation::MustBeValidFor { category, @@ -3031,15 +3025,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut err = self.path_does_not_live_long_enough(borrow_span, &name); - if let BorrowExplanation::MustBeValidFor { ref path, region_name, .. } = explanation { - for constraint in path { - if let ConstraintCategory::Predicate(pred) = constraint.category - && !pred.is_dummy() - { - err.span_note(pred, format!("requirement that {name} is borrowed for `{region_name}` introduced here")); - } - } - } if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { let region_name = annotation.emit(self, &mut err); diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 7ca07bb9b4348..a0ea8b0855699 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -416,6 +416,19 @@ impl<'tcx> BorrowExplanation<'tcx> { { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } + + for constraint in path { + if let ConstraintCategory::Predicate(pred) = constraint.category + && !pred.is_dummy() + { + err.span_note( + pred, + format!("requirement for `{region_name}` introduced here"), + ); + break; + } + } + self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); } _ => {} diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index e99ff763b9a2d..e0776c81dff3d 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -29,7 +29,7 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement that `c` is borrowed for `'a` introduced here +note: requirement for `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -80,7 +80,7 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement that `c` is borrowed for `'a` introduced here +note: requirement for `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -101,6 +101,12 @@ LL | outlives::<'a>(c()); | argument requires that `c` is borrowed for `'a` LL | outlives::<'a>(call_once(c)); | ^ move out of `c` occurs here + | +note: requirement for `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0597]: `x` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:36:13 @@ -142,7 +148,7 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement that `c` is borrowed for `'a` introduced here +note: requirement for `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -190,7 +196,7 @@ LL | T.outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement that `c` is borrowed for `'a` introduced here +note: requirement for `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:49:47 | LL | fn outlives<'a>(&'a self, _: impl Sized + 'a) {} diff --git a/tests/ui/borrowck/fn-item-check-type-params.stderr b/tests/ui/borrowck/fn-item-check-type-params.stderr index aafb7e66ef55f..8da0201134b03 100644 --- a/tests/ui/borrowck/fn-item-check-type-params.stderr +++ b/tests/ui/borrowck/fn-item-check-type-params.stderr @@ -27,6 +27,12 @@ LL | want(&String::new(), extend_lt); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement for `'static` introduced here + --> $DIR/fn-item-check-type-params.rs:47:33 + | +LL | fn want(_: I, _: impl Fn(I) -> O) {} + | ^^^^^^^^^^ error[E0716]: temporary value dropped while borrowed --> $DIR/fn-item-check-type-params.rs:54:26 @@ -36,6 +42,12 @@ LL | let val = extend_lt(&String::from("blah blah blah")); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement for `'static` introduced here + --> $DIR/fn-item-check-type-params.rs:22:21 + | +LL | (T, Option): Displayable, + | ^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr index 393f7b1a61dfa..dab969586efd8 100644 --- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -23,7 +23,7 @@ LL | force_send(async_load(¬_static)); LL | } | - `not_static` dropped here while still borrowed | -note: requirement that `not_static` is borrowed for `'1` introduced here +note: requirement for `'1` introduced here --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18 | LL | fn force_send(_: T) {} diff --git a/tests/ui/borrowck/issue-17545.stderr b/tests/ui/borrowck/issue-17545.stderr index 45e977e39477e..dc0a84b0ab42a 100644 --- a/tests/ui/borrowck/issue-17545.stderr +++ b/tests/ui/borrowck/issue-17545.stderr @@ -10,6 +10,9 @@ LL | | )); | | -- temporary value is freed at the end of this statement | |______| | argument requires that borrow lasts for `'a` + | +note: requirement for `'a` introduced here + --> $SRC_DIR/core/src/ops/function.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr index 8bb72833e301c..72f9a477dafcc 100644 --- a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr +++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr @@ -14,6 +14,11 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | for<'a> I::Item<'a>: Debug, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: requirement for `'static` introduced here + --> $DIR/hrtb-implied-1.rs:26:26 + | +LL | for<'a> I::Item<'a>: Debug, + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs index 25b594e9b1ec7..211def3332002 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.rs +++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs @@ -32,7 +32,7 @@ fn needs_static() { //~| NOTE borrowed value does not live long enoug fn needs_static(_: impl Sized + 'static) {} - //~^ NOTE requirement that `x` is borrowed for `'static` introduced here + //~^ NOTE requirement for `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } @@ -80,7 +80,7 @@ fn needs_static_mut() { //~| NOTE borrowed value does not live long enough fn needs_static(_: impl Sized + 'static) {} - //~^ NOTE requirement that `x` is borrowed for `'static` introduced here + //~^ NOTE requirement for `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index e42a6f15c7e58..c06b14a41139b 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -50,7 +50,7 @@ LL | LL | } | - `x` dropped here while still borrowed | -note: requirement that `x` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/migration-note.rs:34:37 | LL | fn needs_static(_: impl Sized + 'static) {} @@ -131,7 +131,7 @@ LL | LL | } | - `x` dropped here while still borrowed | -note: requirement that `x` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/migration-note.rs:82:37 | LL | fn needs_static(_: impl Sized + 'static) {} diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 136da57daec1b..eb110e868aa58 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -70,7 +70,7 @@ LL | }) LL | } | - `a` dropped here while still borrowed | -note: requirement that `a` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:13:8 | LL | F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>), diff --git a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr index 8e18f546ebd4d..51e4d77c91a1b 100644 --- a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr +++ b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr @@ -14,7 +14,7 @@ LL | z = &local_arr; LL | } | - `local_arr` dropped here while still borrowed | -note: requirement that `local_arr` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/propagate-multiple-requirements.rs:4:21 | LL | fn once U>(f: F, s: S, t: T) -> U { diff --git a/tests/ui/nll/local-outlives-static-via-hrtb.stderr b/tests/ui/nll/local-outlives-static-via-hrtb.stderr index cc01a3cfc0b90..ff2be3a2b28ec 100644 --- a/tests/ui/nll/local-outlives-static-via-hrtb.stderr +++ b/tests/ui/nll/local-outlives-static-via-hrtb.stderr @@ -12,16 +12,16 @@ LL | assert_static_via_hrtb_with_assoc_type(&&local); LL | } | - `local` dropped here while still borrowed | -note: requirement that `local` is borrowed for `'static` introduced here - --> $DIR/local-outlives-static-via-hrtb.rs:15:53 - | -LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} - | ^^^^^^^^^^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/local-outlives-static-via-hrtb.rs:15:42 | LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^ +note: requirement for `'static` introduced here + --> $DIR/local-outlives-static-via-hrtb.rs:15:53 + | +LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} + | ^^^^^^^^^^^^ error[E0597]: `local` does not live long enough --> $DIR/local-outlives-static-via-hrtb.rs:25:45 @@ -37,16 +37,16 @@ LL | assert_static_via_hrtb_with_assoc_type(&&local); LL | } | - `local` dropped here while still borrowed | -note: requirement that `local` is borrowed for `'static` introduced here - --> $DIR/local-outlives-static-via-hrtb.rs:19:30 - | -LL | for<'a> &'a T: Reference, - | ^^^^^^^^^^^^^^^^^^^^^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/local-outlives-static-via-hrtb.rs:19:5 | LL | for<'a> &'a T: Reference, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: requirement for `'static` introduced here + --> $DIR/local-outlives-static-via-hrtb.rs:19:30 + | +LL | for<'a> &'a T: Reference, + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr index 56ad78ba4b424..fdc3fc059c534 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr @@ -13,16 +13,16 @@ LL | let b = |_| &a; LL | } | - `a` dropped here while still borrowed | -note: requirement that `a` is borrowed for `'static` introduced here - --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 - | -LL | fn bad &()>(_: F) {} - | ^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/location-insensitive-scopes-issue-117146.rs:20:11 | LL | fn bad &()>(_: F) {} | ^^^^^^^^^^^^^^ +note: requirement for `'static` introduced here + --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 + | +LL | fn bad &()>(_: F) {} + | ^^^ error: implementation of `Fn` is not general enough --> $DIR/location-insensitive-scopes-issue-117146.rs:13:5 diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr index 56ad78ba4b424..fdc3fc059c534 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr @@ -13,16 +13,16 @@ LL | let b = |_| &a; LL | } | - `a` dropped here while still borrowed | -note: requirement that `a` is borrowed for `'static` introduced here - --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 - | -LL | fn bad &()>(_: F) {} - | ^^^ note: due to a current limitation of the type system, this implies a `'static` lifetime --> $DIR/location-insensitive-scopes-issue-117146.rs:20:11 | LL | fn bad &()>(_: F) {} | ^^^^^^^^^^^^^^ +note: requirement for `'static` introduced here + --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 + | +LL | fn bad &()>(_: F) {} + | ^^^ error: implementation of `Fn` is not general enough --> $DIR/location-insensitive-scopes-issue-117146.rs:13:5 diff --git a/tests/ui/regions/regions-infer-proc-static-upvar.stderr b/tests/ui/regions/regions-infer-proc-static-upvar.stderr index 1a76b5f00f943..ff833de0ad012 100644 --- a/tests/ui/regions/regions-infer-proc-static-upvar.stderr +++ b/tests/ui/regions/regions-infer-proc-static-upvar.stderr @@ -12,7 +12,7 @@ LL | | }); LL | } | - `x` dropped here while still borrowed | -note: requirement that `x` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/regions-infer-proc-static-upvar.rs:4:19 | LL | fn foo(_p: F) { } diff --git a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr index 2c8ce20f09e46..76cd18dfa1329 100644 --- a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr +++ b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr @@ -11,7 +11,7 @@ LL | } LL | } | - `line` dropped here while still borrowed | -note: requirement that `line` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/regions-pattern-typing-issue-19552.rs:1:21 | LL | fn assert_static(_t: T) {} diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr index e530e4669d7f6..354a1327beead 100644 --- a/tests/ui/static/static-lifetime-bound.stderr +++ b/tests/ui/static/static-lifetime-bound.stderr @@ -11,7 +11,7 @@ LL | f(&x); LL | } | - `x` dropped here while still borrowed | -note: requirement that `x` is borrowed for `'static` introduced here +note: requirement for `'static` introduced here --> $DIR/static-lifetime-bound.rs:1:10 | LL | fn f<'a: 'static>(_: &'a i32) {} diff --git a/tests/ui/static/static-region-bound.stderr b/tests/ui/static/static-region-bound.stderr index a47c94571022d..e7747216a57b1 100644 --- a/tests/ui/static/static-region-bound.stderr +++ b/tests/ui/static/static-region-bound.stderr @@ -7,6 +7,12 @@ LL | f(x); | ---- argument requires that borrow lasts for `'static` LL | } | - temporary value is freed at the end of this statement + | +note: requirement for `'static` introduced here + --> $DIR/static-region-bound.rs:3:8 + | +LL | fn f(_: T) {} + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/wf/wf-in-where-clause-static.current.stderr b/tests/ui/wf/wf-in-where-clause-static.current.stderr index d0bb89884c68a..53cc6093f540b 100644 --- a/tests/ui/wf/wf-in-where-clause-static.current.stderr +++ b/tests/ui/wf/wf-in-where-clause-static.current.stderr @@ -6,6 +6,12 @@ LL | let s = foo(&String::from("blah blah blah")); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement for `'static` introduced here + --> $DIR/wf-in-where-clause-static.rs:12:17 + | +LL | &'static S: Static, + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/wf/wf-in-where-clause-static.next.stderr b/tests/ui/wf/wf-in-where-clause-static.next.stderr index d0bb89884c68a..53cc6093f540b 100644 --- a/tests/ui/wf/wf-in-where-clause-static.next.stderr +++ b/tests/ui/wf/wf-in-where-clause-static.next.stderr @@ -6,6 +6,12 @@ LL | let s = foo(&String::from("blah blah blah")); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement for `'static` introduced here + --> $DIR/wf-in-where-clause-static.rs:12:17 + | +LL | &'static S: Static, + | ^^^^^^ error: aborting due to 1 previous error From 4973903cd204dd2cd36e15267de72ed6d954e3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 31 Aug 2025 20:42:01 +0000 Subject: [PATCH 3/5] reword note --- .../rustc_borrowck/src/diagnostics/explain_borrow.rs | 2 +- .../without-precise-captures-we-are-powerless.stderr | 10 +++++----- tests/ui/borrowck/fn-item-check-type-params.stderr | 4 ++-- ...implementation-not-general-enough-ice-133252.stderr | 2 +- tests/ui/borrowck/issue-17545.stderr | 2 +- .../bugs/hrtb-implied-1.stderr | 2 +- .../ui/impl-trait/precise-capturing/migration-note.rs | 4 ++-- .../impl-trait/precise-capturing/migration-note.stderr | 4 ++-- ...ted-shorter-to-static-comparing-against-free.stderr | 2 +- .../propagate-multiple-requirements.stderr | 2 +- tests/ui/nll/local-outlives-static-via-hrtb.stderr | 4 ++-- ...location-insensitive-scopes-issue-117146.nll.stderr | 2 +- ...ion-insensitive-scopes-issue-117146.polonius.stderr | 2 +- .../ui/regions/regions-infer-proc-static-upvar.stderr | 2 +- .../regions/regions-pattern-typing-issue-19552.stderr | 2 +- tests/ui/static/static-lifetime-bound.stderr | 2 +- tests/ui/static/static-region-bound.stderr | 2 +- tests/ui/wf/wf-in-where-clause-static.current.stderr | 2 +- tests/ui/wf/wf-in-where-clause-static.next.stderr | 2 +- 19 files changed, 27 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index a0ea8b0855699..66c43a07c80ce 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -423,7 +423,7 @@ impl<'tcx> BorrowExplanation<'tcx> { { err.span_note( pred, - format!("requirement for `{region_name}` introduced here"), + format!("requirement that the value outlives `{region_name}` introduced here"), ); break; } diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index e0776c81dff3d..4aae9807dd2e4 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -29,7 +29,7 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement for `'a` introduced here +note: requirement that the value outlives `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -80,7 +80,7 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement for `'a` introduced here +note: requirement that the value outlives `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -102,7 +102,7 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); | ^ move out of `c` occurs here | -note: requirement for `'a` introduced here +note: requirement that the value outlives `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -148,7 +148,7 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement for `'a` introduced here +note: requirement that the value outlives `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} @@ -196,7 +196,7 @@ LL | T.outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | -note: requirement for `'a` introduced here +note: requirement that the value outlives `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:49:47 | LL | fn outlives<'a>(&'a self, _: impl Sized + 'a) {} diff --git a/tests/ui/borrowck/fn-item-check-type-params.stderr b/tests/ui/borrowck/fn-item-check-type-params.stderr index 8da0201134b03..7a0a7752a14b2 100644 --- a/tests/ui/borrowck/fn-item-check-type-params.stderr +++ b/tests/ui/borrowck/fn-item-check-type-params.stderr @@ -28,7 +28,7 @@ LL | want(&String::new(), extend_lt); | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/fn-item-check-type-params.rs:47:33 | LL | fn want(_: I, _: impl Fn(I) -> O) {} @@ -43,7 +43,7 @@ LL | let val = extend_lt(&String::from("blah blah blah")); | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/fn-item-check-type-params.rs:22:21 | LL | (T, Option): Displayable, diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr index dab969586efd8..7b840d54ed038 100644 --- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -23,7 +23,7 @@ LL | force_send(async_load(¬_static)); LL | } | - `not_static` dropped here while still borrowed | -note: requirement for `'1` introduced here +note: requirement that the value outlives `'1` introduced here --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18 | LL | fn force_send(_: T) {} diff --git a/tests/ui/borrowck/issue-17545.stderr b/tests/ui/borrowck/issue-17545.stderr index dc0a84b0ab42a..63fd57cd2336f 100644 --- a/tests/ui/borrowck/issue-17545.stderr +++ b/tests/ui/borrowck/issue-17545.stderr @@ -11,7 +11,7 @@ LL | | )); | |______| | argument requires that borrow lasts for `'a` | -note: requirement for `'a` introduced here +note: requirement that the value outlives `'a` introduced here --> $SRC_DIR/core/src/ops/function.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr index 72f9a477dafcc..77a637c470cc2 100644 --- a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr +++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr @@ -14,7 +14,7 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | for<'a> I::Item<'a>: Debug, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/hrtb-implied-1.rs:26:26 | LL | for<'a> I::Item<'a>: Debug, diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs index 211def3332002..412d8af98845e 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.rs +++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs @@ -32,7 +32,7 @@ fn needs_static() { //~| NOTE borrowed value does not live long enoug fn needs_static(_: impl Sized + 'static) {} - //~^ NOTE requirement for `'static` introduced here + //~^ NOTE requirement that the value outlives `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } @@ -80,7 +80,7 @@ fn needs_static_mut() { //~| NOTE borrowed value does not live long enough fn needs_static(_: impl Sized + 'static) {} - //~^ NOTE requirement for `'static` introduced here + //~^ NOTE requirement that the value outlives `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index c06b14a41139b..880e7878477af 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -50,7 +50,7 @@ LL | LL | } | - `x` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/migration-note.rs:34:37 | LL | fn needs_static(_: impl Sized + 'static) {} @@ -131,7 +131,7 @@ LL | LL | } | - `x` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/migration-note.rs:82:37 | LL | fn needs_static(_: impl Sized + 'static) {} diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index eb110e868aa58..af07745a00af4 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -70,7 +70,7 @@ LL | }) LL | } | - `a` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:13:8 | LL | F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>), diff --git a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr index 51e4d77c91a1b..4136ac418deb4 100644 --- a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr +++ b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr @@ -14,7 +14,7 @@ LL | z = &local_arr; LL | } | - `local_arr` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/propagate-multiple-requirements.rs:4:21 | LL | fn once U>(f: F, s: S, t: T) -> U { diff --git a/tests/ui/nll/local-outlives-static-via-hrtb.stderr b/tests/ui/nll/local-outlives-static-via-hrtb.stderr index ff2be3a2b28ec..263d271b6b3d0 100644 --- a/tests/ui/nll/local-outlives-static-via-hrtb.stderr +++ b/tests/ui/nll/local-outlives-static-via-hrtb.stderr @@ -17,7 +17,7 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^ -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/local-outlives-static-via-hrtb.rs:15:53 | LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} @@ -42,7 +42,7 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | for<'a> &'a T: Reference, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/local-outlives-static-via-hrtb.rs:19:30 | LL | for<'a> &'a T: Reference, diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr index fdc3fc059c534..804b3f00a2642 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr @@ -18,7 +18,7 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | fn bad &()>(_: F) {} | ^^^^^^^^^^^^^^ -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 | LL | fn bad &()>(_: F) {} diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr index fdc3fc059c534..804b3f00a2642 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr @@ -18,7 +18,7 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | fn bad &()>(_: F) {} | ^^^^^^^^^^^^^^ -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 | LL | fn bad &()>(_: F) {} diff --git a/tests/ui/regions/regions-infer-proc-static-upvar.stderr b/tests/ui/regions/regions-infer-proc-static-upvar.stderr index ff833de0ad012..158d74ed06d94 100644 --- a/tests/ui/regions/regions-infer-proc-static-upvar.stderr +++ b/tests/ui/regions/regions-infer-proc-static-upvar.stderr @@ -12,7 +12,7 @@ LL | | }); LL | } | - `x` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/regions-infer-proc-static-upvar.rs:4:19 | LL | fn foo(_p: F) { } diff --git a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr index 76cd18dfa1329..a8fd827bc6951 100644 --- a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr +++ b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr @@ -11,7 +11,7 @@ LL | } LL | } | - `line` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/regions-pattern-typing-issue-19552.rs:1:21 | LL | fn assert_static(_t: T) {} diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr index 354a1327beead..51be79be5db8a 100644 --- a/tests/ui/static/static-lifetime-bound.stderr +++ b/tests/ui/static/static-lifetime-bound.stderr @@ -11,7 +11,7 @@ LL | f(&x); LL | } | - `x` dropped here while still borrowed | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/static-lifetime-bound.rs:1:10 | LL | fn f<'a: 'static>(_: &'a i32) {} diff --git a/tests/ui/static/static-region-bound.stderr b/tests/ui/static/static-region-bound.stderr index e7747216a57b1..8472738daa49c 100644 --- a/tests/ui/static/static-region-bound.stderr +++ b/tests/ui/static/static-region-bound.stderr @@ -8,7 +8,7 @@ LL | f(x); LL | } | - temporary value is freed at the end of this statement | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/static-region-bound.rs:3:8 | LL | fn f(_: T) {} diff --git a/tests/ui/wf/wf-in-where-clause-static.current.stderr b/tests/ui/wf/wf-in-where-clause-static.current.stderr index 53cc6093f540b..788fe2c3faa07 100644 --- a/tests/ui/wf/wf-in-where-clause-static.current.stderr +++ b/tests/ui/wf/wf-in-where-clause-static.current.stderr @@ -7,7 +7,7 @@ LL | let s = foo(&String::from("blah blah blah")); | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/wf-in-where-clause-static.rs:12:17 | LL | &'static S: Static, diff --git a/tests/ui/wf/wf-in-where-clause-static.next.stderr b/tests/ui/wf/wf-in-where-clause-static.next.stderr index 53cc6093f540b..788fe2c3faa07 100644 --- a/tests/ui/wf/wf-in-where-clause-static.next.stderr +++ b/tests/ui/wf/wf-in-where-clause-static.next.stderr @@ -7,7 +7,7 @@ LL | let s = foo(&String::from("blah blah blah")); | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` | -note: requirement for `'static` introduced here +note: requirement that the value outlives `'static` introduced here --> $DIR/wf-in-where-clause-static.rs:12:17 | LL | &'static S: Static, From 58f5260b960004090bfa9e7ef5068d6554ac9f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Sep 2025 20:58:44 +0000 Subject: [PATCH 4/5] Address review comment --- .../src/diagnostics/explain_borrow.rs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 66c43a07c80ce..67e33b37416c4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -417,16 +417,20 @@ impl<'tcx> BorrowExplanation<'tcx> { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } - for constraint in path { - if let ConstraintCategory::Predicate(pred) = constraint.category - && !pred.is_dummy() - { - err.span_note( - pred, - format!("requirement that the value outlives `{region_name}` introduced here"), - ); - break; - } + if let Some(pred) = path + .iter() + .filter_map(|constraint| match constraint.category { + ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred), + _ => None, + }) + .next() + { + err.span_note( + pred, + format!( + "requirement that the value outlives `{region_name}` introduced here" + ), + ); } self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); From c5313fed76a99942edb4c7f94607fa3d2d6da21c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Sep 2025 21:13:53 +0000 Subject: [PATCH 5/5] Point at multiple outlives requirements instead of just the first one ``` error[E0716]: temporary value dropped while borrowed --> $DIR/multiple-sources-for-outlives-requirement.rs:5:38 | LL | fn foo<'b>() { | -- lifetime `'b` defined here LL | outlives_indir::<'_, 'b, _>(&mut 1u32); | ---------------------------------^^^^-- temporary value is freed at the end of this statement | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'b` | note: requirements that the value outlives `'b` introduced here --> $DIR/multiple-sources-for-outlives-requirement.rs:1:23 | LL | fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {} | ^^ ^^ ``` --- .../src/diagnostics/explain_borrow.rs | 13 +++++++----- ...ltiple-sources-for-outlives-requirement.rs | 11 ++++++++++ ...le-sources-for-outlives-requirement.stderr | 20 +++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 tests/ui/regions/multiple-sources-for-outlives-requirement.rs create mode 100644 tests/ui/regions/multiple-sources-for-outlives-requirement.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 67e33b37416c4..638d89f5bcbdb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -417,18 +417,21 @@ impl<'tcx> BorrowExplanation<'tcx> { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } - if let Some(pred) = path + let mut preds = path .iter() .filter_map(|constraint| match constraint.category { ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred), _ => None, }) - .next() - { + .collect::>(); + preds.sort(); + preds.dedup(); + if !preds.is_empty() { + let s = if preds.len() == 1 { "" } else { "s" }; err.span_note( - pred, + preds, format!( - "requirement that the value outlives `{region_name}` introduced here" + "requirement{s} that the value outlives `{region_name}` introduced here" ), ); } diff --git a/tests/ui/regions/multiple-sources-for-outlives-requirement.rs b/tests/ui/regions/multiple-sources-for-outlives-requirement.rs new file mode 100644 index 0000000000000..720cd1cf6eecb --- /dev/null +++ b/tests/ui/regions/multiple-sources-for-outlives-requirement.rs @@ -0,0 +1,11 @@ +fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {} +//~^ NOTE: requirements that the value outlives `'b` introduced here + +fn foo<'b>() { //~ NOTE: lifetime `'b` defined here + outlives_indir::<'_, 'b, _>(&mut 1u32); //~ ERROR: temporary value dropped while borrowed + //~^ NOTE: argument requires that borrow lasts for `'b` + //~| NOTE: creates a temporary value which is freed while still in use + //~| NOTE: temporary value is freed at the end of this statement +} + +fn main() {} diff --git a/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr b/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr new file mode 100644 index 0000000000000..4cdaf950e155c --- /dev/null +++ b/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr @@ -0,0 +1,20 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/multiple-sources-for-outlives-requirement.rs:5:38 + | +LL | fn foo<'b>() { + | -- lifetime `'b` defined here +LL | outlives_indir::<'_, 'b, _>(&mut 1u32); + | ---------------------------------^^^^-- temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | argument requires that borrow lasts for `'b` + | +note: requirements that the value outlives `'b` introduced here + --> $DIR/multiple-sources-for-outlives-requirement.rs:1:23 + | +LL | fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {} + | ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0716`.