Skip to content

Commit a18d424

Browse files
committed
Allocate a new diagnostic for defaulted type parameters cannot use Self
(Without this commit, you still get an error (a very similar one, at that), but it complains about use of forward declaration, which is confusing since people do not necessarily think of `Self` as being declared at all.) Update: incorporate review feedback.
1 parent 3a4921c commit a18d424

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

src/librustc_resolve/diagnostics.rs

+11
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,17 @@ impl<'a> Resolver<'a> {
354354
span, "defaulted type parameters cannot be forward declared".to_string());
355355
err
356356
}
357+
ResolutionError::SelfInTyParamDefault => {
358+
let mut err = struct_span_err!(
359+
self.session,
360+
span,
361+
E0735,
362+
"type parameters cannot use `Self` in their defaults"
363+
);
364+
err.span_label(
365+
span, "`Self` in type parameter default".to_string());
366+
err
367+
}
357368
ResolutionError::ConstParamDependentOnTypeParam => {
358369
let mut err = struct_span_err!(
359370
self.session,

src/librustc_resolve/error_codes.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Type parameter defaults can only use parameters that occur before them.
88
Erroneous code example:
99
1010
```compile_fail,E0128
11-
struct Foo<T=U, U=()> {
11+
struct Foo<T = U, U = ()> {
1212
field1: T,
13-
filed2: U,
13+
field2: U,
1414
}
1515
// error: type parameters with a default cannot use forward declared
1616
// identifiers
@@ -20,9 +20,9 @@ Since type parameters are evaluated in-order, you may be able to fix this issue
2020
by doing:
2121
2222
```
23-
struct Foo<U=(), T=U> {
23+
struct Foo<U = (), T = U> {
2424
field1: T,
25-
filed2: U,
25+
field2: U,
2626
}
2727
```
2828
@@ -1705,6 +1705,21 @@ fn const_id<T, const N: T>() -> T { // error: const parameter
17051705
}
17061706
```
17071707
"##,
1708+
1709+
E0735: r##"
1710+
Type parameter defaults cannot use `Self` on structs, enums, or unions.
1711+
1712+
Erroneous code example:
1713+
1714+
```compile_fail,E0735
1715+
struct Foo<X = Box<Self>> {
1716+
field1: Option<X>,
1717+
field2: Option<X>,
1718+
}
1719+
// error: type parameters cannot use `Self` in their defaults.
1720+
```
1721+
"##,
1722+
17081723
;
17091724
// E0153, unused error code
17101725
// E0157, unused error code

src/librustc_resolve/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ enum ResolutionError<'a> {
214214
BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
215215
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
216216
ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
217+
/// Error E0735: type parameters with a default cannot use `Self`
218+
SelfInTyParamDefault,
217219
/// Error E0671: const parameter cannot depend on type parameter.
218220
ConstParamDependentOnTypeParam,
219221
}
@@ -1536,7 +1538,7 @@ impl<'a> Resolver<'a> {
15361538
if let Some(res) = ribs[i].bindings.get(&rib_ident).cloned() {
15371539
// The ident resolves to a type parameter or local variable.
15381540
return Some(LexicalScopeBinding::Res(
1539-
self.validate_res_from_ribs(i, res, record_used, path_span, ribs),
1541+
self.validate_res_from_ribs(i, rib_ident, res, record_used, path_span, ribs),
15401542
));
15411543
}
15421544

@@ -2122,6 +2124,7 @@ impl<'a> Resolver<'a> {
21222124
fn validate_res_from_ribs(
21232125
&mut self,
21242126
rib_index: usize,
2127+
rib_ident: Ident,
21252128
res: Res,
21262129
record_used: bool,
21272130
span: Span,
@@ -2133,7 +2136,12 @@ impl<'a> Resolver<'a> {
21332136
// An invalid forward use of a type parameter from a previous default.
21342137
if let ForwardTyParamBanRibKind = all_ribs[rib_index].kind {
21352138
if record_used {
2136-
self.report_error(span, ResolutionError::ForwardDeclaredTyParam);
2139+
let res_error = if rib_ident.name == kw::SelfUpper {
2140+
ResolutionError::SelfInTyParamDefault
2141+
} else {
2142+
ResolutionError::ForwardDeclaredTyParam
2143+
};
2144+
self.report_error(span, res_error);
21372145
}
21382146
assert_eq!(res, Res::Err);
21392147
return Res::Err;

0 commit comments

Comments
 (0)