-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tweak output of missing lifetime on associated type #135602
base: master
Are you sure you want to change the base?
Conversation
r? @Nadrieril rustbot has assigned @Nadrieril. Use |
This comment has been minimized.
This comment has been minimized.
When an associated type is missing a lifetime, point at its enclosing `impl`, whether it has or doesn't have lifetimes defined. If it does have a lifetime, suggest using it. ``` error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-1.rs:8:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use ... LL | type Item = &T; | ^ this lifetime must come from the implemented type | help: consider using the lifetime from the impl block | LL | type Item = &'a T; | ++ ``` ``` error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | LL | impl IntoIterator for &S { | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type ```
…s an implicit borrow in the self type ``` error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/missing-lifetime-in-assoc-type-1.rs:4:6 | LL | impl<'a> IntoIterator for &S { | ^^ unconstrained lifetime parameter | help: consider using the named lifetime here instead of an implict lifetime | LL | impl<'a> IntoIterator for &'a S { | ++ ```
``` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/missing-lifetime-in-assoc-type-2.rs:7:57 | LL | impl IntoIterator for &S { | - help: consider introducing lifetime `'a` here: `<'a>` ... LL | type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ^^ undeclared lifetime ``` ``` error[E0106]: missing lifetime specifier --> $DIR/issue-74918-missing-lifetime.rs:9:30 | LL | type Item = IteratorChunk<T, S>; | ^ expected named lifetime parameter | help: consider introducing a named lifetime parameter | LL ~ impl<'a, T, S: Iterator<Item = T>> Iterator for ChunkingIterator<T, S> { LL ~ type Item = IteratorChunk<'a, T, S>; | ```
Previously we only showed the trait's assoc item if the trait was local, because we were looking for a small span only for the generics, which we don't have for foreign traits. We now use `def_span` for the item, so we at least provide some context, even if its span is too wide. ``` error[E0195]: lifetime parameters or bounds on type `IntoIter` do not match the trait declaration --> tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs:7:18 | 7 | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; | ^^^^ lifetimes do not match type in trait | ::: /home/gh-estebank/rust/library/core/src/iter/traits/collect.rs:292:5 | 292 | type IntoIter: Iterator<Item = Self::Item>; | ------------------------------------------ lifetimes in impl do not match this type in trait ```
Given an associated item that needs a named lifetime, look at the enclosing `impl` item for one. If there is none, look at the self type and the implemented trait to see if either of those has an anonimous lifetime. If so, suggest adding a named lifetime. ``` error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | LL | type Item = &T; | ^ this lifetime must come from the implemented type | help: add a lifetime to the impl block and use it in the self type and associated type | LL ~ impl<'a> IntoIterator for &'a S { LL ~ type Item = &'a T; | ```
bcacdc8
to
7b38d31
Compare
Move the previous long message to a note and use a shorter primary message: ``` error: missing lifetime in associated type --> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use ... LL | type Item = &T; | ^ this lifetime must come from the implemented type | note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: consider using the lifetime from the impl block | LL | type Item = &'a T; | ++ ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attached screenshots as I find that 1) the colors help get a better sense of what the output looks in practice and 2) the lack of spans into the std types makes it harder to get what I was going for.
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates | ||
--> $DIR/missing-lifetime-in-assoc-type-1.rs:4:6 | ||
| | ||
LL | impl<'a> IntoIterator for &S { | ||
| ^^ unconstrained lifetime parameter | ||
| | ||
help: consider using the named lifetime here instead of an implict lifetime | ||
| | ||
LL | impl<'a> IntoIterator for &'a S { | ||
| ++ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error: missing lifetime in associated type | ||
--> $DIR/missing-lifetime-in-assoc-type-4.rs:5:17 | ||
| | ||
LL | type Item = &T; | ||
| ^ this lifetime must come from the implemented type | ||
| | ||
note: in the trait the associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | ||
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | ||
help: add a lifetime to the impl block and use it in the self type and associated type | ||
| | ||
LL ~ impl<'a> IntoIterator for &'a S { | ||
LL ~ type Item = &'a T; | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error[E0261]: use of undeclared lifetime name `'a` | ||
--> $DIR/missing-lifetime-in-assoc-type-2.rs:7:57 | ||
| | ||
LL | impl IntoIterator for &S { | ||
| - help: consider introducing lifetime `'a` here: `<'a>` | ||
... | ||
LL | type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ||
| ^^ undeclared lifetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to review on a per-commit basis and stop early. I can split-off later commits onto their own PRs. They are all together because they end up affecting the same output and build on each other, but they don't need to land together. |
Each commit can be reviewed independently. Address parts of #135589.
When an associated type is missing a lifetime, point at its enclosing
impl
, whether it has or doesn't have lifetimes defined. If it does have a lifetime, suggest using it.On unconstrained lifetime on impl block, suggest using it if there's an implicit borrow in the self type
Do not suggest introducing lifetime in impl assoc type
Previously we only showed the trait's assoc item if the trait was local, because we were looking for a small span only for the generics, which we don't have for foreign traits. We now use
def_span
for the item, so we at least provide some context, even if its span is too wide.