Repository navigation
Account for trait object with implicit 'static lifetime in field type being returned - #164776
Conversation
|
r? @oli-obk rustbot has assigned @oli-obk. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| let (these, s, introduce) = if v.0.len() == 1 { | ||
| ("this", "", "introduces") | ||
| } else { | ||
| ("these", "s", "introduce") |
There was a problem hiding this comment.
There's no tests for the plural version at all, and I'm not sure it's better to pluralize here than to have one span per dyn trait
There was a problem hiding this comment.
There's one span per dyn Trait, but what you propose would cause multiple notes. I'm already being redundant by having both the help and the suggestion point at pretty much the same place (and am considering just leaving the suggestion), wouldn't want to make this even longer output.
It now looks like this:
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:126:25
|
LL | pub fn new(string: &str) -> Self {
| - let's call the lifetime of this reference `'1`
LL | Thing {
LL | chars: (Box::new(string.chars()), Box::new(string.chars())),
| ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
note: these `dyn Trait`s introduce an implicit `'static` obligation
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:120:21
|
LL | pub struct Thing {
LL | chars: (Box<dyn Iterator<Item = char>>, Box<dyn Iterator<Item = char>>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime
|
LL ~ pub struct Thing<'a> {
LL ~ chars: (Box<dyn Iterator<Item = char> + 'a>, Box<dyn Iterator<Item = char> + 'a>),
|
I wonder if I should change it to be
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:126:25
|
LL | pub fn new(string: &str) -> Self {
| - let's call the lifetime of this reference `'1`
LL | Thing {
LL | chars: (Box::new(string.chars()), Box::new(string.chars())),
| ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
note: `dyn Trait`s in the type definition introduce an implicit `'static` obligation, consider introducing an explicit lifetime
|
LL ~ pub struct Thing<'a> {
LL ~ chars: (Box<dyn Iterator<Item = char> + 'a>, Box<dyn Iterator<Item = char> + 'a>),
|
The message would still need to account for plurality.
| }; | ||
| diag.span_note( | ||
| span, | ||
| format!("{these} trait object{s} {introduce} an implicit `'static` obligation"), |
There was a problem hiding this comment.
I thought "trait object" was outdated terminology that we're phasing out, but I keep forgetting if that's actually a thing or if we have docs for it or sth
There was a problem hiding this comment.
Used dyn Trait. I thought so too, but did find multiple diagnostics that still use that wording. I'm more certain about dyn-compatibility and it might be what we're both thinking of.
|
Reminder, once the PR becomes ready for a review, use |
f1e60ac to
d625bbc
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
d625bbc to
fe5080d
Compare
fe5080d to
cae5ac3
Compare
This comment has been minimized.
This comment has been minimized.
cae5ac3 to
4dac048
Compare
| LL | fn foo(mut x: Ref, y: Ref) { | ||
| | ----- - has type `Ref<'_, '1>` | ||
| | | | ||
| | ----- --- - --- lifetime `'1` introduced here | ||
| | | | | | ||
| | | | has type `Ref<'_, '1>` | ||
| | | lifetime `'2` introduced here | ||
| | has type `Ref<'_, '2>` |
There was a problem hiding this comment.
These cases are made more verbose one could argue unnecessarily, but there are quite a few other cases where it is a significant improvement (because we point at the exact type in a longer path). I can try spending a bit more time to try to filter only these, but this PR is already ballooning in size, so I'll leave it up to you to decide what to do :)
There was a problem hiding this comment.
sometimes more verbose is better if things are hard to debug already. So sgtm for now and we can revisit by throwing some of these at ppl and seeing how useful the messages are to them
| error: lifetime may not live long enough | ||
| --> $DIR/implicit-lifetime-in-assoc-type-projection.rs:29:5 | ||
| | | ||
| LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ||
| | -- lifetime `'a` defined here | ||
| LL | type Output = u64; | ||
| LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) { | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | | | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^^^^^^^^^^^^^^^ | ||
| | | | | | ||
| | | | lifetime `'1` introduced here | ||
| | | has type `Box<dyn Subscriber<Input = <MyStruct<'_> as Publisher<'1>>::Output>>` | ||
| | requires that `'1` must outlive `'a` |
There was a problem hiding this comment.
This is a case where I think the current approach is an improvement (let alone the ones pointing at the impl that we were hiding before).
…pe being returned
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:11:24
|
LL | pub fn new(string: &str) -> Self {
| - let's call the lifetime of this reference `'1`
LL | Thing {
LL | chars: Box::new(string.chars()),
| ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
note: this trait object introduces an implicit `'static` obligation
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:5:20
|
LL | pub struct Thing {
LL | chars: Box<dyn Iterator<Item = char>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime
|
LL ~ pub struct Thing<'a> {
LL ~ chars: Box<dyn Iterator<Item = char> + 'a>,
|
```
…nd add test for multiple `dyn Trait`s
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:126:25
|
LL | pub fn new(string: &str) -> Self {
| - let's call the lifetime of this reference `'1`
LL | Thing {
LL | chars: (Box::new(string.chars()), Box::new(string.chars())),
| ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
note: these `dyn Trait`s introduce an implicit `'static` obligation
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:120:21
|
LL | pub struct Thing {
LL | chars: (Box<dyn Iterator<Item = char>>, Box<dyn Iterator<Item = char>>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime
|
LL ~ pub struct Thing<'a> {
LL ~ chars: (Box<dyn Iterator<Item = char> + 'a>, Box<dyn Iterator<Item = char> + 'a>),
|
```
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:24:13
|
LL | impl Thing<'_> {
| -- lifetime `'2` introduced here
LL | pub fn new(string: &str) -> Self {
| - ---- return type is `b::Thing<'2>`
| |
| let's call the lifetime of this reference `'1`
LL | / Thing {
LL | | chars: Box::new(string.chars()),
LL | | }
| |_____________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
```
```
error: lifetime may not live long enough
--> $DIR/issue-52742.rs:12:9
|
LL | impl Foo<'_, '_> {
| -- lifetime `'2` introduced here
LL | fn take_bar(&mut self, b: Bar<'_>) {
| --------- - -- lifetime `'1` introduced here
| | |
| | has type `Bar<'1>`
| has type `&mut Foo<'_, '2>`
LL | self.y = b.z
| ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
```
750bb36 to
3574f1d
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
| let lt_span = if let Some(needle) = self.regioncx.to_error_region(needle_fr) | ||
| && let Some(def_id) = needle.opt_param_def_id(self.infcx.tcx, self.mir_def_id().into()) | ||
| { | ||
| Some(self.infcx.tcx.def_span(def_id)) | ||
| } else { | ||
| None | ||
| }; |
There was a problem hiding this comment.
| let lt_span = if let Some(needle) = self.regioncx.to_error_region(needle_fr) | |
| && let Some(def_id) = needle.opt_param_def_id(self.infcx.tcx, self.mir_def_id().into()) | |
| { | |
| Some(self.infcx.tcx.def_span(def_id)) | |
| } else { | |
| None | |
| }; | |
| let lt_span = self.regioncx | |
| .to_error_region(needle_fr) | |
| .and_then(|needle| needle.opt_param_def_id(self.infcx.tcx, self.mir_def_id()) | |
| .map(|def_id| self.infcx.tcx.def_span(def_id.into())); |
or sth ^^
…expr-2, r=oli-obk
Account for trait object with implicit `'static` lifetime in field type being returned
Point at `dyn Trait` in field of type definition when it introduces a `'static` obligation:
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:11:24
|
LL | pub fn new(string: &str) -> Self {
| - let's call the lifetime of this reference `'1`
LL | Thing {
LL | chars: Box::new(string.chars()),
| ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
note: `dyn Trait` introduces an implicit `'static` obligation
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:5:20
|
LL | pub struct Thing {
LL | chars: Box<dyn Iterator<Item = char>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime
|
LL ~ pub struct Thing<'a> {
LL ~ chars: Box<dyn Iterator<Item = char> + 'a>,
|
```
Fix rust-lang#78547.
Point at introduction of unmet lifetime:
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:24:13
|
LL | impl Thing<'_> {
| -- lifetime `'2` introduced here
LL | pub fn new(string: &str) -> Self {
| - ---- return type is `b::Thing<'2>`
| |
| let's call the lifetime of this reference `'1`
LL | / Thing {
LL | | chars: Box::new(string.chars()),
LL | | }
| |_____________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
```
```
error: lifetime may not live long enough
--> $DIR/issue-52742.rs:12:9
|
LL | impl Foo<'_, '_> {
| -- lifetime `'2` introduced here
LL | fn take_bar(&mut self, b: Bar<'_>) {
| --------- - -- lifetime `'1` introduced here
| | |
| | has type `Bar<'1>`
| has type `&mut Foo<'_, '2>`
LL | self.y = b.z
| ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
```
…expr-2, r=oli-obk
Account for trait object with implicit `'static` lifetime in field type being returned
Point at `dyn Trait` in field of type definition when it introduces a `'static` obligation:
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:11:24
|
LL | pub fn new(string: &str) -> Self {
| - let's call the lifetime of this reference `'1`
LL | Thing {
LL | chars: Box::new(string.chars()),
| ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
note: `dyn Trait` introduces an implicit `'static` obligation
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:5:20
|
LL | pub struct Thing {
LL | chars: Box<dyn Iterator<Item = char>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime
|
LL ~ pub struct Thing<'a> {
LL ~ chars: Box<dyn Iterator<Item = char> + 'a>,
|
```
Fix rust-lang#78547.
Point at introduction of unmet lifetime:
```
error: lifetime may not live long enough
--> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:24:13
|
LL | impl Thing<'_> {
| -- lifetime `'2` introduced here
LL | pub fn new(string: &str) -> Self {
| - ---- return type is `b::Thing<'2>`
| |
| let's call the lifetime of this reference `'1`
LL | / Thing {
LL | | chars: Box::new(string.chars()),
LL | | }
| |_____________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
```
```
error: lifetime may not live long enough
--> $DIR/issue-52742.rs:12:9
|
LL | impl Foo<'_, '_> {
| -- lifetime `'2` introduced here
LL | fn take_bar(&mut self, b: Bar<'_>) {
| --------- - -- lifetime `'1` introduced here
| | |
| | has type `Bar<'1>`
| has type `&mut Foo<'_, '2>`
LL | self.y = b.z
| ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
```
…uwer Rollup of 12 pull requests Successful merges: - #162808 (Enable `--generate-link-to-definition` rustdoc option on std docs) - #163219 (assumptions_on_binders: Test mixed ambiguous ORs) - #164985 (Only recover if we may for `recover_missing_dot`) - #161521 (Replace check_attr_crate_level with check_target for #[doc]) - #162530 (Move #[naked] attribute check to attribute parsing stage) - #164103 (trait solver: Resolve region vars before eager placeholder handling) - #164692 (move `ppcf128` lang item to `core::num::imp`) - #164702 (Point at `impl` through which associated function is provided) - #164776 (Account for trait object with implicit `'static` lifetime in field type being returned) - #164791 (Self param after const param) - #164856 (Switch from `insta` to `expect-test` in bootstrap) - #164888 (Add regression tests for #156380)
…uwer Rollup of 14 pull requests Successful merges: - #163219 (assumptions_on_binders: Test mixed ambiguous ORs) - #164985 (Only recover if we may for `recover_missing_dot`) - #161521 (Replace check_attr_crate_level with check_target for #[doc]) - #162530 (Move #[naked] attribute check to attribute parsing stage) - #164103 (trait solver: Resolve region vars before eager placeholder handling) - #164692 (move `ppcf128` lang item to `core::num::imp`) - #164702 (Point at `impl` through which associated function is provided) - #164741 (Use explicit target cpu in tests parsing generated asm) - #164767 (Add regression tests for transmutability issues) - #164776 (Account for trait object with implicit `'static` lifetime in field type being returned) - #164791 (Self param after const param) - #164856 (Switch from `insta` to `expect-test` in bootstrap) - #164888 (Add regression tests for #156380) - #164967 (Add codegen test for power of two implying nonzero with debuginfo)
Rollup merge of #164776 - estebank:short-lifetime-in-return-expr-2, r=oli-obk Account for trait object with implicit `'static` lifetime in field type being returned Point at `dyn Trait` in field of type definition when it introduces a `'static` obligation: ``` error: lifetime may not live long enough --> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:11:24 | LL | pub fn new(string: &str) -> Self { | - let's call the lifetime of this reference `'1` LL | Thing { LL | chars: Box::new(string.chars()), | ^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static` | note: `dyn Trait` introduces an implicit `'static` obligation --> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:5:20 | LL | pub struct Thing { LL | chars: Box<dyn Iterator<Item = char>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider introducing an explicit lifetime | LL ~ pub struct Thing<'a> { LL ~ chars: Box<dyn Iterator<Item = char> + 'a>, | ``` Fix #78547. Point at introduction of unmet lifetime: ``` error: lifetime may not live long enough --> $DIR/return-expr-with-implicit-trait-object-static-obligation.rs:24:13 | LL | impl Thing<'_> { | -- lifetime `'2` introduced here LL | pub fn new(string: &str) -> Self { | - ---- return type is `b::Thing<'2>` | | | let's call the lifetime of this reference `'1` LL | / Thing { LL | | chars: Box::new(string.chars()), LL | | } | |_____________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` ``` ``` error: lifetime may not live long enough --> $DIR/issue-52742.rs:12:9 | LL | impl Foo<'_, '_> { | -- lifetime `'2` introduced here LL | fn take_bar(&mut self, b: Bar<'_>) { | --------- - -- lifetime `'1` introduced here | | | | | has type `Bar<'1>` | has type `&mut Foo<'_, '2>` LL | self.y = b.z | ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` ```
…uwer Rollup of 14 pull requests Successful merges: - rust-lang/rust#163219 (assumptions_on_binders: Test mixed ambiguous ORs) - rust-lang/rust#164985 (Only recover if we may for `recover_missing_dot`) - rust-lang/rust#161521 (Replace check_attr_crate_level with check_target for #[doc]) - rust-lang/rust#162530 (Move #[naked] attribute check to attribute parsing stage) - rust-lang/rust#164103 (trait solver: Resolve region vars before eager placeholder handling) - rust-lang/rust#164692 (move `ppcf128` lang item to `core::num::imp`) - rust-lang/rust#164702 (Point at `impl` through which associated function is provided) - rust-lang/rust#164741 (Use explicit target cpu in tests parsing generated asm) - rust-lang/rust#164767 (Add regression tests for transmutability issues) - rust-lang/rust#164776 (Account for trait object with implicit `'static` lifetime in field type being returned) - rust-lang/rust#164791 (Self param after const param) - rust-lang/rust#164856 (Switch from `insta` to `expect-test` in bootstrap) - rust-lang/rust#164888 (Add regression tests for #156380) - rust-lang/rust#164967 (Add codegen test for power of two implying nonzero with debuginfo)
Point at
dyn Traitin field of type definition when it introduces a'staticobligation:Fix #78547.
Point at introduction of unmet lifetime: