From 5a155f642b265992859f0960e6bacd8d608dadf3 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 18 Mar 2022 00:53:12 +0900 Subject: [PATCH] Improve error message for `impl Self` use `replace` --- compiler/rustc_resolve/src/late.rs | 18 +++++++ src/test/ui/resolve/issue-23305.rs | 1 + src/test/ui/resolve/issue-23305.stderr | 8 ++- src/test/ui/resolve/resolve-self-in-impl.rs | 4 ++ .../ui/resolve/resolve-self-in-impl.stderr | 50 ++++++++++++++----- 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 91695257137cb..027c5a284508a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -394,6 +394,9 @@ struct DiagnosticMetadata<'ast> { /// Used to detect possible `if let` written without `let` and to provide structured suggestion. in_if_condition: Option<&'ast Expr>, + /// When processing a impl self type and encountering a `Self`, suggest not using it. + currently_processing_impl_self_ty: bool, + /// If we are currently in a trait object definition. Used to point at the bounds when /// encountering a struct or enum. current_trait_object: Option<&'ast [ast::GenericBound]>, @@ -1318,7 +1321,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { visit::walk_trait_ref(this, trait_ref); } // Resolve the self type. + let prev = replace( + &mut this.diagnostic_metadata.currently_processing_impl_self_ty, + true, + ); this.visit_ty(self_type); + this.diagnostic_metadata.currently_processing_impl_self_ty = prev; // Resolve the generic parameters. this.visit_generics(generics); // Resolve the items within the impl. @@ -2038,6 +2046,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { Ok(Some(partial_res)) if partial_res.unresolved_segments() == 0 => { if source.is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err { + if self.diagnostic_metadata.currently_processing_impl_self_ty { + if let Res::SelfTy { .. } = partial_res.base_res() { + if path.len() == 1 && path[0].ident.name == kw::SelfUpper { + self.r.session.span_err( + span, + "`Self` is only available in impls, traits, and type definitions", + ); + } + } + } partial_res } else { report_errors(self, Some(partial_res.base_res())) diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs index 95635e12a63b1..f02b13696399a 100644 --- a/src/test/ui/resolve/issue-23305.rs +++ b/src/test/ui/resolve/issue-23305.rs @@ -4,5 +4,6 @@ pub trait ToNbt { impl dyn ToNbt {} //~^ ERROR cycle detected +//~| ERROR `Self` is only available in impls, traits, and type definitions fn main() {} diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr index 0dcf0184db107..6fae19071c2b1 100644 --- a/src/test/ui/resolve/issue-23305.stderr +++ b/src/test/ui/resolve/issue-23305.stderr @@ -1,3 +1,9 @@ +error: `Self` is only available in impls, traits, and type definitions + --> $DIR/issue-23305.rs:5:16 + | +LL | impl dyn ToNbt {} + | ^^^^ + error[E0391]: cycle detected when computing type of `` --> $DIR/issue-23305.rs:5:16 | @@ -11,6 +17,6 @@ note: cycle used when collecting item types in top-level module LL | pub trait ToNbt { | ^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/resolve/resolve-self-in-impl.rs b/src/test/ui/resolve/resolve-self-in-impl.rs index 024fdc51ea318..b77cf4c7ebc4b 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.rs +++ b/src/test/ui/resolve/resolve-self-in-impl.rs @@ -12,9 +12,13 @@ impl Tr for S where S: Copy {} // OK impl Tr for S where Self::A: Copy {} // OK impl Tr for Self {} //~ ERROR cycle detected +//~^ ERROR `Self` is only available in impls, traits, and type definitions impl Tr for S {} //~ ERROR cycle detected +//~^ ERROR `Self` is only available in impls, traits, and type definitions impl Self {} //~ ERROR cycle detected +//~^ ERROR `Self` is only available in impls, traits, and type definitions impl S {} //~ ERROR cycle detected +//~^ ERROR `Self` is only available in impls, traits, and type definitions impl Tr for S {} //~ ERROR cycle detected fn main() {} diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr index 7f623e47353b9..2ac8eec52782c 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.stderr +++ b/src/test/ui/resolve/resolve-self-in-impl.stderr @@ -1,3 +1,27 @@ +error: `Self` is only available in impls, traits, and type definitions + --> $DIR/resolve-self-in-impl.rs:14:13 + | +LL | impl Tr for Self {} + | ^^^^ + +error: `Self` is only available in impls, traits, and type definitions + --> $DIR/resolve-self-in-impl.rs:16:15 + | +LL | impl Tr for S {} + | ^^^^ + +error: `Self` is only available in impls, traits, and type definitions + --> $DIR/resolve-self-in-impl.rs:18:6 + | +LL | impl Self {} + | ^^^^ + +error: `Self` is only available in impls, traits, and type definitions + --> $DIR/resolve-self-in-impl.rs:20:8 + | +LL | impl S {} + | ^^^^ + error[E0391]: cycle detected when computing type of `` --> $DIR/resolve-self-in-impl.rs:14:13 | @@ -17,13 +41,13 @@ LL | | LL | | fn main() {} | |____________^ -error[E0391]: cycle detected when computing type of `` - --> $DIR/resolve-self-in-impl.rs:15:15 +error[E0391]: cycle detected when computing type of `` + --> $DIR/resolve-self-in-impl.rs:16:15 | LL | impl Tr for S {} | ^^^^ | - = note: ...which immediately requires computing type of `` again + = note: ...which immediately requires computing type of `` again note: cycle used when collecting item types in top-level module --> $DIR/resolve-self-in-impl.rs:1:1 | @@ -36,13 +60,13 @@ LL | | LL | | fn main() {} | |____________^ -error[E0391]: cycle detected when computing type of `` - --> $DIR/resolve-self-in-impl.rs:16:6 +error[E0391]: cycle detected when computing type of `` + --> $DIR/resolve-self-in-impl.rs:18:6 | LL | impl Self {} | ^^^^ | - = note: ...which immediately requires computing type of `` again + = note: ...which immediately requires computing type of `` again note: cycle used when collecting item types in top-level module --> $DIR/resolve-self-in-impl.rs:1:1 | @@ -55,13 +79,13 @@ LL | | LL | | fn main() {} | |____________^ -error[E0391]: cycle detected when computing type of `` - --> $DIR/resolve-self-in-impl.rs:17:8 +error[E0391]: cycle detected when computing type of `` + --> $DIR/resolve-self-in-impl.rs:20:8 | LL | impl S {} | ^^^^ | - = note: ...which immediately requires computing type of `` again + = note: ...which immediately requires computing type of `` again note: cycle used when collecting item types in top-level module --> $DIR/resolve-self-in-impl.rs:1:1 | @@ -74,13 +98,13 @@ LL | | LL | | fn main() {} | |____________^ -error[E0391]: cycle detected when computing trait implemented by `` - --> $DIR/resolve-self-in-impl.rs:18:1 +error[E0391]: cycle detected when computing trait implemented by `` + --> $DIR/resolve-self-in-impl.rs:22:1 | LL | impl Tr for S {} | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: ...which immediately requires computing trait implemented by `` again + = note: ...which immediately requires computing trait implemented by `` again note: cycle used when collecting item types in top-level module --> $DIR/resolve-self-in-impl.rs:1:1 | @@ -93,6 +117,6 @@ LL | | LL | | fn main() {} | |____________^ -error: aborting due to 5 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0391`.