-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Tweak output of missing lifetime on associated type #135602
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
base: master
Are you sure you want to change the base?
Changes from 4 commits
eb6d6f9
b4507bf
a6cb0b5
2c7160b
119ea42
4756c5d
a46faeb
b4682f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -20,7 +20,8 @@ use rustc_ast::*; | |||||||||||||||||||||||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; | ||||||||||||||||||||||||||||
use rustc_errors::codes::*; | ||||||||||||||||||||||||||||
use rustc_errors::{ | ||||||||||||||||||||||||||||
Applicability, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions, | ||||||||||||||||||||||||||||
Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions, | ||||||||||||||||||||||||||||
pluralize, | ||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||
use rustc_hir::def::Namespace::{self, *}; | ||||||||||||||||||||||||||||
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; | ||||||||||||||||||||||||||||
|
@@ -359,6 +360,7 @@ enum LifetimeBinderKind { | |||||||||||||||||||||||||||
Function, | ||||||||||||||||||||||||||||
Closure, | ||||||||||||||||||||||||||||
ImplBlock, | ||||||||||||||||||||||||||||
ImplAssocType, | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
impl LifetimeBinderKind { | ||||||||||||||||||||||||||||
|
@@ -369,6 +371,7 @@ impl LifetimeBinderKind { | |||||||||||||||||||||||||||
PolyTrait => "bound", | ||||||||||||||||||||||||||||
WhereBound => "bound", | ||||||||||||||||||||||||||||
Item | ConstItem => "item", | ||||||||||||||||||||||||||||
ImplAssocType => "associated type", | ||||||||||||||||||||||||||||
ImplBlock => "impl block", | ||||||||||||||||||||||||||||
Function => "function", | ||||||||||||||||||||||||||||
Closure => "closure", | ||||||||||||||||||||||||||||
|
@@ -1870,9 +1873,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { | |||||||||||||||||||||||||||
ty: ty.span, | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||
self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError { | ||||||||||||||||||||||||||||
lifetime: lifetime.ident.span, | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
let mut err = self.r.dcx().create_err( | ||||||||||||||||||||||||||||
errors::AnonymousLivetimeNonGatReportError { | ||||||||||||||||||||||||||||
lifetime: lifetime.ident.span, | ||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span); | ||||||||||||||||||||||||||||
err.emit(); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||
self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError { | ||||||||||||||||||||||||||||
|
@@ -1909,6 +1916,47 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { | |||||||||||||||||||||||||||
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
fn point_at_impl_lifetimes(&mut self, err: &mut Diag<'_>, i: usize, lifetime: Span) { | ||||||||||||||||||||||||||||
let Some((rib, span)) = self.lifetime_ribs[..i] | ||||||||||||||||||||||||||||
.iter() | ||||||||||||||||||||||||||||
.rev() | ||||||||||||||||||||||||||||
.skip(1) | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the |
||||||||||||||||||||||||||||
.filter_map(|rib| match rib.kind { | ||||||||||||||||||||||||||||
LifetimeRibKind::Generics { span, kind: LifetimeBinderKind::ImplBlock, .. } => { | ||||||||||||||||||||||||||||
Some((rib, span)) | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
_ => None, | ||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||
.next() | ||||||||||||||||||||||||||||
Comment on lines
+1949
to
+1955
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
|
||||||||||||||||||||||||||||
else { | ||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||
if !rib.bindings.is_empty() { | ||||||||||||||||||||||||||||
err.span_label( | ||||||||||||||||||||||||||||
span, | ||||||||||||||||||||||||||||
format!( | ||||||||||||||||||||||||||||
"there {} named lifetime{} specified on the impl block you could use", | ||||||||||||||||||||||||||||
if rib.bindings.len() == 1 { "is a" } else { "are" }, | ||||||||||||||||||||||||||||
pluralize!(rib.bindings.len()), | ||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
if rib.bindings.len() == 1 { | ||||||||||||||||||||||||||||
err.span_suggestion_verbose( | ||||||||||||||||||||||||||||
lifetime.shrink_to_hi(), | ||||||||||||||||||||||||||||
"consider using the lifetime from the impl block", | ||||||||||||||||||||||||||||
format!("{} ", rib.bindings.keys().next().unwrap()), | ||||||||||||||||||||||||||||
Applicability::MaybeIncorrect, | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||
err.span_label( | ||||||||||||||||||||||||||||
span, | ||||||||||||||||||||||||||||
"you could add a lifetime on the impl block, if the trait or the self type can \ | ||||||||||||||||||||||||||||
have one", | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
#[instrument(level = "debug", skip(self))] | ||||||||||||||||||||||||||||
fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) { | ||||||||||||||||||||||||||||
let id = self.r.next_node_id(); | ||||||||||||||||||||||||||||
|
@@ -3349,7 +3397,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { | |||||||||||||||||||||||||||
LifetimeRibKind::Generics { | ||||||||||||||||||||||||||||
binder: item.id, | ||||||||||||||||||||||||||||
span: generics.span, | ||||||||||||||||||||||||||||
kind: LifetimeBinderKind::Item, | ||||||||||||||||||||||||||||
kind: LifetimeBinderKind::ImplAssocType, | ||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||
|this| { | ||||||||||||||||||||||||||||
this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { | ||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
struct S; | ||
struct T; | ||
|
||
impl<'a> IntoIterator for &S { | ||
//~^ ERROR E0207 | ||
//~| NOTE there is a named lifetime specified on the impl block you could use | ||
//~| NOTE unconstrained lifetime parameter | ||
//~| HELP consider using the named lifetime here instead of an implict lifetime | ||
type Item = &T; | ||
//~^ ERROR in the trait associated type | ||
//~| HELP consider using the lifetime from the impl block | ||
//~| NOTE this lifetime must come from the implemented type | ||
type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
todo!() | ||
} | ||
} | ||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
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: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 | ||
| | ||
help: consider using the lifetime from the impl block | ||
| | ||
LL | type Item = &'a T; | ||
| ++ | ||
|
||
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 { | ||
| ++ | ||
Comment on lines
+17
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0207`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
struct S; | ||
struct T; | ||
|
||
impl IntoIterator for &S { | ||
type Item = &T; | ||
//~^ ERROR in the trait associated type | ||
type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ||
//~^ ERROR use of undeclared lifetime name `'a` | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
todo!() | ||
} | ||
} | ||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
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 | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0261`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
struct S; | ||
struct T; | ||
|
||
impl IntoIterator for &S { | ||
type Item = &T; | ||
//~^ ERROR in the trait associated type | ||
type IntoIter = std::collections::btree_map::Values<i32, T>; | ||
//~^ ERROR missing lifetime specifier | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
todo!() | ||
} | ||
} | ||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
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-3.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 | ||
|
||
error[E0106]: missing lifetime specifier | ||
--> $DIR/missing-lifetime-in-assoc-type-3.rs:7:56 | ||
| | ||
LL | type IntoIter = std::collections::btree_map::Values<i32, T>; | ||
| ^ expected named lifetime parameter | ||
| | ||
help: consider introducing a named lifetime parameter | ||
| | ||
LL ~ impl<'a> IntoIterator for &S { | ||
LL | type Item = &T; | ||
LL | | ||
LL ~ type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ||
| | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0106`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
struct S; | ||
struct T; | ||
|
||
impl IntoIterator for &S { | ||
type Item = &T; | ||
//~^ ERROR in the trait associated type | ||
type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; | ||
//~^ ERROR lifetime parameters or bounds on type `IntoIter` do not match the trait declaration | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
todo!() | ||
} | ||
} | ||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
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-4.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 | ||
|
||
error[E0195]: lifetime parameters or bounds on type `IntoIter` do not match the trait declaration | ||
--> $DIR/missing-lifetime-in-assoc-type-4.rs:7:18 | ||
| | ||
LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; | ||
| ^^^^ lifetimes do not match type in trait | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0195`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
struct S; | ||
struct T; | ||
|
||
impl<'a> IntoIterator for &'_ S { | ||
//~^ ERROR E0207 | ||
//~| NOTE there is a named lifetime specified on the impl block you could use | ||
//~| NOTE unconstrained lifetime parameter | ||
//~| HELP consider using the named lifetime here instead of an implict lifetime | ||
type Item = &T; | ||
//~^ ERROR in the trait associated type | ||
//~| HELP consider using the lifetime from the impl block | ||
//~| NOTE this lifetime must come from the implemented type | ||
type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
todo!() | ||
} | ||
} | ||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
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-5.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 | ||
| | ||
help: consider using the lifetime from the impl block | ||
| | ||
LL | type Item = &'a T; | ||
| ++ | ||
|
||
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates | ||
--> $DIR/missing-lifetime-in-assoc-type-5.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: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0207`. |
Uh oh!
There was an error while loading. Please reload this page.
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.
Could you add a comment to the
Item
variant explaining which items it covers? Is it only trait assoc types now? If so better rename it.