Rollup merge of #111477 - y21:extra-impl-in-trait-impl, r=compiler-errors
better diagnostics for `impl<..> impl Trait for Type` Fixes #109963
This commit is contained in:
commit
d7f742532a
@ -478,6 +478,11 @@ parse_missing_for_in_trait_impl = missing `for` in a trait impl
|
|||||||
|
|
||||||
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
|
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
|
||||||
|
|
||||||
|
parse_extra_impl_keyword_in_trait_impl = unexpected `impl` keyword
|
||||||
|
.suggestion = remove the extra `impl`
|
||||||
|
.note = this is parsed as an `impl Trait` type, but a trait is expected at this position
|
||||||
|
|
||||||
|
|
||||||
parse_non_item_in_item_list = non-item in item list
|
parse_non_item_in_item_list = non-item in item list
|
||||||
.suggestion_use_const_not_let = consider using `const` instead of `let` for associated const
|
.suggestion_use_const_not_let = consider using `const` instead of `let` for associated const
|
||||||
.label_list_start = item list starts here
|
.label_list_start = item list starts here
|
||||||
|
@ -1519,6 +1519,16 @@ pub(crate) struct ExpectedTraitInTraitImplFoundType {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_extra_impl_keyword_in_trait_impl)]
|
||||||
|
pub(crate) struct ExtraImplKeywordInTraitImpl {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
|
pub extra_impl_kw: Span,
|
||||||
|
#[note]
|
||||||
|
pub impl_trait_span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_bounds_not_allowed_on_trait_aliases)]
|
#[diag(parse_bounds_not_allowed_on_trait_aliases)]
|
||||||
pub(crate) struct BoundsNotAllowedOnTraitAliases {
|
pub(crate) struct BoundsNotAllowedOnTraitAliases {
|
||||||
|
@ -603,10 +603,24 @@ fn parse_item_impl(
|
|||||||
let path = match ty_first.kind {
|
let path = match ty_first.kind {
|
||||||
// This notably includes paths passed through `ty` macro fragments (#46438).
|
// This notably includes paths passed through `ty` macro fragments (#46438).
|
||||||
TyKind::Path(None, path) => path,
|
TyKind::Path(None, path) => path,
|
||||||
_ => {
|
other => {
|
||||||
self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
|
if let TyKind::ImplTrait(_, bounds) = other
|
||||||
span: ty_first.span,
|
&& let [bound] = bounds.as_slice()
|
||||||
});
|
{
|
||||||
|
// Suggest removing extra `impl` keyword:
|
||||||
|
// `impl<T: Default> impl Default for Wrapper<T>`
|
||||||
|
// ^^^^^
|
||||||
|
let extra_impl_kw = ty_first.span.until(bound.span());
|
||||||
|
self.sess
|
||||||
|
.emit_err(errors::ExtraImplKeywordInTraitImpl {
|
||||||
|
extra_impl_kw,
|
||||||
|
impl_trait_span: ty_first.span
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
|
||||||
|
span: ty_first.span,
|
||||||
|
});
|
||||||
|
}
|
||||||
err_path(ty_first.span)
|
err_path(ty_first.span)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
19
tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
Normal file
19
tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
struct S<T>(T);
|
||||||
|
struct S2;
|
||||||
|
|
||||||
|
impl<T: Default> Default for S<T> {
|
||||||
|
//~^ ERROR: unexpected `impl` keyword
|
||||||
|
//~| HELP: remove the extra `impl`
|
||||||
|
fn default() -> Self { todo!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for S2 {
|
||||||
|
//~^ ERROR: unexpected `impl` keyword
|
||||||
|
//~| HELP: remove the extra `impl`
|
||||||
|
fn default() -> Self { todo!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {}
|
19
tests/ui/impl-trait/extra-impl-in-trait-impl.rs
Normal file
19
tests/ui/impl-trait/extra-impl-in-trait-impl.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
struct S<T>(T);
|
||||||
|
struct S2;
|
||||||
|
|
||||||
|
impl<T: Default> impl Default for S<T> {
|
||||||
|
//~^ ERROR: unexpected `impl` keyword
|
||||||
|
//~| HELP: remove the extra `impl`
|
||||||
|
fn default() -> Self { todo!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl impl Default for S2 {
|
||||||
|
//~^ ERROR: unexpected `impl` keyword
|
||||||
|
//~| HELP: remove the extra `impl`
|
||||||
|
fn default() -> Self { todo!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {}
|
26
tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
Normal file
26
tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
error: unexpected `impl` keyword
|
||||||
|
--> $DIR/extra-impl-in-trait-impl.rs:6:18
|
||||||
|
|
|
||||||
|
LL | impl<T: Default> impl Default for S<T> {
|
||||||
|
| ^^^^^ help: remove the extra `impl`
|
||||||
|
|
|
||||||
|
note: this is parsed as an `impl Trait` type, but a trait is expected at this position
|
||||||
|
--> $DIR/extra-impl-in-trait-impl.rs:6:18
|
||||||
|
|
|
||||||
|
LL | impl<T: Default> impl Default for S<T> {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: unexpected `impl` keyword
|
||||||
|
--> $DIR/extra-impl-in-trait-impl.rs:12:6
|
||||||
|
|
|
||||||
|
LL | impl impl Default for S2 {
|
||||||
|
| ^^^^^ help: remove the extra `impl`
|
||||||
|
|
|
||||||
|
note: this is parsed as an `impl Trait` type, but a trait is expected at this position
|
||||||
|
--> $DIR/extra-impl-in-trait-impl.rs:12:6
|
||||||
|
|
|
||||||
|
LL | impl impl Default for S2 {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user