From 6d19ac36b904155ca0f3f89e6a6361d56a46551d Mon Sep 17 00:00:00 2001 From: Veera Date: Wed, 5 Jun 2024 19:11:40 -0400 Subject: [PATCH 1/2] Update Tests --- .../associated-type-bounds/no-gat-position.rs | 1 + .../no-gat-position.stderr | 5 + .../associated-types/associated-types-eq-2.rs | 2 - .../associated-types-eq-2.stderr | 62 +++--------- .../rtn-in-impl-signature.stderr | 5 + .../issue-89013-no-kw.rs | 3 +- .../issue-89013-no-kw.stderr | 22 +---- .../parser-error-recovery/issue-89013.rs | 1 - .../parser-error-recovery/issue-89013.stderr | 22 +---- ...ams-declared-in-wrong-spot-issue-113073.rs | 33 +++++++ ...declared-in-wrong-spot-issue-113073.stderr | 96 +++++++++++++++++++ 11 files changed, 161 insertions(+), 91 deletions(-) create mode 100644 tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.rs create mode 100644 tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr diff --git a/tests/ui/associated-type-bounds/no-gat-position.rs b/tests/ui/associated-type-bounds/no-gat-position.rs index cb62c88246813..249812ebbff71 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.rs +++ b/tests/ui/associated-type-bounds/no-gat-position.rs @@ -5,6 +5,7 @@ pub trait Iter { fn next<'a>(&'a mut self) -> Option>; //~^ ERROR associated item constraints are not allowed here + //~| HELP consider removing this associated item binding } impl Iter for () { diff --git a/tests/ui/associated-type-bounds/no-gat-position.stderr b/tests/ui/associated-type-bounds/no-gat-position.stderr index e167ac1fda458..b8e466b8d8421 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.stderr +++ b/tests/ui/associated-type-bounds/no-gat-position.stderr @@ -3,6 +3,11 @@ error[E0229]: associated item constraints are not allowed here | LL | fn next<'a>(&'a mut self) -> Option>; | ^^^^^^^^^ associated item constraint not allowed here + | +help: consider removing this associated item binding + | +LL | fn next<'a>(&'a mut self) -> Option>; + | ~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/associated-types-eq-2.rs b/tests/ui/associated-types/associated-types-eq-2.rs index f0a7d1e46b1bb..88eb298106100 100644 --- a/tests/ui/associated-types/associated-types-eq-2.rs +++ b/tests/ui/associated-types/associated-types-eq-2.rs @@ -76,7 +76,6 @@ trait Tr3 { impl Tr3 for Bar { } @@ -92,7 +91,6 @@ impl Tr3 for Qux { // matches the const param ident but the constraint is a type arg impl Tr3 for Bar { //~^ ERROR associated item constraints are not allowed here -//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied } // Test for when equality constraint's ident diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr index 53e4e59128ea6..69b1b533450c7 100644 --- a/tests/ui/associated-types/associated-types-eq-2.stderr +++ b/tests/ui/associated-types/associated-types-eq-2.stderr @@ -5,7 +5,6 @@ LL | impl Tr3 for Bar { | |____^ | @@ -14,7 +13,7 @@ LL | | = 42, T2 = Qux, T3 = usize> for Bar { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete - --> $DIR/associated-types-eq-2.rs:85:10 + --> $DIR/associated-types-eq-2.rs:84:10 | LL | impl Tr3 for Qux { | ^^^^^^ @@ -24,7 +23,7 @@ LL | impl Tr3 for Qux { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete - --> $DIR/associated-types-eq-2.rs:100:14 + --> $DIR/associated-types-eq-2.rs:98:14 | LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ^^^^^^^ @@ -34,7 +33,7 @@ LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete - --> $DIR/associated-types-eq-2.rs:108:10 + --> $DIR/associated-types-eq-2.rs:106:10 | LL | impl Tr3 for Bar { | ^^^^^^ @@ -190,22 +189,6 @@ help: to use `GenericTerm` as a generic argument specify it directly LL | impl Tr2> for Bar { | ~~~~~~~~~~~~~~~~ -error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied - --> $DIR/associated-types-eq-2.rs:76:6 - | -LL | impl Tr3 $DIR/associated-types-eq-2.rs:69:7 - | -LL | trait Tr3 { - | ^^^ ------------ -- -- -help: add missing generic arguments - | -LL | impl Tr3 $DIR/associated-types-eq-2.rs:76:10 | @@ -213,7 +196,6 @@ LL | impl Tr3 for Bar { | |____^ associated item constraint not allowed here | @@ -223,7 +205,7 @@ LL | impl Tr3<42, T2 = Qux, T3 = usize> for Bar { | ~~ error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied - --> $DIR/associated-types-eq-2.rs:85:6 + --> $DIR/associated-types-eq-2.rs:84:6 | LL | impl Tr3 for Qux { | ^^^ expected 3 generic arguments @@ -239,7 +221,7 @@ LL | impl Tr3 for Qux { | ++++++++++ error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-types-eq-2.rs:85:10 + --> $DIR/associated-types-eq-2.rs:84:10 | LL | impl Tr3 for Qux { | ^^^^^^ associated item constraint not allowed here @@ -249,24 +231,8 @@ help: consider removing this associated item binding LL | impl Tr3 for Qux { | ~~~~~~~ -error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied - --> $DIR/associated-types-eq-2.rs:93:6 - | -LL | impl Tr3 for Bar { - | ^^^ expected 3 generic arguments - | -note: trait defined here, with 3 generic parameters: `N`, `T2`, `T3` - --> $DIR/associated-types-eq-2.rs:69:7 - | -LL | trait Tr3 { - | ^^^ ------------ -- -- -help: add missing generic arguments - | -LL | impl Tr3 for Bar { - | ++++++++++ - error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-types-eq-2.rs:93:10 + --> $DIR/associated-types-eq-2.rs:92:10 | LL | impl Tr3 for Bar { | ^^^^^^^ associated item constraint not allowed here @@ -277,7 +243,7 @@ LL | impl Tr3 for Bar { | ~~~~~~~~ error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied - --> $DIR/associated-types-eq-2.rs:100:6 + --> $DIR/associated-types-eq-2.rs:98:6 | LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ^^^ -- supplied 1 generic argument @@ -295,7 +261,7 @@ LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar { | ++++++++ error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-types-eq-2.rs:100:14 + --> $DIR/associated-types-eq-2.rs:98:14 | LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ^^^^^^^ associated item constraint not allowed here @@ -306,7 +272,7 @@ LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ~~~~~~~~~ error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied - --> $DIR/associated-types-eq-2.rs:108:6 + --> $DIR/associated-types-eq-2.rs:106:6 | LL | impl Tr3 for Bar { | ^^^ expected 3 generic arguments @@ -322,7 +288,7 @@ LL | impl Tr3 for Bar { | ++++++++++ error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-types-eq-2.rs:108:10 + --> $DIR/associated-types-eq-2.rs:106:10 | LL | impl Tr3 for Bar { | ^^^^^^ associated item constraint not allowed here @@ -333,13 +299,13 @@ LL | impl Tr3 for Bar { | ~~~~~~~ error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied - --> $DIR/associated-types-eq-2.rs:119:13 + --> $DIR/associated-types-eq-2.rs:117:13 | LL | impl<'a, T> St<'a , T = Qux> { | ^^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `T` - --> $DIR/associated-types-eq-2.rs:117:8 + --> $DIR/associated-types-eq-2.rs:115:8 | LL | struct St<'a, T> { v: &'a T } | ^^ - @@ -349,7 +315,7 @@ LL | impl<'a, T> St<'a, T , T = Qux> { | +++ error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-types-eq-2.rs:119:21 + --> $DIR/associated-types-eq-2.rs:117:21 | LL | impl<'a, T> St<'a , T = Qux> { | ^^^^^^^ associated item constraint not allowed here @@ -359,7 +325,7 @@ help: to use `Qux` as a generic argument specify it directly LL | impl<'a, T> St<'a , Qux> { | ~~~ -error: aborting due to 27 previous errors +error: aborting due to 25 previous errors Some errors have detailed explanations: E0046, E0107, E0229, E0658. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr index b07c5735dff6b..b0c89b0592508 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr @@ -12,6 +12,11 @@ error[E0229]: associated item constraints are not allowed here | LL | impl Super1<'_, bar(): Send> for () {} | ^^^^^^^^^^^ associated item constraint not allowed here + | +help: consider removing this associated item binding + | +LL | impl Super1<'_, bar(): Send> for () {} + | ~~~~~~~~~~~~~ error[E0046]: not all trait items implemented, missing: `bar` --> $DIR/rtn-in-impl-signature.rs:10:1 diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs index fbf1553c182cf..c15482f92dca6 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -7,8 +7,7 @@ struct Bar; const T: usize = 42; impl Foo for Bar { -//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied -//~| ERROR associated item constraints are not allowed here +//~^ ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { [0u8; 3] diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index a132859b412f1..78cddcc234c6e 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -8,22 +8,6 @@ LL | impl Foo for Bar { = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied - --> $DIR/issue-89013-no-kw.rs:9:6 - | -LL | impl Foo for Bar { - | ^^^ expected 1 generic argument - | -note: trait defined here, with 1 generic parameter: `N` - --> $DIR/issue-89013-no-kw.rs:1:7 - | -LL | trait Foo { - | ^^^ -------------- -help: add missing generic argument - | -LL | impl Foo for Bar { - | ++ - error[E0229]: associated item constraints are not allowed here --> $DIR/issue-89013-no-kw.rs:9:10 | @@ -35,7 +19,7 @@ help: to use `3` as a generic argument specify it directly LL | impl Foo<3> for Bar { | ~ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0229, E0658. -For more information about an error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0229, E0658. +For more information about an error, try `rustc --explain E0229`. diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs index c9c7ff3a1704f..6302f7f2ad5d2 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -8,7 +8,6 @@ const T: usize = 42; impl Foo for Bar { //~^ ERROR expected lifetime, type, or constant, found keyword `const` -//~| ERROR trait takes 1 generic //~| ERROR associated item constraints are not allowed here //~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr index 2fdd12085652f..387eb226e70ed 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -20,22 +20,6 @@ LL | impl Foo for Bar { = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied - --> $DIR/issue-89013.rs:9:6 - | -LL | impl Foo for Bar { - | ^^^ expected 1 generic argument - | -note: trait defined here, with 1 generic parameter: `N` - --> $DIR/issue-89013.rs:1:7 - | -LL | trait Foo { - | ^^^ -------------- -help: add missing generic argument - | -LL | impl Foo for Bar { - | ++ - error[E0229]: associated item constraints are not allowed here --> $DIR/issue-89013.rs:9:10 | @@ -47,7 +31,7 @@ help: to use `3` as a generic argument specify it directly LL | impl Foo<3> for Bar { | ~ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0229, E0658. -For more information about an error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0229, E0658. +For more information about an error, try `rustc --explain E0229`. diff --git a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.rs b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.rs new file mode 100644 index 0000000000000..3a5b60e5763b3 --- /dev/null +++ b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.rs @@ -0,0 +1,33 @@ +trait Foo {} + +impl Foo for String {} +//~^ ERROR associated item constraints are not allowed here +//~| HELP declare the type parameter right after the `impl` keyword + +impl Foo for u8 {} +//~^ ERROR associated item constraints are not allowed here +//~| HELP declare the type parameter right after the `impl` keyword +//~| ERROR use of undeclared lifetime name `'a` +//~| HELP consider introducing lifetime `'a` here + +impl Foo for u16 {} +//~^ ERROR associated item constraints are not allowed here +//~| HELP declare the type parameter right after the `impl` keyword + +impl<'a> Foo for u32 {} +//~^ ERROR associated item constraints are not allowed here +//~| HELP declare the type parameter right after the `impl` keyword + +trait Bar {} + +impl Bar for String {} +//~^ ERROR associated item constraints are not allowed here +//~| HELP declare the type parameter right after the `impl` keyword + +impl Bar for u8 {} +//~^ ERROR trait takes 2 generic arguments but 1 generic argument was supplied +//~| HELP add missing generic argument +//~| ERROR associated item constraints are not allowed here +//~| HELP declare the type parameter right after the `impl` keyword + +fn main() {} diff --git a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr new file mode 100644 index 0000000000000..dfc6761e17e7f --- /dev/null +++ b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr @@ -0,0 +1,96 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:7:13 + | +LL | impl Foo for u8 {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + +error[E0229]: associated item constraints are not allowed here + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:3:10 + | +LL | impl Foo for String {} + | ^^^^^^^^^^ associated item constraint not allowed here + | +help: declare the type parameter right after the `impl` keyword + | +LL | impl Foo for String {} + | ++++++++++++ ~ + +error[E0229]: associated item constraints are not allowed here + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:7:10 + | +LL | impl Foo for u8 {} + | ^^^^^^^^^^^^^^^ associated item constraint not allowed here + | +help: declare the type parameter right after the `impl` keyword + | +LL | impl<'a, T: 'a + Default> Foo for u8 {} + | +++++++++++++++++++++ ~ + +error[E0229]: associated item constraints are not allowed here + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:13:13 + | +LL | impl Foo for u16 {} + | ^^^^^^^^^^ associated item constraint not allowed here + | +help: declare the type parameter right after the `impl` keyword + | +LL | impl Foo for u16 {} + | ++++++++++++ ~ + +error[E0229]: associated item constraints are not allowed here + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:17:14 + | +LL | impl<'a> Foo for u32 {} + | ^^^^^^^^^^^^^^^ associated item constraint not allowed here + | +help: declare the type parameter right after the `impl` keyword + | +LL | impl<'a, 'a, T: 'a + Default> Foo for u32 {} + | +++++++++++++++++++++ ~ + +error[E0229]: associated item constraints are not allowed here + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:23:10 + | +LL | impl Bar for String {} + | ^^^^^^^^^^ associated item constraint not allowed here + | +help: declare the type parameter right after the `impl` keyword + | +LL | impl Bar for String {} + | ++++++++++++ ~ + +error[E0107]: trait takes 2 generic arguments but 1 generic argument was supplied + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:27:9 + | +LL | impl Bar for u8 {} + | ^^^ - supplied 1 generic argument + | | + | expected 2 generic arguments + | +note: trait defined here, with 2 generic parameters: `T`, `K` + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:21:7 + | +LL | trait Bar {} + | ^^^ - - +help: add missing generic argument + | +LL | impl Bar for u8 {} + | +++ + +error[E0229]: associated item constraints are not allowed here + --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:27:16 + | +LL | impl Bar for u8 {} + | ^^^^^^^^^^ associated item constraint not allowed here + | +help: declare the type parameter right after the `impl` keyword + | +LL | impl Bar for u8 {} + | ++++++++++++ ~ + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0107, E0229, E0261. +For more information about an error, try `rustc --explain E0107`. From 5da1b4189e8b6820624ea548efe90c2cc35d576c Mon Sep 17 00:00:00 2001 From: Veera Date: Wed, 5 Jun 2024 20:12:16 -0400 Subject: [PATCH 2/2] E0229: Suggest Moving Type Constraints to Type Parameter Declaration --- compiler/rustc_hir/src/hir.rs | 24 +++++++ .../src/hir_ty_lowering/errors.rs | 71 ++++++++++++++++--- .../src/hir_ty_lowering/generics.rs | 17 ++++- .../associated-type-bounds/no-gat-position.rs | 2 +- .../no-gat-position.stderr | 2 +- .../rtn-in-impl-signature.stderr | 2 +- 6 files changed, 105 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e971d0e3c1435..a021847db2695 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2456,6 +2456,15 @@ pub enum AssocItemConstraintKind<'hir> { Bound { bounds: &'hir [GenericBound<'hir>] }, } +impl<'hir> AssocItemConstraintKind<'hir> { + pub fn descr(&self) -> &'static str { + match self { + AssocItemConstraintKind::Equality { .. } => "binding", + AssocItemConstraintKind::Bound { .. } => "constraint", + } + } +} + #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Ty<'hir> { pub hir_id: HirId, @@ -3735,6 +3744,21 @@ impl<'hir> Node<'hir> { } } + /// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`. + pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> { + match self { + Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) + if impl_block + .of_trait + .and_then(|trait_ref| trait_ref.trait_def_id()) + .is_some_and(|trait_id| trait_id == trait_def_id) => + { + Some(impl_block) + } + _ => None, + } + } + pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 3a9ef244fd3f5..2d240699105d6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1217,7 +1217,6 @@ pub fn prohibit_assoc_item_constraint( // otherwise suggest the removal of the binding. if let Some((def_id, segment, _)) = segment && segment.args().parenthesized == hir::GenericArgsParentheses::No - && let hir::AssocItemConstraintKind::Equality { term } = constraint.kind { // Suggests removal of the offending binding let suggest_removal = |e: &mut Diag<'_>| { @@ -1263,7 +1262,7 @@ pub fn prohibit_assoc_item_constraint( if let Ok(suggestion) = tcx.sess.source_map().span_to_snippet(removal_span) { e.span_suggestion_verbose( removal_span, - "consider removing this associated item binding", + format!("consider removing this associated item {}", constraint.kind.descr()), suggestion, Applicability::MaybeIncorrect, ); @@ -1286,19 +1285,73 @@ pub fn prohibit_assoc_item_constraint( // Check if the type has a generic param with the same name // as the assoc type name in the associated item binding. let generics = tcx.generics_of(def_id); - let matching_param = - generics.own_params.iter().find(|p| p.name.as_str() == constraint.ident.as_str()); + let matching_param = generics.own_params.iter().find(|p| p.name == constraint.ident.name); // Now emit the appropriate suggestion if let Some(matching_param) = matching_param { - match (&matching_param.kind, term) { - (GenericParamDefKind::Type { .. }, hir::Term::Ty(ty)) => { - suggest_direct_use(&mut err, ty.span); - } - (GenericParamDefKind::Const { .. }, hir::Term::Const(c)) => { + match (constraint.kind, &matching_param.kind) { + ( + hir::AssocItemConstraintKind::Equality { term: hir::Term::Ty(ty) }, + GenericParamDefKind::Type { .. }, + ) => suggest_direct_use(&mut err, ty.span), + ( + hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(c) }, + GenericParamDefKind::Const { .. }, + ) => { let span = tcx.hir().span(c.hir_id); suggest_direct_use(&mut err, span); } + (hir::AssocItemConstraintKind::Bound { bounds }, _) => { + // Suggest `impl Trait for Foo` when finding + // `impl Trait for Foo` + + // Get the parent impl block based on the binding we have + // and the trait DefId + let impl_block = tcx + .hir() + .parent_iter(constraint.hir_id) + .find_map(|(_, node)| node.impl_block_of_trait(def_id)); + + let type_with_constraints = + tcx.sess.source_map().span_to_snippet(constraint.span); + + if let Some(impl_block) = impl_block + && let Ok(type_with_constraints) = type_with_constraints + { + // Filter out the lifetime parameters because + // they should be declared before the type parameter + let lifetimes: String = bounds + .iter() + .filter_map(|bound| { + if let hir::GenericBound::Outlives(lifetime) = bound { + Some(format!("{lifetime}, ")) + } else { + None + } + }) + .collect(); + // Figure out a span and suggestion string based on + // whether there are any existing parameters + let param_decl = if let Some(param_span) = + impl_block.generics.span_for_param_suggestion() + { + (param_span, format!(", {lifetimes}{type_with_constraints}")) + } else { + ( + impl_block.generics.span.shrink_to_lo(), + format!("<{lifetimes}{type_with_constraints}>"), + ) + }; + let suggestions = + vec![param_decl, (constraint.span, format!("{}", matching_param.name))]; + + err.multipart_suggestion_verbose( + format!("declare the type parameter right after the `impl` keyword"), + suggestions, + Applicability::MaybeIncorrect, + ); + } + } _ => suggest_removal(&mut err), } } else { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 26cabb69d25c7..3f888c4e2722b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -531,6 +531,7 @@ pub(crate) fn check_generic_arg_count( let num_default_params = expected_max - expected_min; + let mut all_params_are_binded = false; let gen_args_info = if provided > expected_max { invalid_args.extend((expected_max..provided).map(|i| i + args_offset)); let num_redundant_args = provided - expected_max; @@ -547,6 +548,20 @@ pub(crate) fn check_generic_arg_count( } else { let num_missing_args = expected_max - provided; + let constraint_names: Vec<_> = + gen_args.constraints.iter().map(|b| b.ident.name).collect(); + let param_names: Vec<_> = gen_params + .own_params + .iter() + .filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter + .map(|param| param.name) + .collect(); + if constraint_names == param_names { + // We set this to true and delay emitting `WrongNumberOfGenericArgs` + // to provide a succinct error for cases like issue #113073 + all_params_are_binded = true; + }; + GenericArgsInfo::MissingTypesOrConsts { num_missing_args, num_default_params, @@ -567,7 +582,7 @@ pub(crate) fn check_generic_arg_count( def_id, ) .diagnostic() - .emit() + .emit_unless(all_params_are_binded) }); Err(reported) diff --git a/tests/ui/associated-type-bounds/no-gat-position.rs b/tests/ui/associated-type-bounds/no-gat-position.rs index 249812ebbff71..ec9214897fa8f 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.rs +++ b/tests/ui/associated-type-bounds/no-gat-position.rs @@ -5,7 +5,7 @@ pub trait Iter { fn next<'a>(&'a mut self) -> Option>; //~^ ERROR associated item constraints are not allowed here - //~| HELP consider removing this associated item binding + //~| HELP consider removing this associated item constraint } impl Iter for () { diff --git a/tests/ui/associated-type-bounds/no-gat-position.stderr b/tests/ui/associated-type-bounds/no-gat-position.stderr index b8e466b8d8421..39a2f89f9acf0 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.stderr +++ b/tests/ui/associated-type-bounds/no-gat-position.stderr @@ -4,7 +4,7 @@ error[E0229]: associated item constraints are not allowed here LL | fn next<'a>(&'a mut self) -> Option>; | ^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this associated item binding +help: consider removing this associated item constraint | LL | fn next<'a>(&'a mut self) -> Option>; | ~~~~~~~~~~~ diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr index b0c89b0592508..54960ae60bcca 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr @@ -13,7 +13,7 @@ error[E0229]: associated item constraints are not allowed here LL | impl Super1<'_, bar(): Send> for () {} | ^^^^^^^^^^^ associated item constraint not allowed here | -help: consider removing this associated item binding +help: consider removing this associated item constraint | LL | impl Super1<'_, bar(): Send> for () {} | ~~~~~~~~~~~~~