move suggestions to its own method
This commit is contained in:
parent
9db03b9bc8
commit
5639e52ae1
5 changed files with 107 additions and 29 deletions
|
@ -250,25 +250,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
let code = source.error_code(res.is_some());
|
let code = source.error_code(res.is_some());
|
||||||
let mut err =
|
let mut err =
|
||||||
self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code);
|
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()
|
self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
|
||||||
&& 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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(sugg) = base_error.suggestion {
|
if let Some(sugg) = base_error.suggestion {
|
||||||
err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
|
err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
|
||||||
|
@ -704,6 +687,35 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suggest_swapping_misplaced_self_ty_and_trait(
|
||||||
|
&mut self,
|
||||||
|
err: &mut Diagnostic,
|
||||||
|
source: PathSource<'_>,
|
||||||
|
res: Option<Res>,
|
||||||
|
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(
|
fn get_single_associated_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &[Segment],
|
path: &[Segment],
|
||||||
|
|
|
@ -2,10 +2,21 @@
|
||||||
|
|
||||||
pub trait Trait<'a, T> {}
|
pub trait Trait<'a, T> {}
|
||||||
|
|
||||||
pub struct Struct<T> {}
|
pub struct Struct<T>;
|
||||||
|
pub enum Enum<T> {}
|
||||||
|
|
||||||
|
pub union Union<T> {
|
||||||
|
f1: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T> Struct<T> for Trait<'a, T> {}
|
impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
//~^ ERROR expected trait, found struct `Struct`
|
//~^ ERROR expected trait, found struct `Struct`
|
||||||
//~| ERROR trait objects must include the `dyn` keyword
|
//~| ERROR trait objects must include the `dyn` keyword
|
||||||
|
|
||||||
|
impl<'a, T> Enum<T> for Trait<'a, T> {}
|
||||||
|
//~^ ERROR expected trait, found enum `Enum`
|
||||||
|
|
||||||
|
impl<'a, T> Union<T> for Trait<'a, T> {}
|
||||||
|
//~^ ERROR expected trait, found union `Union`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,16 +1,38 @@
|
||||||
error[E0404]: expected trait, found struct `Struct`
|
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<T> for Trait<'a, T> {}
|
LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
| ^^^^^^^^^ not a trait
|
| ^^^^^^^^^ 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<T> {}
|
LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
|
||||||
| ~~~~~~~~~~~~ ~~~~~~~~~
|
| ~~~~~~~~~~~~ ~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0404]: expected trait, found enum `Enum`
|
||||||
|
--> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:16:13
|
||||||
|
|
|
||||||
|
LL | impl<'a, T> Enum<T> 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<T> {}
|
||||||
|
| ~~~~~~~~~~~~ ~~~~~~~
|
||||||
|
|
||||||
|
error[E0404]: expected trait, found union `Union`
|
||||||
|
--> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13
|
||||||
|
|
|
||||||
|
LL | impl<'a, T> Union<T> 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<T> {}
|
||||||
|
| ~~~~~~~~~~~~ ~~~~~~~~
|
||||||
|
|
||||||
error[E0782]: trait objects must include the `dyn` keyword
|
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<T> for Trait<'a, T> {}
|
LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -21,7 +43,7 @@ LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
|
LL + impl<'a, T> Struct<T> 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.
|
Some errors have detailed explanations: E0404, E0782.
|
||||||
For more information about an error, try `rustc --explain E0404`.
|
For more information about an error, try `rustc --explain E0404`.
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
pub trait Trait<'a, T> {}
|
pub trait Trait<'a, T> {}
|
||||||
|
|
||||||
pub struct Struct<T> {}
|
pub struct Struct<T>;
|
||||||
|
pub enum Enum<T> {}
|
||||||
|
|
||||||
|
pub union Union<T> {
|
||||||
|
f1: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T> Struct<T> for Trait<'a, T> {}
|
impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
//~^ ERROR expected trait, found struct `Struct`
|
//~^ ERROR expected trait, found struct `Struct`
|
||||||
//~| WARNING trait objects without an explicit `dyn` are deprecated
|
//~| 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!
|
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
|
|
||||||
|
impl<'a, T> Enum<T> for Trait<'a, T> {}
|
||||||
|
//~^ ERROR expected trait, found enum `Enum`
|
||||||
|
|
||||||
|
impl<'a, T> Union<T> for Trait<'a, T> {}
|
||||||
|
//~^ ERROR expected trait, found union `Union`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,16 +1,38 @@
|
||||||
error[E0404]: expected trait, found struct `Struct`
|
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<T> for Trait<'a, T> {}
|
LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
| ^^^^^^^^^ not a trait
|
| ^^^^^^^^^ 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<T> {}
|
LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
|
||||||
| ~~~~~~~~~~~~ ~~~~~~~~~
|
| ~~~~~~~~~~~~ ~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0404]: expected trait, found enum `Enum`
|
||||||
|
--> $DIR/suggest-swapping-self-ty-and-trait.rs:15:13
|
||||||
|
|
|
||||||
|
LL | impl<'a, T> Enum<T> 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<T> {}
|
||||||
|
| ~~~~~~~~~~~~ ~~~~~~~
|
||||||
|
|
||||||
|
error[E0404]: expected trait, found union `Union`
|
||||||
|
--> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13
|
||||||
|
|
|
||||||
|
LL | impl<'a, T> Union<T> 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<T> {}
|
||||||
|
| ~~~~~~~~~~~~ ~~~~~~~~
|
||||||
|
|
||||||
warning: trait objects without an explicit `dyn` are deprecated
|
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<T> for Trait<'a, T> {}
|
LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -24,6 +46,6 @@ LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
|
||||||
LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
|
LL + impl<'a, T> Struct<T> 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`.
|
For more information about this error, try `rustc --explain E0404`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue