Skip to content

Commit a46faeb

Browse files
committed
Tweak wording in associated type with anon lifetime error
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; | ++ ```
1 parent 4756c5d commit a46faeb

19 files changed

+126
-25
lines changed

compiler/rustc_resolve/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ resolve_added_macro_use =
1111
resolve_ancestor_only =
1212
visibilities can only be restricted to ancestor modules
1313
14-
resolve_anonymous_lifetime_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
14+
resolve_anonymous_lifetime_non_gat_report_error = missing lifetime in associated type
1615
.label = this lifetime must come from the implemented type
16+
.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
1717
1818
resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here
1919

compiler/rustc_resolve/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,8 @@ pub(crate) struct AnonymousLivetimeNonGatReportError {
901901
#[primary_span]
902902
#[label]
903903
pub(crate) lifetime: Span,
904+
#[note]
905+
pub(crate) decl: MultiSpan,
904906
}
905907

906908
#[derive(Subdiagnostic)]

compiler/rustc_resolve/src/late.rs

+31-4
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ use rustc_ast::*;
2121
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
2222
use rustc_errors::codes::*;
2323
use rustc_errors::{
24-
Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions,
25-
pluralize,
24+
Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan, StashKey,
25+
Suggestions, pluralize,
2626
};
2727
use rustc_hir::def::Namespace::{self, *};
2828
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
2929
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};
3030
use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate};
3131
use rustc_middle::middle::resolve_bound_vars::Set1;
32-
use rustc_middle::ty::DelegationFnSig;
32+
use rustc_middle::ty::{AssocKind, DelegationFnSig};
3333
use rustc_middle::{bug, span_bug};
3434
use rustc_session::config::{CrateType, ResolveDocLinks};
3535
use rustc_session::lint::{self, BuiltinLintDiag};
3636
use rustc_session::parse::feature_err;
3737
use rustc_span::source_map::{Spanned, respan};
38-
use rustc_span::{BytePos, Ident, Span, Symbol, SyntaxContext, kw, sym};
38+
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, SyntaxContext, kw, sym};
3939
use smallvec::{SmallVec, smallvec};
4040
use tracing::{debug, instrument, trace};
4141

@@ -688,6 +688,9 @@ struct DiagMetadata<'ast> {
688688
/// The current impl items (used to suggest).
689689
current_impl_items: Option<&'ast [P<AssocItem>]>,
690690

691+
/// The current impl items (used to suggest).
692+
current_impl_item: Option<&'ast AssocItem>,
693+
691694
/// When processing impl trait
692695
currently_processing_impl_trait: Option<(TraitRef, Ty)>,
693696

@@ -1874,9 +1877,30 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18741877
ty: ty.span,
18751878
});
18761879
} else {
1880+
let decl = if !trait_id.is_local()
1881+
&& let Some(assoc) = self.diag_metadata.current_impl_item
1882+
&& let AssocItemKind::Type(_) = assoc.kind
1883+
&& let assocs = self.r.tcx.associated_items(trait_id)
1884+
&& let Some(assoc) = assocs.find_by_name_and_kind(
1885+
self.r.tcx,
1886+
assoc.ident,
1887+
AssocKind::Type,
1888+
trait_id,
1889+
) {
1890+
let mut decl: MultiSpan =
1891+
self.r.tcx.def_span(assoc.def_id).into();
1892+
decl.push_span_label(
1893+
self.r.tcx.def_span(trait_id),
1894+
String::new(),
1895+
);
1896+
decl
1897+
} else {
1898+
DUMMY_SP.into()
1899+
};
18771900
let mut err = self.r.dcx().create_err(
18781901
errors::AnonymousLivetimeNonGatReportError {
18791902
lifetime: lifetime.ident.span,
1903+
decl,
18801904
},
18811905
);
18821906
self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span);
@@ -3366,6 +3390,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33663390
) {
33673391
use crate::ResolutionError::*;
33683392
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
3393+
let prev = self.diag_metadata.current_impl_item.take();
3394+
self.diag_metadata.current_impl_item = Some(&item);
33693395
match &item.kind {
33703396
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
33713397
debug!("resolve_implementation AssocItemKind::Const");
@@ -3501,6 +3527,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
35013527
panic!("unexpanded macro in resolve!")
35023528
}
35033529
}
3530+
self.diag_metadata.current_impl_item = prev;
35043531
}
35053532

35063533
fn check_trait_item<F>(

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

+3-3
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 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
12+
//~^ ERROR missing lifetime in associated type
1313
}
1414

1515
impl MyTrait for &u32 {
@@ -19,15 +19,15 @@ impl MyTrait for &u32 {
1919

2020
impl<'a> MyTrait for &f64 {
2121
type Output = &f64;
22-
//~^ 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+
//~^ ERROR missing lifetime in associated type
2323
}
2424

2525
trait OtherTrait<'a> {
2626
type Output;
2727
}
2828
impl OtherTrait<'_> for f64 {
2929
type Output = &f64;
30-
//~^ 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
30+
//~^ ERROR missing lifetime in associated type
3131
}
3232

3333
// This is what you have to do:

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
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
1+
error: missing lifetime in associated type
22
--> $DIR/assoc-type.rs:11:19
33
|
44
LL | type Output = &i32;
55
| ^ this lifetime must come from the implemented type
66
|
7+
= 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
78
help: add a lifetime to the impl block and use it in the self type and associated type
89
|
910
LL ~ impl<'a> MyTrait for &'a i32 {
@@ -16,25 +17,27 @@ error[E0637]: `'_` cannot be used here
1617
LL | type Output = &'_ i32;
1718
| ^^ `'_` is a reserved lifetime name
1819

19-
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
20+
error: missing lifetime in associated type
2021
--> $DIR/assoc-type.rs:21:19
2122
|
2223
LL | impl<'a> MyTrait for &f64 {
2324
| ---- there is a named lifetime specified on the impl block you could use
2425
LL | type Output = &f64;
2526
| ^ this lifetime must come from the implemented type
2627
|
28+
= 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
2729
help: consider using the lifetime from the impl block
2830
|
2931
LL | type Output = &'a f64;
3032
| ++
3133

32-
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
34+
error: missing lifetime in associated type
3335
--> $DIR/assoc-type.rs:29:19
3436
|
3537
LL | type Output = &f64;
3638
| ^ this lifetime must come from the implemented type
3739
|
40+
= 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
3841
help: add a lifetime to the impl block and use it in the trait and associated type
3942
|
4043
LL ~ impl<'a> OtherTrait<'a> for f64 {

tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ impl<'a> IntoIterator for &S {
77
//~| NOTE unconstrained lifetime parameter
88
//~| HELP consider using the named lifetime here instead of an implict lifetime
99
type Item = &T;
10-
//~^ ERROR in the trait associated type
10+
//~^ ERROR missing lifetime in associated type
1111
//~| HELP consider using the lifetime from the impl block
1212
//~| NOTE this lifetime must come from the implemented type
13+
//~| NOTE in the trait the associated type is declared without lifetime parameters
1314
type IntoIter = std::collections::btree_map::Values<'a, i32, T>;
1415

1516
fn into_iter(self) -> Self::IntoIter {

tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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
1+
error: missing lifetime in associated type
22
--> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17
33
|
44
LL | impl<'a> IntoIterator for &S {
@@ -7,6 +7,8 @@ LL | impl<'a> IntoIterator for &S {
77
LL | type Item = &T;
88
| ^ this lifetime must come from the implemented type
99
|
10+
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
11+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
1012
help: consider using the lifetime from the impl block
1113
|
1214
LL | type Item = &'a T;

tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct T;
33

44
impl IntoIterator for &S {
55
type Item = &T;
6-
//~^ ERROR in the trait associated type
6+
//~^ ERROR missing lifetime in associated type
77
type IntoIter = std::collections::btree_map::Values<'a, i32, T>;
88
//~^ ERROR use of undeclared lifetime name `'a`
99

tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
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
1+
error: missing lifetime in associated type
22
--> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17
33
|
44
LL | type Item = &T;
55
| ^ this lifetime must come from the implemented type
66
|
7+
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
8+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
79
help: add a lifetime to the impl block and use it in the self type and associated type
810
|
911
LL ~ impl<'a> IntoIterator for &'a S {

tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct T;
33

44
impl IntoIterator for &S {
55
type Item = &T;
6-
//~^ ERROR in the trait associated type
6+
//~^ ERROR missing lifetime in associated type
77
type IntoIter = std::collections::btree_map::Values<i32, T>;
88
//~^ ERROR missing lifetime specifier
99

tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
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
1+
error: missing lifetime in associated type
22
--> $DIR/missing-lifetime-in-assoc-type-3.rs:5:17
33
|
44
LL | type Item = &T;
55
| ^ this lifetime must come from the implemented type
66
|
7+
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
8+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
79
help: add a lifetime to the impl block and use it in the self type and associated type
810
|
911
LL ~ impl<'a> IntoIterator for &'a S {

tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct T;
33

44
impl IntoIterator for &S {
55
type Item = &T;
6-
//~^ ERROR in the trait associated type
6+
//~^ ERROR missing lifetime in associated type
77
type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>;
88
//~^ ERROR lifetime parameters or bounds on type `IntoIter` do not match the trait declaration
99

tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
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
1+
error: missing lifetime in associated type
22
--> $DIR/missing-lifetime-in-assoc-type-4.rs:5:17
33
|
44
LL | type Item = &T;
55
| ^ this lifetime must come from the implemented type
66
|
7+
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
8+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
79
help: add a lifetime to the impl block and use it in the self type and associated type
810
|
911
LL ~ impl<'a> IntoIterator for &'a S {

tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ impl<'a> IntoIterator for &'_ S {
77
//~| NOTE unconstrained lifetime parameter
88
//~| HELP consider using the named lifetime here instead of an implict lifetime
99
type Item = &T;
10-
//~^ ERROR in the trait associated type
10+
//~^ ERROR missing lifetime in associated type
1111
//~| HELP consider using the lifetime from the impl block
1212
//~| NOTE this lifetime must come from the implemented type
13+
//~| NOTE in the trait the associated type is declared without lifetime parameters
1314
type IntoIter = std::collections::btree_map::Values<'a, i32, T>;
1415

1516
fn into_iter(self) -> Self::IntoIter {

tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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
1+
error: missing lifetime in associated type
22
--> $DIR/missing-lifetime-in-assoc-type-5.rs:9:17
33
|
44
LL | impl<'a> IntoIterator for &'_ S {
@@ -7,6 +7,8 @@ LL | impl<'a> IntoIterator for &'_ S {
77
LL | type Item = &T;
88
| ^ this lifetime must come from the implemented type
99
|
10+
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
11+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
1012
help: consider using the lifetime from the impl block
1113
|
1214
LL | type Item = &'a T;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//~ NOTE in the trait the associated type is declared without lifetime parameters
2+
struct S;
3+
struct T;
4+
5+
trait Trait {
6+
type Item;
7+
type IntoIter;
8+
fn into_iter(self) -> Self::IntoIter;
9+
}
10+
11+
impl<'a> Trait for &'_ S {
12+
//~^ ERROR E0207
13+
//~| NOTE there is a named lifetime specified on the impl block you could use
14+
//~| NOTE unconstrained lifetime parameter
15+
//~| HELP consider using the named lifetime here instead of an implict lifetime
16+
type Item = &T;
17+
//~^ ERROR missing lifetime in associated type
18+
//~| HELP consider using the lifetime from the impl block
19+
//~| NOTE this lifetime must come from the implemented type
20+
type IntoIter = std::collections::btree_map::Values<'a, i32, T>;
21+
22+
fn into_iter(self) -> Self::IntoIter {
23+
todo!()
24+
}
25+
}
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error: missing lifetime in associated type
2+
--> $DIR/missing-lifetime-in-assoc-type-6.rs:16:17
3+
|
4+
LL | impl<'a> Trait for &'_ S {
5+
| ---- there is a named lifetime specified on the impl block you could use
6+
...
7+
LL | type Item = &T;
8+
| ^ this lifetime must come from the implemented type
9+
|
10+
= 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
11+
help: consider using the lifetime from the impl block
12+
|
13+
LL | type Item = &'a T;
14+
| ++
15+
16+
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
17+
--> $DIR/missing-lifetime-in-assoc-type-6.rs:11:6
18+
|
19+
LL | impl<'a> Trait for &'_ S {
20+
| ^^ unconstrained lifetime parameter
21+
|
22+
help: consider using the named lifetime here instead of an implict lifetime
23+
|
24+
LL | impl<'a> Trait for &'a S {
25+
| ~~
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0207`.

tests/ui/lifetimes/no_lending_iterators.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ trait Bar {
1616

1717
impl Bar for usize {
1818
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
19+
//~^ ERROR missing lifetime in associated type
2020

2121
fn poke(&mut self, item: Self::Item) {
2222
self += *item;
@@ -25,7 +25,7 @@ impl Bar for usize {
2525

2626
impl Bar for isize {
2727
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]
28+
//~^ ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration [E0195]
2929

3030
fn poke(&mut self, item: Self::Item) {
3131
self += *item;

tests/ui/lifetimes/no_lending_iterators.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ 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: 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
13+
error: missing lifetime in associated type
1414
--> $DIR/no_lending_iterators.rs:18:17
1515
|
1616
LL | impl Bar for usize {
1717
| - you could add a lifetime on the impl block, if the trait or the self type could have one
1818
LL | type Item = &usize;
1919
| ^ this lifetime must come from the implemented type
20+
|
21+
= 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
2022

2123
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
2224
--> $DIR/no_lending_iterators.rs:27:14

0 commit comments

Comments
 (0)