From 5639e52ae1aa91a5d2fef12509410d2997886d49 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 9 Jun 2022 17:52:10 +0900 Subject: [PATCH] move suggestions to its own method --- .../rustc_resolve/src/late/diagnostics.rs | 50 ++++++++++++------- ...swapping-self-ty-and-trait-edition-2021.rs | 13 ++++- ...ping-self-ty-and-trait-edition-2021.stderr | 30 +++++++++-- .../suggest-swapping-self-ty-and-trait.rs | 13 ++++- .../suggest-swapping-self-ty-and-trait.stderr | 30 +++++++++-- 5 files changed, 107 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 2266b4a1ecb..6f9c6592ad7 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -250,25 +250,8 @@ struct BaseError<'a> { let code = source.error_code(res.is_some()); let mut err = self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code); - if let Some((trait_ref, self_ty)) = - self.diagnostic_metadata.currently_processing_impl_trait.clone() - && let TyKind::Path(_, self_ty_path) = &self_ty.kind - && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None) - && let ModuleKind::Def(DefKind::Trait, ..) = module.kind - && trait_ref.path.span == span - && let PathSource::Trait(_) = source - && let Some(Res::Def(DefKind::Struct, _)) = res - && let Ok(self_ty_str) = - self.r.session.source_map().span_to_snippet(self_ty.span) - && let Ok(trait_ref_str) = - self.r.session.source_map().span_to_snippet(trait_ref.path.span) - { - err.multipart_suggestion( - "consider swapping the struct and the trait", - vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)], - Applicability::MaybeIncorrect, - ); - } + + self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); if let Some(sugg) = base_error.suggestion { err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect); @@ -704,6 +687,35 @@ fn detect_assoct_type_constraint_meant_as_path(&self, base_span: Span, err: &mut } } + fn suggest_swapping_misplaced_self_ty_and_trait( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + res: Option, + span: Span, + ) { + if let Some((trait_ref, self_ty)) = + self.diagnostic_metadata.currently_processing_impl_trait.clone() + && let TyKind::Path(_, self_ty_path) = &self_ty.kind + && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = + self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None) + && let ModuleKind::Def(DefKind::Trait, ..) = module.kind + && trait_ref.path.span == span + && let PathSource::Trait(_) = source + && let Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) = res + && let Ok(self_ty_str) = + self.r.session.source_map().span_to_snippet(self_ty.span) + && let Ok(trait_ref_str) = + self.r.session.source_map().span_to_snippet(trait_ref.path.span) + { + err.multipart_suggestion( + "`impl` items mention the trait being implemented first and the type it is being implemented for second", + vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)], + Applicability::MaybeIncorrect, + ); + } + } + fn get_single_associated_item( &mut self, path: &[Segment], diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs index a32e943daf8..03c7ed347bd 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs @@ -2,10 +2,21 @@ pub trait Trait<'a, T> {} -pub struct Struct {} +pub struct Struct; +pub enum Enum {} + +pub union Union { + f1: usize, +} impl<'a, T> Struct for Trait<'a, T> {} //~^ ERROR expected trait, found struct `Struct` //~| ERROR trait objects must include the `dyn` keyword +impl<'a, T> Enum for Trait<'a, T> {} +//~^ ERROR expected trait, found enum `Enum` + +impl<'a, T> Union for Trait<'a, T> {} +//~^ ERROR expected trait, found union `Union` + fn main() {} diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr index aa9d09a797b..dd6951e0474 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr @@ -1,16 +1,38 @@ error[E0404]: expected trait, found struct `Struct` - --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:13 + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:13 | LL | impl<'a, T> Struct for Trait<'a, T> {} | ^^^^^^^^^ not a trait | -help: consider swapping the struct and the trait +help: `impl` items mention the trait being implemented first and the type it is being implemented for second | LL | impl<'a, T> Trait<'a, T> for Struct {} | ~~~~~~~~~~~~ ~~~~~~~~~ +error[E0404]: expected trait, found enum `Enum` + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:16:13 + | +LL | impl<'a, T> Enum for Trait<'a, T> {} + | ^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Enum {} + | ~~~~~~~~~~~~ ~~~~~~~ + +error[E0404]: expected trait, found union `Union` + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13 + | +LL | impl<'a, T> Union for Trait<'a, T> {} + | ^^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Union {} + | ~~~~~~~~~~~~ ~~~~~~~~ + error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:27 + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:27 | LL | impl<'a, T> Struct for Trait<'a, T> {} | ^^^^^^^^^^^^ @@ -21,7 +43,7 @@ LL - impl<'a, T> Struct for Trait<'a, T> {} LL + impl<'a, T> Struct for dyn Trait<'a, T> {} | -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0404, E0782. For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs index d74cc86f7ea..947bc2c7965 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs @@ -1,10 +1,21 @@ pub trait Trait<'a, T> {} -pub struct Struct {} +pub struct Struct; +pub enum Enum {} + +pub union Union { + f1: usize, +} impl<'a, T> Struct for Trait<'a, T> {} //~^ ERROR expected trait, found struct `Struct` //~| WARNING trait objects without an explicit `dyn` are deprecated //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +impl<'a, T> Enum for Trait<'a, T> {} +//~^ ERROR expected trait, found enum `Enum` + +impl<'a, T> Union for Trait<'a, T> {} +//~^ ERROR expected trait, found union `Union` + fn main() {} diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr index f5f22f03cd9..86ab8474c42 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr @@ -1,16 +1,38 @@ error[E0404]: expected trait, found struct `Struct` - --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:13 + --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:13 | LL | impl<'a, T> Struct for Trait<'a, T> {} | ^^^^^^^^^ not a trait | -help: consider swapping the struct and the trait +help: `impl` items mention the trait being implemented first and the type it is being implemented for second | LL | impl<'a, T> Trait<'a, T> for Struct {} | ~~~~~~~~~~~~ ~~~~~~~~~ +error[E0404]: expected trait, found enum `Enum` + --> $DIR/suggest-swapping-self-ty-and-trait.rs:15:13 + | +LL | impl<'a, T> Enum for Trait<'a, T> {} + | ^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Enum {} + | ~~~~~~~~~~~~ ~~~~~~~ + +error[E0404]: expected trait, found union `Union` + --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13 + | +LL | impl<'a, T> Union for Trait<'a, T> {} + | ^^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Union {} + | ~~~~~~~~~~~~ ~~~~~~~~ + warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:27 + --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:27 | LL | impl<'a, T> Struct for Trait<'a, T> {} | ^^^^^^^^^^^^ @@ -24,6 +46,6 @@ LL - impl<'a, T> Struct for Trait<'a, T> {} LL + impl<'a, T> Struct for dyn Trait<'a, T> {} | -error: aborting due to previous error; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0404`. -- GitLab