diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c21d3653a13be..3ff659dfc1c3d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -5607,6 +5607,18 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, 'ast, '_, '_> { .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. })) .count(); self.r.item_generics_num_lifetimes.insert(def_id, count); + let type_or_const_count = generics + .params + .iter() + .filter(|param| { + matches!( + param.kind, + ast::GenericParamKind::Type { .. } + | ast::GenericParamKind::Const { .. } + ) + }) + .count(); + self.r.item_generics_num_type_or_const_params.insert(def_id, type_or_const_count); } ItemKind::ForeignMod(ForeignMod { items, .. }) => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b126272583692..6d7408b71d4b4 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1322,7 +1322,17 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut fallback = false; let typo_sugg = typo_sugg .to_opt_suggestion() - .filter(|sugg| !suggested_candidates.contains(sugg.candidate.as_str())); + .filter(|sugg| !suggested_candidates.contains(sugg.candidate.as_str())) + // this filters out suggestions that require parameters when no parameter is present + .filter(|sugg| { + if !path.last().is_some_and(|s| s.has_generic_args) { + return true; + } + let Some(def_id) = sugg.res.opt_def_id() else { + return true; + }; + self.r.item_generics_num_type_or_const_params(def_id) > 0 + }); if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) { fallback = true; match self.diag_metadata.current_let_binding { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b7e57ad8ec37e..d1740decd92c8 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1499,6 +1499,8 @@ pub struct Resolver<'ra, 'tcx> { /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap = default::fx_hash_map(), + /// Amount of type or const parameters for each item in the crate. + item_generics_num_type_or_const_params: FxHashMap = default::fx_hash_map(), /// Generic args to suggest for required params (e.g. `<'_>`, `<_, _>`), if any. item_required_generic_args_suggestions: FxHashMap = default::fx_hash_map(), delegation_fn_sigs: LocalDefIdMap = Default::default(), @@ -1709,6 +1711,17 @@ impl<'tcx> Resolver<'_, 'tcx> { self.tcx.generics_of(def_id).own_counts().lifetimes } } + // Get count of expected parameters + fn item_generics_num_type_or_const_params(&self, def_id: DefId) -> usize { + if let Some(def_id) = def_id.as_local() { + self.item_generics_num_type_or_const_params.get(&def_id).copied().unwrap_or(0) + } else { + let generics = self.tcx.generics_of(def_id); + let counts = generics.own_counts(); + // saturating_sub may not be strictly necessary, better safe than sorry + counts.types.saturating_sub(generics.has_own_self() as usize) + counts.consts + } + } fn item_required_generic_args_suggestion(&self, def_id: DefId) -> String { if let Some(def_id) = def_id.as_local() { diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr index e087e046ec35d..14f80b6b1d71a 100644 --- a/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr @@ -2,16 +2,7 @@ error[E0425]: cannot find value `ERR` in this scope --> $DIR/unused_speculative_def_id.rs:20:16 | LL | field: A<{ ERR:: }>, - | ^^^ - | - --> $SRC_DIR/core/src/result.rs:LL:COL - | - = note: similarly named tuple variant `Err` defined here -help: a tuple variant with a similar name exists - | -LL - field: A<{ ERR:: }>, -LL + field: A<{ Err:: }>, - | + | ^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/imports/generic-param-filter.rs b/tests/ui/imports/generic-param-filter.rs new file mode 100644 index 0000000000000..288e5d9503560 --- /dev/null +++ b/tests/ui/imports/generic-param-filter.rs @@ -0,0 +1,4 @@ +fn test_cloned(_x: cloned<(), ()>){} +//~^ ERROR: cannot find type `cloned` in this scope + +fn main(){} diff --git a/tests/ui/imports/generic-param-filter.stderr b/tests/ui/imports/generic-param-filter.stderr new file mode 100644 index 0000000000000..8437aed28fd31 --- /dev/null +++ b/tests/ui/imports/generic-param-filter.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find type `cloned` in this scope + --> $DIR/generic-param-filter.rs:1:20 + | +LL | fn test_cloned(_x: cloned<(), ()>){} + | ^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`.