From c00ff9c4d01e8ba64bf03aaf3bb7940874d3e094 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 27 Oct 2022 21:48:41 +0100 Subject: [PATCH 1/3] DoIt --- .../locales/en-US/hir_analysis.ftl | 2 + .../rustc_hir_analysis/src/collect/type_of.rs | 32 ++++++++- compiler/rustc_hir_analysis/src/errors.rs | 7 ++ src/test/ui/resolve/issue-23305.rs | 2 +- src/test/ui/resolve/issue-23305.stderr | 20 +----- src/test/ui/resolve/resolve-self-in-impl.rs | 8 +-- .../ui/resolve/resolve-self-in-impl.stderr | 68 +++---------------- 7 files changed, 56 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index 7ac44312695d9..7cedfca5728c7 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -146,3 +146,5 @@ hir_analysis_const_impl_for_non_const_trait = hir_analysis_const_bound_for_non_const_trait = ~const can only be applied to `#[const_trait]` traits + +hir_analysis_self_in_impl_self = `Self` is not valid at this location diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 32f359a815819..877cd75587be8 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -319,7 +319,37 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } } ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty), - ItemKind::Impl(hir::Impl { self_ty, .. }) => icx.to_ty(*self_ty), + ItemKind::Impl( + hir::Impl { self_ty, .. } + ) => { + struct MyVisitor(bool); + impl<'v> hir::intravisit::Visitor<'v> for MyVisitor { + fn visit_ty(&mut self, t: &'v Ty<'v>) { + if matches!( + &t.kind, + TyKind::Path(hir::QPath::Resolved( + _, + Path { + res: hir::def::Res::SelfTyAlias { .. }, + .. + }, + )) + ) { + self.0 = true; + return; + } + hir::intravisit::walk_ty(self, t); + } + } + + let mut my_visitor = MyVisitor(false); + my_visitor.visit_ty(self_ty); + + match my_visitor.0 { + true => { tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: self_ty.span}); tcx.ty_error() }, + false => icx.to_ty(*self_ty), + } + }, ItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); tcx.mk_fn_def(def_id.to_def_id(), substs) diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index bd0c1f5dd1098..c3bfd0437ada3 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -270,3 +270,10 @@ pub struct ConstBoundForNonConstTrait { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_self_in_impl_self)] +pub struct SelfInImplSelf { + #[primary_span] + pub span: Span, +} diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs index 95635e12a63b1..3e3d5ee2fda0e 100644 --- a/src/test/ui/resolve/issue-23305.rs +++ b/src/test/ui/resolve/issue-23305.rs @@ -3,6 +3,6 @@ pub trait ToNbt { } impl dyn ToNbt {} -//~^ ERROR cycle detected +//~^ ERROR `Self` is not valid at this location fn main() {} diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr index 20aeb7b995a61..1b2745de321c0 100644 --- a/src/test/ui/resolve/issue-23305.stderr +++ b/src/test/ui/resolve/issue-23305.stderr @@ -1,22 +1,8 @@ -error[E0391]: cycle detected when computing type of `` - --> $DIR/issue-23305.rs:5:16 +error: `Self` is not valid at this location + --> $DIR/issue-23305.rs:5:6 | LL | impl dyn ToNbt {} - | ^^^^ - | - = note: ...which immediately requires computing type of `` again -note: cycle used when collecting item types in top-level module - --> $DIR/issue-23305.rs:1:1 - | -LL | / pub trait ToNbt { -LL | | fn new(val: T) -> Self; -LL | | } -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ + | ^^^^^^^^^^^^^^^ error: aborting due to previous error -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..f845e780bbfe7 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.rs +++ b/src/test/ui/resolve/resolve-self-in-impl.rs @@ -11,10 +11,10 @@ impl Tr for S where Self: Copy {} // OK impl Tr for S where S: Copy {} // OK impl Tr for S where Self::A: Copy {} // OK -impl Tr for Self {} //~ ERROR cycle detected -impl Tr for S {} //~ ERROR cycle detected -impl Self {} //~ ERROR cycle detected -impl S {} //~ ERROR cycle detected +impl Tr for Self {} //~ ERROR `Self` is not valid at this location +impl Tr for S {} //~ ERROR `Self` is not valid at this location +impl Self {} //~ ERROR `Self` is not valid at this location +impl S {} //~ ERROR `Self` is not valid at this location 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 aa99c1a33352e..93e2b4695fc06 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.stderr +++ b/src/test/ui/resolve/resolve-self-in-impl.stderr @@ -1,78 +1,26 @@ -error[E0391]: cycle detected when computing type of `` +error: `Self` is not valid at this location --> $DIR/resolve-self-in-impl.rs:14:13 | LL | impl Tr for Self {} | ^^^^ - | - = 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 - | -LL | / #![feature(associated_type_defaults)] -LL | | -LL | | struct S(T); -LL | | trait Tr { -... | -LL | | -LL | | fn main() {} - | |____________^ -error[E0391]: cycle detected when computing type of `` - --> $DIR/resolve-self-in-impl.rs:15:15 +error: `Self` is not valid at this location + --> $DIR/resolve-self-in-impl.rs:15:13 | LL | impl Tr for S {} - | ^^^^ - | - = 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 - | -LL | / #![feature(associated_type_defaults)] -LL | | -LL | | struct S(T); -LL | | trait Tr { -... | -LL | | -LL | | fn main() {} - | |____________^ + | ^^^^^^^ -error[E0391]: cycle detected when computing type of `` +error: `Self` is not valid at this location --> $DIR/resolve-self-in-impl.rs:16:6 | LL | impl Self {} | ^^^^ - | - = 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 - | -LL | / #![feature(associated_type_defaults)] -LL | | -LL | | struct S(T); -LL | | trait Tr { -... | -LL | | -LL | | fn main() {} - | |____________^ -error[E0391]: cycle detected when computing type of `` - --> $DIR/resolve-self-in-impl.rs:17:8 +error: `Self` is not valid at this location + --> $DIR/resolve-self-in-impl.rs:17:6 | LL | impl S {} - | ^^^^ - | - = 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 - | -LL | / #![feature(associated_type_defaults)] -LL | | -LL | | struct S(T); -LL | | trait Tr { -... | -LL | | -LL | | fn main() {} - | |____________^ + | ^^^^^^^ error[E0391]: cycle detected when computing trait implemented by `` --> $DIR/resolve-self-in-impl.rs:18:1 From ca5a6e43dd6fcfddf436d36f6907d8ef44c7105b Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 27 Oct 2022 22:18:26 +0100 Subject: [PATCH 2/3] use proper spans --- .../locales/en-US/hir_analysis.ftl | 4 +- .../rustc_hir_analysis/src/collect/type_of.rs | 13 +++--- compiler/rustc_hir_analysis/src/errors.rs | 6 ++- src/test/ui/resolve/issue-23305.rs | 2 +- src/test/ui/resolve/issue-23305.stderr | 8 ++-- src/test/ui/resolve/resolve-self-in-impl.rs | 9 +++-- .../ui/resolve/resolve-self-in-impl.stderr | 40 +++++++++++++------ 7 files changed, 54 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index 7cedfca5728c7..855866be6279f 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -147,4 +147,6 @@ hir_analysis_const_impl_for_non_const_trait = hir_analysis_const_bound_for_non_const_trait = ~const can only be applied to `#[const_trait]` traits -hir_analysis_self_in_impl_self = `Self` is not valid at this location +hir_analysis_self_in_impl_self = + `Self` is not valid in the self type of an impl block + .note = replace `Self` with a different type \ No newline at end of file diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 877cd75587be8..2032a4bce60cd 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -322,7 +322,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { ItemKind::Impl( hir::Impl { self_ty, .. } ) => { - struct MyVisitor(bool); + struct MyVisitor(Vec); impl<'v> hir::intravisit::Visitor<'v> for MyVisitor { fn visit_ty(&mut self, t: &'v Ty<'v>) { if matches!( @@ -335,19 +335,22 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { }, )) ) { - self.0 = true; + self.0.push(t.span); return; } hir::intravisit::walk_ty(self, t); } } - let mut my_visitor = MyVisitor(false); + let mut my_visitor = MyVisitor(vec![]); my_visitor.visit_ty(self_ty); match my_visitor.0 { - true => { tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: self_ty.span}); tcx.ty_error() }, - false => icx.to_ty(*self_ty), + spans if spans.len() > 0 => { + tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), }); + tcx.ty_error() + }, + _ => icx.to_ty(*self_ty), } }, ItemKind::Fn(..) => { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index c3bfd0437ada3..6ed8244d119de 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1,7 +1,7 @@ //! Errors emitted by `rustc_hir_analysis`. -use rustc_errors::IntoDiagnostic; use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler}; +use rustc_errors::{IntoDiagnostic, MultiSpan}; use rustc_macros::{Diagnostic, LintDiagnostic}; use rustc_middle::ty::Ty; use rustc_span::{symbol::Ident, Span, Symbol}; @@ -275,5 +275,7 @@ pub struct ConstBoundForNonConstTrait { #[diag(hir_analysis_self_in_impl_self)] pub struct SelfInImplSelf { #[primary_span] - pub span: Span, + pub span: MultiSpan, + #[note] + pub note: (), } diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs index 3e3d5ee2fda0e..6d7fe7c50a230 100644 --- a/src/test/ui/resolve/issue-23305.rs +++ b/src/test/ui/resolve/issue-23305.rs @@ -3,6 +3,6 @@ pub trait ToNbt { } impl dyn ToNbt {} -//~^ ERROR `Self` is not valid at this location +//~^ ERROR `Self` is not valid in the self type of an impl block fn main() {} diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr index 1b2745de321c0..aad1b583a3244 100644 --- a/src/test/ui/resolve/issue-23305.stderr +++ b/src/test/ui/resolve/issue-23305.stderr @@ -1,8 +1,10 @@ -error: `Self` is not valid at this location - --> $DIR/issue-23305.rs:5:6 +error: `Self` is not valid in the self type of an impl block + --> $DIR/issue-23305.rs:5:16 | LL | impl dyn ToNbt {} - | ^^^^^^^^^^^^^^^ + | ^^^^ + | + = note: replace `Self` with a different type error: aborting due to previous error diff --git a/src/test/ui/resolve/resolve-self-in-impl.rs b/src/test/ui/resolve/resolve-self-in-impl.rs index f845e780bbfe7..d0872d1b76f20 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.rs +++ b/src/test/ui/resolve/resolve-self-in-impl.rs @@ -11,10 +11,11 @@ impl Tr for S where Self: Copy {} // OK impl Tr for S where S: Copy {} // OK impl Tr for S where Self::A: Copy {} // OK -impl Tr for Self {} //~ ERROR `Self` is not valid at this location -impl Tr for S {} //~ ERROR `Self` is not valid at this location -impl Self {} //~ ERROR `Self` is not valid at this location -impl S {} //~ ERROR `Self` is not valid at this location +impl Tr for Self {} //~ ERROR `Self` is not valid in the self type of an impl block +impl Tr for S {} //~ ERROR `Self` is not valid in the self type of an impl block +impl Self {} //~ ERROR `Self` is not valid in the self type of an impl block +impl S {} //~ ERROR `Self` is not valid in the self type of an impl block +impl (Self, Self) {} //~ ERROR `Self` is not valid in the self type of an impl block 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 93e2b4695fc06..9f9ed68898f6c 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.stderr +++ b/src/test/ui/resolve/resolve-self-in-impl.stderr @@ -1,34 +1,50 @@ -error: `Self` is not valid at this location +error: `Self` is not valid in the self type of an impl block --> $DIR/resolve-self-in-impl.rs:14:13 | LL | impl Tr for Self {} | ^^^^ + | + = note: replace `Self` with a different type -error: `Self` is not valid at this location - --> $DIR/resolve-self-in-impl.rs:15:13 +error: `Self` is not valid in the self type of an impl block + --> $DIR/resolve-self-in-impl.rs:15:15 | LL | impl Tr for S {} - | ^^^^^^^ + | ^^^^ + | + = note: replace `Self` with a different type -error: `Self` is not valid at this location +error: `Self` is not valid in the self type of an impl block --> $DIR/resolve-self-in-impl.rs:16:6 | LL | impl Self {} | ^^^^ + | + = note: replace `Self` with a different type -error: `Self` is not valid at this location - --> $DIR/resolve-self-in-impl.rs:17:6 +error: `Self` is not valid in the self type of an impl block + --> $DIR/resolve-self-in-impl.rs:17:8 | LL | impl S {} - | ^^^^^^^ + | ^^^^ + | + = note: replace `Self` with a different type + +error: `Self` is not valid in the self type of an impl block + --> $DIR/resolve-self-in-impl.rs:18:7 + | +LL | impl (Self, Self) {} + | ^^^^ ^^^^ + | + = note: replace `Self` with a different type -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:19: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 | @@ -41,6 +57,6 @@ LL | | LL | | fn main() {} | |____________^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0391`. From b3425587a669d81b45f0d14f7fd6ae6108bf9444 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 27 Oct 2022 22:29:16 +0100 Subject: [PATCH 3/3] tidy + move logic to fn --- .../locales/en-US/hir_analysis.ftl | 4 +-- compiler/rustc_hir/src/hir.rs | 24 ++++++++++++++ .../rustc_hir_analysis/src/collect/type_of.rs | 33 +++---------------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index 855866be6279f..62f004da0cae3 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -147,6 +147,6 @@ hir_analysis_const_impl_for_non_const_trait = hir_analysis_const_bound_for_non_const_trait = ~const can only be applied to `#[const_trait]` traits -hir_analysis_self_in_impl_self = +hir_analysis_self_in_impl_self = `Self` is not valid in the self type of an impl block - .note = replace `Self` with a different type \ No newline at end of file + .note = replace `Self` with a different type diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index bc149e48d89e8..9a9e40a3f43a7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2418,6 +2418,30 @@ impl<'hir> Ty<'hir> { } final_ty } + + pub fn find_self_aliases(&self) -> Vec { + use crate::intravisit::Visitor; + struct MyVisitor(Vec); + impl<'v> Visitor<'v> for MyVisitor { + fn visit_ty(&mut self, t: &'v Ty<'v>) { + if matches!( + &t.kind, + TyKind::Path(QPath::Resolved( + _, + Path { res: crate::def::Res::SelfTyAlias { .. }, .. }, + )) + ) { + self.0.push(t.span); + return; + } + crate::intravisit::walk_ty(self, t); + } + } + + let mut my_visitor = MyVisitor(vec![]); + my_visitor.visit_ty(self); + my_visitor.0 + } } /// Not represented directly in the AST; referred to by name through a `ty_path`. diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 2032a4bce60cd..20903a68d6d93 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -319,36 +319,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } } ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty), - ItemKind::Impl( - hir::Impl { self_ty, .. } - ) => { - struct MyVisitor(Vec); - impl<'v> hir::intravisit::Visitor<'v> for MyVisitor { - fn visit_ty(&mut self, t: &'v Ty<'v>) { - if matches!( - &t.kind, - TyKind::Path(hir::QPath::Resolved( - _, - Path { - res: hir::def::Res::SelfTyAlias { .. }, - .. - }, - )) - ) { - self.0.push(t.span); - return; - } - hir::intravisit::walk_ty(self, t); - } - } - - let mut my_visitor = MyVisitor(vec![]); - my_visitor.visit_ty(self_ty); - - match my_visitor.0 { - spans if spans.len() > 0 => { + ItemKind::Impl(hir::Impl { self_ty, .. }) => { + match self_ty.find_self_aliases() { + spans if spans.len() > 0 => { tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), }); - tcx.ty_error() + tcx.ty_error() }, _ => icx.to_ty(*self_ty), }