Skip to content

Commit 5a155f6

Browse files
committed
Improve error message for impl Self
use `replace`
1 parent 3ba1ebe commit 5a155f6

File tree

5 files changed

+67
-14
lines changed

5 files changed

+67
-14
lines changed

compiler/rustc_resolve/src/late.rs

+18
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ struct DiagnosticMetadata<'ast> {
394394
/// Used to detect possible `if let` written without `let` and to provide structured suggestion.
395395
in_if_condition: Option<&'ast Expr>,
396396

397+
/// When processing a impl self type and encountering a `Self`, suggest not using it.
398+
currently_processing_impl_self_ty: bool,
399+
397400
/// If we are currently in a trait object definition. Used to point at the bounds when
398401
/// encountering a struct or enum.
399402
current_trait_object: Option<&'ast [ast::GenericBound]>,
@@ -1318,7 +1321,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13181321
visit::walk_trait_ref(this, trait_ref);
13191322
}
13201323
// Resolve the self type.
1324+
let prev = replace(
1325+
&mut this.diagnostic_metadata.currently_processing_impl_self_ty,
1326+
true,
1327+
);
13211328
this.visit_ty(self_type);
1329+
this.diagnostic_metadata.currently_processing_impl_self_ty = prev;
13221330
// Resolve the generic parameters.
13231331
this.visit_generics(generics);
13241332
// Resolve the items within the impl.
@@ -2038,6 +2046,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
20382046
Ok(Some(partial_res)) if partial_res.unresolved_segments() == 0 => {
20392047
if source.is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err
20402048
{
2049+
if self.diagnostic_metadata.currently_processing_impl_self_ty {
2050+
if let Res::SelfTy { .. } = partial_res.base_res() {
2051+
if path.len() == 1 && path[0].ident.name == kw::SelfUpper {
2052+
self.r.session.span_err(
2053+
span,
2054+
"`Self` is only available in impls, traits, and type definitions",
2055+
);
2056+
}
2057+
}
2058+
}
20412059
partial_res
20422060
} else {
20432061
report_errors(self, Some(partial_res.base_res()))

src/test/ui/resolve/issue-23305.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ pub trait ToNbt<T> {
44

55
impl dyn ToNbt<Self> {}
66
//~^ ERROR cycle detected
7+
//~| ERROR `Self` is only available in impls, traits, and type definitions
78

89
fn main() {}

src/test/ui/resolve/issue-23305.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: `Self` is only available in impls, traits, and type definitions
2+
--> $DIR/issue-23305.rs:5:16
3+
|
4+
LL | impl dyn ToNbt<Self> {}
5+
| ^^^^
6+
17
error[E0391]: cycle detected when computing type of `<impl at $DIR/issue-23305.rs:5:1: 5:24>`
28
--> $DIR/issue-23305.rs:5:16
39
|
@@ -11,6 +17,6 @@ note: cycle used when collecting item types in top-level module
1117
LL | pub trait ToNbt<T> {
1218
| ^^^^^^^^^^^^^^^^^^
1319

14-
error: aborting due to previous error
20+
error: aborting due to 2 previous errors
1521

1622
For more information about this error, try `rustc --explain E0391`.

src/test/ui/resolve/resolve-self-in-impl.rs

+4
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ impl Tr for S where S<Self>: Copy {} // OK
1212
impl Tr for S where Self::A: Copy {} // OK
1313

1414
impl Tr for Self {} //~ ERROR cycle detected
15+
//~^ ERROR `Self` is only available in impls, traits, and type definitions
1516
impl Tr for S<Self> {} //~ ERROR cycle detected
17+
//~^ ERROR `Self` is only available in impls, traits, and type definitions
1618
impl Self {} //~ ERROR cycle detected
19+
//~^ ERROR `Self` is only available in impls, traits, and type definitions
1720
impl S<Self> {} //~ ERROR cycle detected
21+
//~^ ERROR `Self` is only available in impls, traits, and type definitions
1822
impl Tr<Self::A> for S {} //~ ERROR cycle detected
1923

2024
fn main() {}

src/test/ui/resolve/resolve-self-in-impl.stderr

+37-13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
error: `Self` is only available in impls, traits, and type definitions
2+
--> $DIR/resolve-self-in-impl.rs:14:13
3+
|
4+
LL | impl Tr for Self {}
5+
| ^^^^
6+
7+
error: `Self` is only available in impls, traits, and type definitions
8+
--> $DIR/resolve-self-in-impl.rs:16:15
9+
|
10+
LL | impl Tr for S<Self> {}
11+
| ^^^^
12+
13+
error: `Self` is only available in impls, traits, and type definitions
14+
--> $DIR/resolve-self-in-impl.rs:18:6
15+
|
16+
LL | impl Self {}
17+
| ^^^^
18+
19+
error: `Self` is only available in impls, traits, and type definitions
20+
--> $DIR/resolve-self-in-impl.rs:20:8
21+
|
22+
LL | impl S<Self> {}
23+
| ^^^^
24+
125
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:14:1: 14:20>`
226
--> $DIR/resolve-self-in-impl.rs:14:13
327
|
@@ -17,13 +41,13 @@ LL | |
1741
LL | | fn main() {}
1842
| |____________^
1943

20-
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:23>`
21-
--> $DIR/resolve-self-in-impl.rs:15:15
44+
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:23>`
45+
--> $DIR/resolve-self-in-impl.rs:16:15
2246
|
2347
LL | impl Tr for S<Self> {}
2448
| ^^^^
2549
|
26-
= note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:23>` again
50+
= note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:23>` again
2751
note: cycle used when collecting item types in top-level module
2852
--> $DIR/resolve-self-in-impl.rs:1:1
2953
|
@@ -36,13 +60,13 @@ LL | |
3660
LL | | fn main() {}
3761
| |____________^
3862

39-
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:13>`
40-
--> $DIR/resolve-self-in-impl.rs:16:6
63+
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:13>`
64+
--> $DIR/resolve-self-in-impl.rs:18:6
4165
|
4266
LL | impl Self {}
4367
| ^^^^
4468
|
45-
= note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:13>` again
69+
= note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:13>` again
4670
note: cycle used when collecting item types in top-level module
4771
--> $DIR/resolve-self-in-impl.rs:1:1
4872
|
@@ -55,13 +79,13 @@ LL | |
5579
LL | | fn main() {}
5680
| |____________^
5781

58-
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:16>`
59-
--> $DIR/resolve-self-in-impl.rs:17:8
82+
error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:20:1: 20:16>`
83+
--> $DIR/resolve-self-in-impl.rs:20:8
6084
|
6185
LL | impl S<Self> {}
6286
| ^^^^
6387
|
64-
= note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:16>` again
88+
= note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:20:1: 20:16>` again
6589
note: cycle used when collecting item types in top-level module
6690
--> $DIR/resolve-self-in-impl.rs:1:1
6791
|
@@ -74,13 +98,13 @@ LL | |
7498
LL | | fn main() {}
7599
| |____________^
76100

77-
error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:26>`
78-
--> $DIR/resolve-self-in-impl.rs:18:1
101+
error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:22:1: 22:26>`
102+
--> $DIR/resolve-self-in-impl.rs:22:1
79103
|
80104
LL | impl Tr<Self::A> for S {}
81105
| ^^^^^^^^^^^^^^^^^^^^^^
82106
|
83-
= note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:26>` again
107+
= note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:22:1: 22:26>` again
84108
note: cycle used when collecting item types in top-level module
85109
--> $DIR/resolve-self-in-impl.rs:1:1
86110
|
@@ -93,6 +117,6 @@ LL | |
93117
LL | | fn main() {}
94118
| |____________^
95119

96-
error: aborting due to 5 previous errors
120+
error: aborting due to 9 previous errors
97121

98122
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)