Skip to content

Commit b70fb41

Browse files
committed
And more general error
1 parent d6e4fe5 commit b70fb41

File tree

7 files changed

+78
-15
lines changed

7 files changed

+78
-15
lines changed

compiler/rustc_resolve/messages.ftl

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ resolve_added_macro_use =
1111
resolve_ancestor_only =
1212
visibilities can only be restricted to ancestor modules
1313
14+
resolve_anonymous_livetime_non_gat_report_error =
15+
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
16+
.label = this lifetime must come from the implemented type
17+
1418
resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here
1519
1620
resolve_associated_const_with_similar_name_exists =
@@ -235,7 +239,7 @@ resolve_label_with_similar_name_reachable =
235239
a label with a similar name is reachable
236240
237241
resolve_lending_iterator_report_error =
238-
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.
242+
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
239243
.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.
240244
241245
resolve_lifetime_param_in_enum_discriminant =

compiler/rustc_resolve/src/errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,14 @@ pub(crate) struct LendingIteratorReportError {
891891
pub(crate) ty: Span,
892892
}
893893

894+
#[derive(Diagnostic)]
895+
#[diag(resolve_anonymous_livetime_non_gat_report_error)]
896+
pub(crate) struct AnonymousLivetimeNonGatReportError {
897+
#[primary_span]
898+
#[label]
899+
pub(crate) lifetime: Span,
900+
}
901+
894902
#[derive(Subdiagnostic)]
895903
#[multipart_suggestion(
896904
resolve_elided_anonymous_lifetime_report_error_suggestion,

compiler/rustc_resolve/src/late.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,9 @@ struct DiagMetadata<'ast> {
629629
in_assignment: Option<&'ast Expr>,
630630
is_assign_rhs: bool,
631631

632+
/// If we are setting an associated type in trait impl, is it a non-GAT type?
633+
in_non_gat_assoc_type: Option<bool>,
634+
632635
/// Used to detect possible `.` -> `..` typo when calling methods.
633636
in_range: Option<(&'ast Expr, &'ast Expr)>,
634637

@@ -1704,21 +1707,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
17041707
}
17051708
}
17061709

1707-
// Is it caused by user trying to implement a lending iterator?
1710+
// are we trying to use an anonymous lifetime
1711+
// on a non GAT associated trait type?
17081712
if !self.in_func_body
17091713
&& let Some((module, _)) = &self.current_trait_ref
17101714
&& let Some(ty) = &self.diag_metadata.current_self_type
1715+
&& Some(true) == self.diag_metadata.in_non_gat_assoc_type
17111716
&& let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind
1712-
&& def_id_matches_path(
1717+
{
1718+
if def_id_matches_path(
17131719
self.r.tcx,
17141720
trait_id,
17151721
&["core", "iter", "traits", "iterator", "Iterator"],
1716-
)
1717-
{
1718-
self.r.dcx().emit_err(errors::LendingIteratorReportError {
1719-
lifetime: lifetime.ident.span,
1720-
ty: ty.span(),
1721-
});
1722+
) {
1723+
self.r.dcx().emit_err(errors::LendingIteratorReportError {
1724+
lifetime: lifetime.ident.span,
1725+
ty: ty.span(),
1726+
});
1727+
} else {
1728+
self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
1729+
lifetime: lifetime.ident.span,
1730+
});
1731+
}
17221732
} else {
17231733
self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
17241734
span: lifetime.ident.span,
@@ -3076,6 +3086,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
30763086
);
30773087
}
30783088
AssocItemKind::Type(box TyAlias { generics, .. }) => {
3089+
self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
30793090
debug!("resolve_implementation AssocItemKind::Type");
30803091
// We also need a new scope for the impl item type parameters.
30813092
self.with_generic_param_rib(
@@ -3104,6 +3115,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
31043115
});
31053116
},
31063117
);
3118+
self.diag_metadata.in_non_gat_assoc_type = None;
31073119
}
31083120
AssocItemKind::Delegation(box delegation) => {
31093121
debug!("resolve_implementation AssocItemKind::Delegation");

tests/ui/impl-header-lifetime-elision/assoc-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait MyTrait {
99

1010
impl MyTrait for &i32 {
1111
type Output = &i32;
12-
//~^ ERROR `&` without an explicit lifetime name cannot be used here
12+
//~^ 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
1313
}
1414

1515
impl MyTrait for &u32 {

tests/ui/impl-header-lifetime-elision/assoc-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0637]: `&` without an explicit lifetime name cannot be used here
1+
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
22
--> $DIR/assoc-type.rs:11:19
33
|
44
LL | type Output = &i32;
5-
| ^ explicit lifetime name needed here
5+
| ^ this lifetime must come from the implemented type
66

77
error[E0637]: `'_` cannot be used here
88
--> $DIR/assoc-type.rs:16:20

tests/ui/lifetimes/no_lending_iterators.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,34 @@ struct Data(String);
22

33
impl Iterator for Data {
44
type Item = &str;
5-
//~^ 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.
5+
//~^ 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
66

77
fn next(&mut self) -> Option<Self::Item> {
88
Some(&self.0)
99
}
1010
}
1111

12+
trait Bar {
13+
type Item;
14+
fn poke(&mut self, item: Self::Item);
15+
}
16+
17+
impl Bar for usize {
18+
type Item = &usize;
19+
//~^ 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
20+
21+
fn poke(&mut self, item: Self::Item) {
22+
self += *item;
23+
}
24+
}
25+
26+
impl Bar for isize {
27+
type Item<'a> = &'a isize;
28+
//~^ ERROR 27:14: 27:18: lifetime parameters or bounds on type `Item` do not match the trait declaration [E0195]
29+
30+
fn poke(&mut self, item: Self::Item) {
31+
self += *item;
32+
}
33+
}
34+
1235
fn main() {}

tests/ui/lifetimes/no_lending_iterators.stderr

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
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.
1+
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
22
--> $DIR/no_lending_iterators.rs:4:17
33
|
44
LL | type Item = &str;
@@ -10,5 +10,21 @@ note: you can't create an `Iterator` that borrows each `Item` from itself, but y
1010
LL | impl Iterator for Data {
1111
| ^^^^
1212

13-
error: aborting due to 1 previous error
13+
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
14+
--> $DIR/no_lending_iterators.rs:18:17
15+
|
16+
LL | type Item = &usize;
17+
| ^ this lifetime must come from the implemented type
18+
19+
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
20+
--> $DIR/no_lending_iterators.rs:27:14
21+
|
22+
LL | type Item;
23+
| - lifetimes in impl do not match this type in trait
24+
...
25+
LL | type Item<'a> = &'a isize;
26+
| ^^^^ lifetimes do not match type in trait
27+
28+
error: aborting due to 3 previous errors
1429

30+
For more information about this error, try `rustc --explain E0195`.

0 commit comments

Comments
 (0)