And more general error

This commit is contained in:
Michael Baikov 2024-05-24 11:20:33 -04:00
parent d6e4fe569c
commit b70fb4159b
7 changed files with 78 additions and 15 deletions

View File

@ -11,6 +11,10 @@ resolve_added_macro_use =
resolve_ancestor_only = resolve_ancestor_only =
visibilities can only be restricted to ancestor modules visibilities can only be restricted to ancestor modules
resolve_anonymous_livetime_non_gat_report_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
.label = this lifetime must come from the implemented type
resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here
resolve_associated_const_with_similar_name_exists = resolve_associated_const_with_similar_name_exists =
@ -235,7 +239,7 @@ resolve_label_with_similar_name_reachable =
a label with a similar name is reachable a label with a similar name is reachable
resolve_lending_iterator_report_error = resolve_lending_iterator_report_error =
associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type. associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
.note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type. .note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type.
resolve_lifetime_param_in_enum_discriminant = resolve_lifetime_param_in_enum_discriminant =

View File

@ -891,6 +891,14 @@ pub(crate) struct LendingIteratorReportError {
pub(crate) ty: Span, pub(crate) ty: Span,
} }
#[derive(Diagnostic)]
#[diag(resolve_anonymous_livetime_non_gat_report_error)]
pub(crate) struct AnonymousLivetimeNonGatReportError {
#[primary_span]
#[label]
pub(crate) lifetime: Span,
}
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[multipart_suggestion( #[multipart_suggestion(
resolve_elided_anonymous_lifetime_report_error_suggestion, resolve_elided_anonymous_lifetime_report_error_suggestion,

View File

@ -629,6 +629,9 @@ struct DiagMetadata<'ast> {
in_assignment: Option<&'ast Expr>, in_assignment: Option<&'ast Expr>,
is_assign_rhs: bool, is_assign_rhs: bool,
/// If we are setting an associated type in trait impl, is it a non-GAT type?
in_non_gat_assoc_type: Option<bool>,
/// Used to detect possible `.` -> `..` typo when calling methods. /// Used to detect possible `.` -> `..` typo when calling methods.
in_range: Option<(&'ast Expr, &'ast Expr)>, in_range: Option<(&'ast Expr, &'ast Expr)>,
@ -1704,21 +1707,28 @@ fn resolve_anonymous_lifetime(&mut self, lifetime: &Lifetime, elided: bool) {
} }
} }
// Is it caused by user trying to implement a lending iterator? // are we trying to use an anonymous lifetime
// on a non GAT associated trait type?
if !self.in_func_body if !self.in_func_body
&& let Some((module, _)) = &self.current_trait_ref && let Some((module, _)) = &self.current_trait_ref
&& let Some(ty) = &self.diag_metadata.current_self_type && let Some(ty) = &self.diag_metadata.current_self_type
&& Some(true) == self.diag_metadata.in_non_gat_assoc_type
&& let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind
&& def_id_matches_path( {
if def_id_matches_path(
self.r.tcx, self.r.tcx,
trait_id, trait_id,
&["core", "iter", "traits", "iterator", "Iterator"], &["core", "iter", "traits", "iterator", "Iterator"],
) ) {
{ self.r.dcx().emit_err(errors::LendingIteratorReportError {
self.r.dcx().emit_err(errors::LendingIteratorReportError { lifetime: lifetime.ident.span,
lifetime: lifetime.ident.span, ty: ty.span(),
ty: ty.span(), });
}); } else {
self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
lifetime: lifetime.ident.span,
});
}
} else { } else {
self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError { self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
span: lifetime.ident.span, span: lifetime.ident.span,
@ -3076,6 +3086,7 @@ fn resolve_impl_item(
); );
} }
AssocItemKind::Type(box TyAlias { generics, .. }) => { AssocItemKind::Type(box TyAlias { generics, .. }) => {
self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
debug!("resolve_implementation AssocItemKind::Type"); debug!("resolve_implementation AssocItemKind::Type");
// We also need a new scope for the impl item type parameters. // We also need a new scope for the impl item type parameters.
self.with_generic_param_rib( self.with_generic_param_rib(
@ -3104,6 +3115,7 @@ fn resolve_impl_item(
}); });
}, },
); );
self.diag_metadata.in_non_gat_assoc_type = None;
} }
AssocItemKind::Delegation(box delegation) => { AssocItemKind::Delegation(box delegation) => {
debug!("resolve_implementation AssocItemKind::Delegation"); debug!("resolve_implementation AssocItemKind::Delegation");

View File

@ -9,7 +9,7 @@ trait MyTrait {
impl MyTrait for &i32 { impl MyTrait for &i32 {
type Output = &i32; type Output = &i32;
//~^ ERROR `&` without an explicit lifetime name cannot be used here //~^ ERROR 11:19: 11:20: 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
} }
impl MyTrait for &u32 { impl MyTrait for &u32 {

View File

@ -1,8 +1,8 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here 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/assoc-type.rs:11:19 --> $DIR/assoc-type.rs:11:19
| |
LL | type Output = &i32; LL | type Output = &i32;
| ^ explicit lifetime name needed here | ^ this lifetime must come from the implemented type
error[E0637]: `'_` cannot be used here error[E0637]: `'_` cannot be used here
--> $DIR/assoc-type.rs:16:20 --> $DIR/assoc-type.rs:16:20

View File

@ -2,11 +2,34 @@
impl Iterator for Data { impl Iterator for Data {
type Item = &str; type Item = &str;
//~^ ERROR 4:17: 4:18: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type. //~^ ERROR 4:17: 4:18: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
Some(&self.0) Some(&self.0)
} }
} }
trait Bar {
type Item;
fn poke(&mut self, item: Self::Item);
}
impl Bar for usize {
type Item = &usize;
//~^ ERROR 18:17: 18:18: 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
fn poke(&mut self, item: Self::Item) {
self += *item;
}
}
impl Bar for isize {
type Item<'a> = &'a isize;
//~^ ERROR 27:14: 27:18: lifetime parameters or bounds on type `Item` do not match the trait declaration [E0195]
fn poke(&mut self, item: Self::Item) {
self += *item;
}
}
fn main() {} fn main() {}

View File

@ -1,4 +1,4 @@
error: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type. error: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
--> $DIR/no_lending_iterators.rs:4:17 --> $DIR/no_lending_iterators.rs:4:17
| |
LL | type Item = &str; LL | type Item = &str;
@ -10,5 +10,21 @@ note: you can't create an `Iterator` that borrows each `Item` from itself, but y
LL | impl Iterator for Data { LL | impl Iterator for Data {
| ^^^^ | ^^^^
error: aborting due to 1 previous error 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/no_lending_iterators.rs:18:17
|
LL | type Item = &usize;
| ^ this lifetime must come from the implemented type
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
--> $DIR/no_lending_iterators.rs:27:14
|
LL | type Item;
| - lifetimes in impl do not match this type in trait
...
LL | type Item<'a> = &'a isize;
| ^^^^ lifetimes do not match type in trait
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0195`.