From 0ade480cd193d8b8c4729946e2610791e338c6d3 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:31:52 +0100 Subject: [PATCH 01/21] Fix unconstrained parameter issue --- compiler/rustc_hir/src/hir.rs | 55 +++++++ .../rustc_hir_analysis/src/impl_wf_check.rs | 140 +++++++++++++++++- 2 files changed, 192 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 45a363b97722a..e9261773b7fe2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1095,6 +1095,61 @@ impl<'hir> Generics<'hir> { bound_span.with_lo(bounds[bound_pos - 1].span().hi()) } } + + pub fn span_for_param_removal(&self, param_index: usize) -> Span { + if param_index >= self.params.len() { + return self.span.shrink_to_hi(); + } + + let is_impl_generic = |par: &&GenericParam<'_>| match par.kind { + GenericParamKind::Type { .. } + | GenericParamKind::Const { .. } + | GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit } => true, + _ => false, + }; + + // Find the span of the type parameter. + if let Some(next) = self.params[param_index + 1..].iter().find(is_impl_generic) { + self.params[param_index].span.until(next.span) + } else if let Some(prev) = self.params[..param_index].iter().rfind(is_impl_generic) { + let mut prev_span = prev.span; + // Consider the span of the bounds with the previous generic parameter when there is. + if let Some(prev_bounds_span) = self.span_for_param_bounds(prev) { + prev_span = prev_span.to(prev_bounds_span); + } + + // Consider the span of the bounds with the current generic parameter when there is. + prev_span.shrink_to_hi().to( + if let Some(cur_bounds_span) = self.span_for_param_bounds(&self.params[param_index]) + { + cur_bounds_span + } else { + self.params[param_index].span + }, + ) + } else { + // Remove also angle brackets <> when there is just ONE generic parameter. + self.span + } + } + + fn span_for_param_bounds(&self, param: &GenericParam<'hir>) -> Option { + self.predicates + .iter() + .find(|pred| { + if let WherePredicateKind::BoundPredicate(WhereBoundPredicate { + origin: PredicateOrigin::GenericParam, + bounded_ty, + .. + }) = pred.kind + { + bounded_ty.span == param.span + } else { + false + } + }) + .map(|pred| pred.span) + } } /// A single predicate in a where-clause. diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 57ee790170384..7d692ad20a8db 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -10,13 +10,18 @@ use std::debug_assert_matches; +use std::ops::ControlFlow; + use min_specialization::check_min_specialization; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::Applicability; use rustc_errors::codes::*; +use rustc_errors::{Applicability, Diag}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::{self, Visitor, walk_lifetime}; +use rustc_hir::{HirId, LifetimeKind, Path, QPath, Ty, TyKind}; +use rustc_middle::hir::nested_filter::All; +use rustc_middle::ty::{self, GenericParamDef, TyCtxt, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; @@ -172,6 +177,13 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( ); } } + suggest_to_remove_or_use_generic( + tcx, + &mut diag, + impl_def_id, + param, + "lifetime", + ); res = Err(diag.emit()); } } @@ -235,8 +247,130 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( const_param_note2: const_param_note, }); diag.code(E0207); + suggest_to_remove_or_use_generic(tcx, &mut diag, impl_def_id, ¶m, "type"); res = Err(diag.emit()); } } res } + +/// A HIR visitor that checks if a specific generic parameter (by its `DefId`) +/// is used within a given HIR tree. +struct ParamUsageVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + /// The `DefId` of the generic parameter we are looking for. + param_def_id: DefId, + found: bool, +} + +// todo: maybe this can be done more efficiently by only searching for generics OR lifetimes and searching more effectively +impl<'tcx> Visitor<'tcx> for ParamUsageVisitor<'tcx> { + type NestedFilter = All; + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx + } + + /// We use `ControlFlow` to stop visiting as soon as we find what we're looking for. + type Result = ControlFlow<()>; + + /// This is the primary method for finding usages of type or const parameters. + fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result { + if let Some(res_def_id) = path.res.opt_def_id() { + if res_def_id == self.param_def_id { + self.found = true; + return ControlFlow::Break(()); // Found it, stop visiting. + } + } + // If not found, continue walking down the HIR tree. + intravisit::walk_path(self, path) + } + + fn visit_lifetime(&mut self, lifetime: &'tcx rustc_hir::Lifetime) -> Self::Result { + if let LifetimeKind::Param(id) = lifetime.kind { + if let Some(local_def_id) = self.param_def_id.as_local() { + if id == local_def_id { + self.found = true; + return ControlFlow::Break(()); // Found it, stop visiting. + } + } + } + walk_lifetime(self, lifetime) + } +} + +fn suggest_to_remove_or_use_generic( + tcx: TyCtxt<'_>, + diag: &mut Diag<'_>, + impl_def_id: LocalDefId, + param: &GenericParamDef, + parameter_type: &str, +) { + let node = tcx.hir_node_by_def_id(impl_def_id); + let hir_impl = node.expect_item().expect_impl(); + + let Some((index, _)) = hir_impl + .generics + .params + .iter() + .enumerate() + .find(|(_, par)| par.def_id.to_def_id() == param.def_id) + else { + return; + }; + + // search if the parameter is used in the impl body + let mut visitor = ParamUsageVisitor { + tcx, // Pass the TyCtxt + param_def_id: param.def_id, + found: false, + }; + + for item_ref in hir_impl.items { + let _ = visitor.visit_impl_item_ref(item_ref); + if visitor.found { + break; + } + } + + let is_param_used = visitor.found; + + // Suggestion for removing the type parameter. + let mut suggestions = vec![]; + if !is_param_used { + // Only suggest removing it if it's not used anywhere. + suggestions.push(vec![(hir_impl.generics.span_for_param_removal(index), String::new())]); + } + + // Suggestion for making use of the type parameter. + if let Some(path) = extract_ty_as_path(hir_impl.self_ty) { + let seg = path.segments.last().unwrap(); + if let Some(args) = seg.args { + suggestions + .push(vec![(args.span().unwrap().shrink_to_hi(), format!(", {}", param.name))]); + } else { + suggestions.push(vec![(seg.ident.span.shrink_to_hi(), format!("<{}>", param.name))]); + } + } + + let msg = if is_param_used { + // If it's used, the only valid fix is to constrain it. + format!("make use of the {} parameter `{}` in the `self` type", parameter_type, param.name) + } else { + format!( + "either remove the unused {} parameter `{}`, or make use of it", + parameter_type, param.name + ) + }; + + diag.multipart_suggestions(msg, suggestions, Applicability::MaybeIncorrect); +} + +fn extract_ty_as_path<'hir>(ty: &Ty<'hir>) -> Option<&'hir Path<'hir>> { + match ty.kind { + TyKind::Path(QPath::Resolved(_, path)) => Some(path), + TyKind::Slice(ty) | TyKind::Array(ty, _) => extract_ty_as_path(ty), + TyKind::Ptr(ty) | TyKind::Ref(_, ty) => extract_ty_as_path(ty.ty), + _ => None, + } +} From a8a7e19ad40af57550ce91660635403890ef16c9 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:32:11 +0100 Subject: [PATCH 02/21] fix tests --- tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr index 55ab144b92419..e9966a7f5bec6 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Allocator for DefaultAllocator { | ^ unconstrained type parameter + | +help: either remove the type parameter T, or make use of it, for example + | +LL - impl Allocator for DefaultAllocator { +LL + impl Allocator for DefaultAllocator { + | +LL | impl Allocator for DefaultAllocator { + | +++ error: aborting due to 1 previous error From 12340a8ef69bff20f0720348ce2fc2139f29b3f8 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:40:43 +0100 Subject: [PATCH 03/21] fix rustdoc ui test --- .../unconstrained-param-in-impl-ambiguity.stderr | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr index 38d1a537fe458..f5c82f0851d63 100644 --- a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `Q` is not constrained by the impl trait, self | LL | unsafe impl Send for Inner {} | ^ unconstrained type parameter + | +help: either remove the type parameter Q, or make use of it, for example + | +LL - unsafe impl Send for Inner {} +LL + unsafe impl Send for Inner {} + | +LL | unsafe impl Send for Inner {} + | +++ error: aborting due to 1 previous error From 69165e1e793d2022ecc9aa6d9be7ca45c89ebeaf Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 15:16:39 +0100 Subject: [PATCH 04/21] fix tests --- ...hr-do-not-blame-outlives-static-ice.stderr | 5 +++ tests/ui/associated-types/issue-26262.stderr | 10 +++++ .../projection-dyn-associated-type.stderr | 1 + .../unconstrained-lifetime-assoc-type.stderr | 5 +++ .../in-trait/unconstrained-impl-region.stderr | 1 + .../issues/issue-78654.full.stderr | 7 ++++ .../async-await/issues/issue-78654.min.stderr | 7 ++++ .../unconstrained_impl_param.stderr | 6 +++ ...post-analysis-user-facing-param-env.stderr | 7 ++++ ...ice-unexpected-inference-var-122549.stderr | 4 ++ .../issues/issue-68366.full.stderr | 14 +++++++ .../issues/issue-68366.min.stderr | 14 +++++++ ...zing_with_unconstrained_impl_params.stderr | 4 ++ .../unconstrained_const_param_on_drop.stderr | 7 ++++ tests/ui/error-codes/E0207.stderr | 5 +++ .../bugs/issue-87735.stderr | 5 +++ .../bugs/issue-88526.stderr | 8 ++++ .../gat-trait-path-generic-type-arg.stderr | 8 ++++ ...nstrained-type-params-inherent-impl.stderr | 16 ++++++++ .../in-trait/refine-resolution-errors.stderr | 1 + .../in-trait/unconstrained-lt.stderr | 5 +++ tests/ui/impl-trait/issues/issue-87340.stderr | 6 +++ tests/ui/issues/issue-16562.stderr | 8 ++++ tests/ui/issues/issue-22886.stderr | 5 +++ tests/ui/issues/issue-29861.stderr | 5 +++ tests/ui/issues/issue-35139.stderr | 5 +++ .../unconstrained-param-ice-137308.stderr | 8 ++++ ...ined-params-in-impl-due-to-overflow.stderr | 8 ++++ .../unconstrained-params-in-impl.stderr | 8 ++++ .../missing-lifetime-in-assoc-type-1.stderr | 4 ++ .../missing-lifetime-in-assoc-type-5.stderr | 4 ++ .../missing-lifetime-in-assoc-type-6.stderr | 4 ++ ...ice-const-not-fully-resolved-113045.stderr | 6 +++ ...assoc-type-suggestion-in-trait-impl.stderr | 8 ++++ .../constrained-type-params-trait-impl.stderr | 37 +++++++++++++++++++ ...resolve-impl-before-constrain-check.stderr | 6 +++ ...-projection-normalization-2.current.stderr | 5 +++ ...ned-projection-normalization-2.next.stderr | 5 +++ ...ed-projection-normalization.current.stderr | 5 +++ ...ained-projection-normalization.next.stderr | 5 +++ .../assoc-type-lifetime-unconstrained.stderr | 5 +++ ...iled-to-resolve-instance-for-110696.stderr | 5 +++ .../impl-with-unconstrained-param.stderr | 6 +++ .../type-alias-impl-trait/issue-74244.stderr | 8 ++++ .../issue-74761-2.stderr | 12 ++++++ .../type-alias-impl-trait/issue-74761.stderr | 12 ++++++ ...s-impl-trait-unconstrained-lifetime.stderr | 6 +++ .../unconstrained-impl-param.stderr | 5 +++ tests/ui/typeck/issue-13853-5.stderr | 8 ++++ 49 files changed, 349 insertions(+) diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr index 4c0726d4ddca9..ca51b0de3422c 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr @@ -12,6 +12,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Foo { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Foo { + | ++++ error[E0308]: mismatched types --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 diff --git a/tests/ui/associated-types/issue-26262.stderr b/tests/ui/associated-types/issue-26262.stderr index 90e2d0d930164..bad72773bb023 100644 --- a/tests/ui/associated-types/issue-26262.stderr +++ b/tests/ui/associated-types/issue-26262.stderr @@ -3,12 +3,22 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl S { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl S { + | +++ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-26262.rs:17:6 | LL | impl<'a,T: Trait2<'a>> Trait1<>::Foo> for T { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a,T: Trait2<'a>> Trait1<>::Foo> for T<'a> { + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/projection-dyn-associated-type.stderr b/tests/ui/associated-types/projection-dyn-associated-type.stderr index 58eb8cff163db..fa0fc3d56beba 100644 --- a/tests/ui/associated-types/projection-dyn-associated-type.stderr +++ b/tests/ui/associated-types/projection-dyn-associated-type.stderr @@ -28,6 +28,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Mirror for A { | ^ unconstrained type parameter + | error[E0277]: the trait bound `(dyn B + 'static): Mirror` is not satisfied --> $DIR/projection-dyn-associated-type.rs:23:6 diff --git a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr index 15d0820c895dd..6e07e616ee959 100644 --- a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr +++ b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr @@ -3,6 +3,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Fun for Holder { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Fun for Holder<'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr index ef7e4ef0eb85f..cea923c6d0375 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr @@ -3,6 +3,7 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Actor for () { | ^^ unconstrained lifetime parameter + | error: aborting due to 1 previous error diff --git a/tests/ui/async-await/issues/issue-78654.full.stderr b/tests/ui/async-await/issues/issue-78654.full.stderr index 0d12a948c68bd..058aafb9610f9 100644 --- a/tests/ui/async-await/issues/issue-78654.full.stderr +++ b/tests/ui/async-await/issues/issue-78654.full.stderr @@ -12,6 +12,13 @@ LL | impl Foo { | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `H`, or make use of it + | +LL - impl Foo { +LL + impl Foo { + | +LL | impl Foo { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/issues/issue-78654.min.stderr b/tests/ui/async-await/issues/issue-78654.min.stderr index 0d12a948c68bd..058aafb9610f9 100644 --- a/tests/ui/async-await/issues/issue-78654.min.stderr +++ b/tests/ui/async-await/issues/issue-78654.min.stderr @@ -12,6 +12,13 @@ LL | impl Foo { | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `H`, or make use of it + | +LL - impl Foo { +LL + impl Foo { + | +LL | impl Foo { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr index c34674604b51d..b56057bb4d74e 100644 --- a/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr +++ b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr @@ -13,6 +13,12 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Trait for () where (U,): AssocConst {} | ^ unconstrained type parameter + | +help: either remove the unused type parameter `U`, or make use of it + | +LL - impl Trait for () where (U,): AssocConst {} +LL + impl Trait for () where (U,): AssocConst {} + | error[E0282]: type annotations needed --> $DIR/unconstrained_impl_param.rs:21:5 diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr index 37eb895f9a8d9..a8005c05b83ba 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr @@ -37,6 +37,13 @@ LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `NUM`, or make use of it + | +LL - impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo +LL + impl<'a> std::ops::Add<&'a Foo> for Foo + | +LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo + | +++++ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr b/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr index 311caaede09af..466d3ea6b4896 100644 --- a/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr +++ b/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr @@ -71,6 +71,10 @@ LL | impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, {}> { | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: make use of the type parameter `N` in the `self` type + | +LL | impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, {}, N> { + | +++ error: aborting due to 8 previous errors diff --git a/tests/ui/const-generics/issues/issue-68366.full.stderr b/tests/ui/const-generics/issues/issue-68366.full.stderr index caed3c1bf3f7d..f5e6adc38279b 100644 --- a/tests/ui/const-generics/issues/issue-68366.full.stderr +++ b/tests/ui/const-generics/issues/issue-68366.full.stderr @@ -18,6 +18,13 @@ LL | impl Collatz<{Some(N)}> {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `N`, or make use of it + | +LL - impl Collatz<{Some(N)}> {} +LL + impl Collatz<{Some(N)}> {} + | +LL | impl Collatz<{Some(N)}, N> {} + | +++ error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:19:6 @@ -27,6 +34,13 @@ LL | impl Foo {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `N`, or make use of it + | +LL - impl Foo {} +LL + impl Foo {} + | +LL | impl Foo {} + | +++ error: overly complex generic constant --> $DIR/issue-68366.rs:12:31 diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index 4d721e958cbc7..3645f9a86791f 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -27,6 +27,13 @@ LL | impl Collatz<{Some(N)}> {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `N`, or make use of it + | +LL - impl Collatz<{Some(N)}> {} +LL + impl Collatz<{Some(N)}> {} + | +LL | impl Collatz<{Some(N)}, N> {} + | +++ error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:19:6 @@ -36,6 +43,13 @@ LL | impl Foo {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `N`, or make use of it + | +LL - impl Foo {} +LL + impl Foo {} + | +LL | impl Foo {} + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr index ad89705e1dca8..8c4f0a8aad5e8 100644 --- a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr +++ b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr @@ -53,6 +53,10 @@ LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact< | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: make use of the type parameter `N` in the `self` type + | +LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}, N> { + | +++ error[E0308]: mismatched types --> $DIR/normalizing_with_unconstrained_impl_params.rs:6:27 diff --git a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr index 515637dd47fc3..cf795a6dee0f4 100644 --- a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr +++ b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr @@ -26,6 +26,13 @@ LL | impl Drop for Foo {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `UNUSED`, or make use of it + | +LL - impl Drop for Foo {} +LL + impl Drop for Foo {} + | +LL | impl Drop for Foo {} + | ++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/error-codes/E0207.stderr b/tests/ui/error-codes/E0207.stderr index 01d7c41854412..d29c8c8e66361 100644 --- a/tests/ui/error-codes/E0207.stderr +++ b/tests/ui/error-codes/E0207.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Foo { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Foo { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr index c3f4f7a73f35f..c87df9de07de3 100644 --- a/tests/ui/generic-associated-types/bugs/issue-87735.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl<'b, T, U> AsRef2 for Foo | ^ unconstrained type parameter + | +help: make use of the type parameter `U` in the `self` type + | +LL | impl<'b, T, U> AsRef2 for Foo + | +++ error[E0309]: the parameter type `U` may not live long enough --> $DIR/issue-87735.rs:34:3 diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.stderr b/tests/ui/generic-associated-types/bugs/issue-88526.stderr index 5e39eb7a6b95a..928f140310dfa 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88526.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `I` is not constrained by the impl trait, self | LL | impl<'q, Q, I, F> A for TestB | ^ unconstrained type parameter + | +help: either remove the unused type parameter `I`, or make use of it + | +LL - impl<'q, Q, I, F> A for TestB +LL + impl<'q, Q, F> A for TestB + | +LL | impl<'q, Q, I, F> A for TestB + | +++ error[E0309]: the parameter type `F` may not live long enough --> $DIR/issue-88526.rs:16:5 diff --git a/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr index 42aa83c8f43e4..e00f5edc23851 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr @@ -27,6 +27,14 @@ error[E0207]: the type parameter `T1` is not constrained by the impl trait, self | LL | impl Foo for T { | ^^ unconstrained type parameter + | +help: either remove the unused type parameter `T1`, or make use of it + | +LL - impl Foo for T { +LL + impl Foo for T { + | +LL | impl Foo for T { + | ++++ error: aborting due to 4 previous errors diff --git a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr index 19b02ad396cd3..bd2d8f7a7c487 100644 --- a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr +++ b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr @@ -3,12 +3,28 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl MyType { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl MyType { +LL + impl MyType { + | +LL | impl MyType { + | +++ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained-type-params-inherent-impl.rs:20:9 | LL | impl MyType1 { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `U`, or make use of it + | +LL - impl MyType1 { +LL + impl MyType1 { + | +LL | impl MyType1 { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr index af71e52b87d71..0c1347a34a49b 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr @@ -3,6 +3,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Mirror for () { | ^ unconstrained type parameter + | error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/refine-resolution-errors.rs:11:18 diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr index 3a4d90dfd4e8d..2c86ab91c236a 100644 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr @@ -21,6 +21,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, T> Foo for T { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a, T> Foo for T<'a> { + | ++++ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/impl-trait/issues/issue-87340.stderr b/tests/ui/impl-trait/issues/issue-87340.stderr index 8513cb2881e1f..c8c40680ae298 100644 --- a/tests/ui/impl-trait/issues/issue-87340.stderr +++ b/tests/ui/impl-trait/issues/issue-87340.stderr @@ -3,6 +3,12 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl X for () { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl X for () { +LL + impl X for () { + | error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-16562.stderr b/tests/ui/issues/issue-16562.stderr index efbd7f712a45a..83f4447aa26d0 100644 --- a/tests/ui/issues/issue-16562.stderr +++ b/tests/ui/issues/issue-16562.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Collection for Col { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl Collection for Col { +LL + impl Collection for Col { + | +LL | impl Collection for Col { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-22886.stderr b/tests/ui/issues/issue-22886.stderr index a04fa677f9ec5..cc5dbbce091ae 100644 --- a/tests/ui/issues/issue-22886.stderr +++ b/tests/ui/issues/issue-22886.stderr @@ -3,6 +3,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Iterator for Newtype { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Iterator for Newtype<'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-29861.stderr b/tests/ui/issues/issue-29861.stderr index a25cbf0515d84..303a7b7d7690b 100644 --- a/tests/ui/issues/issue-29861.stderr +++ b/tests/ui/issues/issue-29861.stderr @@ -3,6 +3,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, T: 'a> MakeRef2 for T { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a, T: 'a> MakeRef2 for T<'a> { + | ++++ error[E0716]: temporary value dropped while borrowed --> $DIR/issue-29861.rs:16:43 diff --git a/tests/ui/issues/issue-35139.stderr b/tests/ui/issues/issue-35139.stderr index 875af70483224..c402811c3b563 100644 --- a/tests/ui/issues/issue-35139.stderr +++ b/tests/ui/issues/issue-35139.stderr @@ -3,6 +3,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> MethodType for MTFn<'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 82cd1217c4903..f051df7e86415 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self | LL | impl A for u8 { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `C`, or make use of it + | +LL - impl A for u8 { +LL + impl A for u8 { + | +LL | impl A for u8 { + | +++ error[E0282]: type annotations needed --> $DIR/unconstrained-param-ice-137308.rs:18:16 diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr index d8270a0abddcd..6745f4a372a63 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Loop {} | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl Loop {} +LL + impl Loop {} + | +LL | impl Loop {} + | +++ error[E0275]: overflow normalizing the type alias `Loop` --> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:1 diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr index 2419c78cba8d9..868a9379f4a28 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl NotInjective {} | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl NotInjective {} +LL + impl NotInjective {} + | +LL | impl NotInjective {} + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index 3374c76bb76b9..033be9d20b659 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -24,6 +24,10 @@ help: consider using the named lifetime here instead of an implicit lifetime | LL | impl<'a> IntoIterator for &'a S { | ++ +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> IntoIterator for &S<'a> { + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr index d58fd8995ef9c..401b9deff4a40 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -25,6 +25,10 @@ help: consider using the named lifetime here instead of an implicit lifetime LL - impl<'a> IntoIterator for &'_ S { LL + impl<'a> IntoIterator for &'a S { | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> IntoIterator for &'_ S<'a> { + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr index 6767243bf21ba..7b89490af9fb2 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr @@ -24,6 +24,10 @@ help: consider using the named lifetime here instead of an implicit lifetime LL - impl<'a> Trait for &'_ S { LL + impl<'a> Trait for &'a S { | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Trait for &'_ S<'a> { + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr index acbdb9b0a308e..c2e7f2c1fcc3e 100644 --- a/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr +++ b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr @@ -3,6 +3,12 @@ error[E0207]: the type parameter `Unconstrained` is not constrained by the impl | LL | impl<'a, Unconstrained> X for [(); 0] {} | ^^^^^^^^^^^^^ unconstrained type parameter + | +help: either remove the unused type parameter `Unconstrained`, or make use of it + | +LL - impl<'a, Unconstrained> X for [(); 0] {} +LL + impl<'a> X for [(); 0] {} + | error: specialization impl does not specialize any associated items --> $DIR/ice-const-not-fully-resolved-113045.rs:11:1 diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr index 54c0cf8ebee91..444563b9dfc5e 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr @@ -15,6 +15,14 @@ error[E0207]: the type parameter `S` is not constrained by the impl trait, self | LL | impl Trait for i32 { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `S`, or make use of it + | +LL - impl Trait for i32 { +LL + impl Trait for i32 { + | +LL | impl Trait for i32 { + | +++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:12 diff --git a/tests/ui/traits/constrained-type-params-trait-impl.stderr b/tests/ui/traits/constrained-type-params-trait-impl.stderr index e59fad6e72db1..0e2284f7dbc7d 100644 --- a/tests/ui/traits/constrained-type-params-trait-impl.stderr +++ b/tests/ui/traits/constrained-type-params-trait-impl.stderr @@ -34,6 +34,14 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Foo for [isize; 1] { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `U`, or make use of it + | +LL - impl Foo for [isize; 1] { +LL + impl Foo for [isize; 1] { + | +LL | impl Foo for [isize; 1] { + | +++ error[E0119]: conflicting implementations of trait `Bar` --> $DIR/constrained-type-params-trait-impl.rs:48:1 @@ -51,24 +59,53 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Bar for T { | ^ unconstrained type parameter + | +help: make use of the type parameter `U` in the `self` type + | +LL | impl Bar for T { + | +++ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/constrained-type-params-trait-impl.rs:48:9 | LL | impl Bar for T | ^ unconstrained type parameter + | +help: either remove the unused type parameter `U`, or make use of it + | +LL - impl Bar for T +LL + impl Bar for T + | +LL | impl Bar for T + | +++ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/constrained-type-params-trait-impl.rs:57:9 | LL | impl Foo for T | ^ unconstrained type parameter + | +help: either remove the unused type parameter `U`, or make use of it + | +LL - impl Foo for T +LL + impl Foo for T + | +LL | impl Foo for T + | +++ error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates --> $DIR/constrained-type-params-trait-impl.rs:57:12 | LL | impl Foo for T | ^ unconstrained type parameter + | +help: either remove the unused type parameter `V`, or make use of it + | +LL - impl Foo for T +LL + impl Foo for T + | +LL | impl Foo for T + | +++ error: aborting due to 9 previous errors diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index 13fbfdb855cbf..e087aec07c9ca 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -3,6 +3,12 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self | LL | impl Callable for () { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `V`, or make use of it + | +LL - impl Callable for () { +LL + impl Callable for () { + | error[E0282]: type annotations needed --> $DIR/resolve-impl-before-constrain-check.rs:17:6 diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 9ce0e8d957dab..6d15d4bf29c9f 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization-2.rs:16:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 2da655afa935c..1522efe97e5ec 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization-2.rs:16:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization.current.stderr b/tests/ui/traits/unconstrained-projection-normalization.current.stderr index c52e8dd68aa87..d6fd9817676f5 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.current.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization.rs:15:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index c52e8dd68aa87..d6fd9817676f5 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization.rs:15:18 diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr index e6b94c525ff23..08060ee467766 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr +++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr @@ -3,6 +3,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, I> UnwrapItemsExt for I { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a, I> UnwrapItemsExt for I<'a> { + | ++++ error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/assoc-type-lifetime-unconstrained.rs:22:9 diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr index d18a824287c0c..236b72d3ef3c5 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr @@ -3,6 +3,11 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl>>, U> MyIndex> for Scope { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl>>, U> MyIndex> for Scope { + | +++ error: item does not constrain `DummyT::{opaque#0}` --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:30:8 diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr index 137a4db81b563..5f686c5b0a3c5 100644 --- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr +++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -3,6 +3,12 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl X for () { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl X for () { +LL + impl X for () { + | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr index f5ca56bacccf6..0bbad183afa2a 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr @@ -3,6 +3,14 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Allocator for DefaultAllocator { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl Allocator for DefaultAllocator { +LL + impl Allocator for DefaultAllocator { + | +LL | impl Allocator for DefaultAllocator { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr index 26babc29000c0..1869354320a41 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -3,12 +3,24 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter + | +help: either remove the unused lifetime parameter `'a`, or make use of it + | +LL - impl<'a, 'b> A for () { +LL + impl<'b> A for () { + | error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-74761-2.rs:7:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter + | +help: either remove the unused lifetime parameter `'b`, or make use of it + | +LL - impl<'a, 'b> A for () { +LL + impl<'a> A for () { + | error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/issue-74761-2.rs:12:28 diff --git a/tests/ui/type-alias-impl-trait/issue-74761.stderr b/tests/ui/type-alias-impl-trait/issue-74761.stderr index a4826c293467e..6d2aa1d695cf9 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761.stderr @@ -3,12 +3,24 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter + | +help: either remove the unused lifetime parameter `'a`, or make use of it + | +LL - impl<'a, 'b> A for () { +LL + impl<'b> A for () { + | error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-74761.rs:7:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter + | +help: either remove the unused lifetime parameter `'b`, or make use of it + | +LL - impl<'a, 'b> A for () { +LL + impl<'a> A for () { + | error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/issue-74761.rs:12:28 diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr index 5f9c56f1ca9d0..6a8adb2c8a5ac 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr @@ -3,6 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, I: Iterator> Trait for (i32, I) { | ^^ unconstrained lifetime parameter + | +help: either remove the unused lifetime parameter `'a`, or make use of it + | +LL - impl<'a, I: Iterator> Trait for (i32, I) { +LL + impl> Trait for (i32, I) { + | error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:14:9 diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr index 7a86685787ced..849f5059d1c54 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr @@ -3,6 +3,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Trait for Opaque<&'a str> { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Trait for Opaque<&'a str, 'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/issue-13853-5.stderr b/tests/ui/typeck/issue-13853-5.stderr index bb967b07b816f..2df273877b5f0 100644 --- a/tests/ui/typeck/issue-13853-5.stderr +++ b/tests/ui/typeck/issue-13853-5.stderr @@ -12,6 +12,14 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl<'a, T: Deserializable> Deserializable for &'a str { | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T`, or make use of it + | +LL - impl<'a, T: Deserializable> Deserializable for &'a str { +LL + impl<'a> Deserializable for &'a str { + | +LL | impl<'a, T: Deserializable> Deserializable for &'a str { + | +++ error[E0308]: mismatched types --> $DIR/issue-13853-5.rs:9:70 From e7d4c8a0edd455718a39243272dc6d61325238d6 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 18:02:24 +0100 Subject: [PATCH 05/21] fix tests (added the help messages in the code too) --- tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs | 1 + tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs | 1 + tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs | 1 + tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr | 2 +- 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs index 3d02d1bb1bd80..8537c385dc336 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -6,6 +6,7 @@ impl<'a> IntoIterator for &S { //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime + //~| HELP make use of the lifetime parameter `'a` in the `self` type type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index 033be9d20b659..ce260201d31b9 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -1,5 +1,5 @@ error: missing lifetime in associated type - --> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17 + --> $DIR/missing-lifetime-in-assoc-type-1.rs:10:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs index 853cc6dc8e4e9..e55f0f0321059 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs @@ -6,6 +6,7 @@ impl<'a> IntoIterator for &'_ S { //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime + //~| HELP make use of the lifetime parameter `'a` in the `self` type type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr index 401b9deff4a40..d1e7a03c6592e 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -1,5 +1,5 @@ error: missing lifetime in associated type - --> $DIR/missing-lifetime-in-assoc-type-5.rs:9:17 + --> $DIR/missing-lifetime-in-assoc-type-5.rs:10:17 | LL | impl<'a> IntoIterator for &'_ S { | ---- there is a named lifetime specified on the impl block you could use diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs index b4fac575edb3b..66af9529ddea7 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs @@ -13,6 +13,7 @@ impl<'a> Trait for &'_ S { //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime + //~| HELP make use of the lifetime parameter `'a` in the `self` type type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr index 7b89490af9fb2..4a3bc044f1f23 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr @@ -1,5 +1,5 @@ error: missing lifetime in associated type - --> $DIR/missing-lifetime-in-assoc-type-6.rs:16:17 + --> $DIR/missing-lifetime-in-assoc-type-6.rs:17:17 | LL | impl<'a> Trait for &'_ S { | ---- there is a named lifetime specified on the impl block you could use From 1065e84b4eb2ea72e58ee71c09fb9853205d5fa0 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 23:17:32 +0100 Subject: [PATCH 06/21] fixed tests (hope the last time) --- tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr | 2 +- .../unconstrained-param-in-impl-ambiguity.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr index e9966a7f5bec6..481be46d39485 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -4,7 +4,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl Allocator for DefaultAllocator { | ^ unconstrained type parameter | -help: either remove the type parameter T, or make use of it, for example +help: either remove the unused type parameter `T`, or make use of it | LL - impl Allocator for DefaultAllocator { LL + impl Allocator for DefaultAllocator { diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr index f5c82f0851d63..801b38c6f415f 100644 --- a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr @@ -4,7 +4,7 @@ error[E0207]: the type parameter `Q` is not constrained by the impl trait, self LL | unsafe impl Send for Inner {} | ^ unconstrained type parameter | -help: either remove the type parameter Q, or make use of it, for example +help: either remove the unused type parameter `Q`, or make use of it | LL - unsafe impl Send for Inner {} LL + unsafe impl Send for Inner {} From 3d490897bcc323c6ba720d0d15f2abab85900c81 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 12 Nov 2025 14:35:12 +0100 Subject: [PATCH 07/21] prepared the search for the generics in the impl and struct definitions to determine if it makes sense to suggest adding the extra parameter to the generics of the struct on the impl ... for ...<> line --- .../rustc_hir_analysis/src/impl_wf_check.rs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 7d692ad20a8db..ebba922081b40 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -26,6 +26,7 @@ use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; use crate::errors::UnconstrainedGenericParameter; +use crate::hir::def::Res; mod min_specialization; @@ -254,8 +255,7 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( res } -/// A HIR visitor that checks if a specific generic parameter (by its `DefId`) -/// is used within a given HIR tree. +/// Use a Visitor to find usages of the type or lifetime parameter struct ParamUsageVisitor<'tcx> { tcx: TyCtxt<'tcx>, /// The `DefId` of the generic parameter we are looking for. @@ -271,10 +271,8 @@ impl<'tcx> Visitor<'tcx> for ParamUsageVisitor<'tcx> { self.tcx } - /// We use `ControlFlow` to stop visiting as soon as we find what we're looking for. type Result = ControlFlow<()>; - /// This is the primary method for finding usages of type or const parameters. fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result { if let Some(res_def_id) = path.res.opt_def_id() { if res_def_id == self.param_def_id { @@ -319,12 +317,25 @@ fn suggest_to_remove_or_use_generic( return; }; - // search if the parameter is used in the impl body - let mut visitor = ParamUsageVisitor { - tcx, // Pass the TyCtxt - param_def_id: param.def_id, - found: false, + // get the struct_def_id from the self type + let Some(struct_def_id) = (|| { + let ty = hir_impl.self_ty; + if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind + && let Res::Def(_, def_id) = path.res + { + Some(def_id) + } else { + None + } + })() else { + return; }; + let generics = tcx.generics_of(struct_def_id); + // println!("number of struct generics: {}", generics.own_params.len()); + // println!("number of impl generics: {}", hir_impl.generics.params.len()); + + // search if the parameter is used in the impl body + let mut visitor = ParamUsageVisitor { tcx, param_def_id: param.def_id, found: false }; for item_ref in hir_impl.items { let _ = visitor.visit_impl_item_ref(item_ref); From bf798a357acabc020517656604e8b88e09fc4b08 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Thu, 5 Mar 2026 16:11:13 +1300 Subject: [PATCH 08/21] first check if the struct Foo has a missing generic parameter --- .../rustc_hir_analysis/src/impl_wf_check.rs | 91 +++++++++++++------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index ebba922081b40..c9033452e7378 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -19,9 +19,9 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor, walk_lifetime}; -use rustc_hir::{HirId, LifetimeKind, Path, QPath, Ty, TyKind}; +use rustc_hir::{GenericArg, HirId, LifetimeKind, Path, QPath, TyKind}; use rustc_middle::hir::nested_filter::All; -use rustc_middle::ty::{self, GenericParamDef, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, GenericParamDef, GenericParamDefKind, TyCtxt, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; @@ -317,11 +317,10 @@ fn suggest_to_remove_or_use_generic( return; }; - // get the struct_def_id from the self type + // Get the Struct/ADT definition ID from the self type let Some(struct_def_id) = (|| { - let ty = hir_impl.self_ty; - if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind - && let Res::Def(_, def_id) = path.res + if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind + && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, def_id) = path.res { Some(def_id) } else { @@ -330,42 +329,80 @@ fn suggest_to_remove_or_use_generic( })() else { return; }; + + // Count how many slots are DEFINED in the struct (N) let generics = tcx.generics_of(struct_def_id); - // println!("number of struct generics: {}", generics.own_params.len()); - // println!("number of impl generics: {}", hir_impl.generics.params.len()); + let total_slots = generics + .own_params + .iter() + .filter(|p| { + if parameter_type == "lifetime" { + matches!(p.kind, GenericParamDefKind::Lifetime) + } else { + matches!(p.kind, GenericParamDefKind::Type { .. }) + } + }) + .count(); + + // Count how many arguments are CURRENTLY PROVIDED in the impl (J) + let mut provided_slots = 0; + let mut last_segment_args = None; + + if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind { + if let Some(seg) = path.segments.last() { + if let Some(args) = seg.args { + last_segment_args = Some(args); + provided_slots = args + .args + .iter() + .filter(|arg| { + if parameter_type == "lifetime" { + matches!(arg, GenericArg::Lifetime(_)) + } else { + matches!(arg, GenericArg::Type(_)) + } + }) + .count(); + } + } + } - // search if the parameter is used in the impl body + // Determine if the parameter is used in the impl body let mut visitor = ParamUsageVisitor { tcx, param_def_id: param.def_id, found: false }; - for item_ref in hir_impl.items { let _ = visitor.visit_impl_item_ref(item_ref); if visitor.found { break; } } - let is_param_used = visitor.found; - // Suggestion for removing the type parameter. + // Build Suggestions let mut suggestions = vec![]; + + // Option A: Remove (Only if not used in body) if !is_param_used { - // Only suggest removing it if it's not used anywhere. suggestions.push(vec![(hir_impl.generics.span_for_param_removal(index), String::new())]); } - // Suggestion for making use of the type parameter. - if let Some(path) = extract_ty_as_path(hir_impl.self_ty) { - let seg = path.segments.last().unwrap(); - if let Some(args) = seg.args { + // Option B: Suggest adding only if there's an available slot + if provided_slots < total_slots { + if let Some(args) = last_segment_args { + // Struct already has <...>, append to it suggestions .push(vec![(args.span().unwrap().shrink_to_hi(), format!(", {}", param.name))]); - } else { + } else if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind { + // Struct has no <...> yet, add it + let seg = path.segments.last().unwrap(); suggestions.push(vec![(seg.ident.span.shrink_to_hi(), format!("<{}>", param.name))]); } } + if suggestions.is_empty() { + return; + } + let msg = if is_param_used { - // If it's used, the only valid fix is to constrain it. format!("make use of the {} parameter `{}` in the `self` type", parameter_type, param.name) } else { format!( @@ -377,11 +414,11 @@ fn suggest_to_remove_or_use_generic( diag.multipart_suggestions(msg, suggestions, Applicability::MaybeIncorrect); } -fn extract_ty_as_path<'hir>(ty: &Ty<'hir>) -> Option<&'hir Path<'hir>> { - match ty.kind { - TyKind::Path(QPath::Resolved(_, path)) => Some(path), - TyKind::Slice(ty) | TyKind::Array(ty, _) => extract_ty_as_path(ty), - TyKind::Ptr(ty) | TyKind::Ref(_, ty) => extract_ty_as_path(ty.ty), - _ => None, - } -} +// fn extract_ty_as_path<'hir>(ty: &Ty<'hir>) -> Option<&'hir Path<'hir>> { +// match ty.kind { +// TyKind::Path(QPath::Resolved(_, path)) => Some(path), +// TyKind::Slice(ty) | TyKind::Array(ty, _) => extract_ty_as_path(ty), +// TyKind::Ptr(ty) | TyKind::Ref(_, ty) => extract_ty_as_path(ty.ty), +// _ => None, +// } +// } From 179940d1441d3bed42e02bc27e5ac954f912e674 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Thu, 5 Mar 2026 16:22:38 +1300 Subject: [PATCH 09/21] adapted test outputs --- tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr | 2 -- .../unconstrained-param-in-impl-ambiguity.stderr | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr index 481be46d39485..62bfb8617b781 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -9,8 +9,6 @@ help: either remove the unused type parameter `T`, or make use of it LL - impl Allocator for DefaultAllocator { LL + impl Allocator for DefaultAllocator { | -LL | impl Allocator for DefaultAllocator { - | +++ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr index 801b38c6f415f..c34607f8773c0 100644 --- a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr @@ -9,8 +9,6 @@ help: either remove the unused type parameter `Q`, or make use of it LL - unsafe impl Send for Inner {} LL + unsafe impl Send for Inner {} | -LL | unsafe impl Send for Inner {} - | +++ error: aborting due to 1 previous error From 9d1025ba2b5424d495c78d475a64f81962963eb3 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Fri, 6 Mar 2026 20:14:27 +1300 Subject: [PATCH 10/21] fixed tests --- .../rustc_hir_analysis/src/impl_wf_check.rs | 10 +++++ ...hr-do-not-blame-outlives-static-ice.stderr | 5 --- tests/ui/associated-types/issue-26262.stderr | 10 ----- .../projection-dyn-associated-type.stderr | 1 - .../unconstrained-lifetime-assoc-type.stderr | 5 --- .../in-trait/unconstrained-impl-region.stderr | 1 - .../issues/issue-78654.full.stderr | 2 - .../async-await/issues/issue-78654.min.stderr | 2 - .../unsized-anon-const-err-2.stderr | 10 +++++ .../unconstrained_impl_param.stderr | 6 --- ...post-analysis-user-facing-param-env.stderr | 2 - ...ice-unexpected-inference-var-122549.stderr | 4 -- .../issues/issue-68366.full.stderr | 4 -- .../issues/issue-68366.min.stderr | 4 -- ...zing_with_unconstrained_impl_params.stderr | 4 -- .../unconstrained_const_param_on_drop.stderr | 2 - tests/ui/error-codes/E0207.stderr | 5 --- .../bugs/issue-87735.stderr | 5 --- .../bugs/issue-88526.stderr | 2 - .../gat-trait-path-generic-type-arg.stderr | 8 ---- ...nstrained-type-params-inherent-impl.stderr | 4 -- .../in-trait/refine-resolution-errors.stderr | 1 - .../in-trait/unconstrained-lt.stderr | 5 --- tests/ui/impl-trait/issues/issue-87340.stderr | 6 --- tests/ui/issues/issue-16562.stderr | 2 - tests/ui/issues/issue-22886.stderr | 5 --- tests/ui/issues/issue-29861.stderr | 5 --- tests/ui/issues/issue-35139.stderr | 5 --- .../unconstrained-param-ice-137308.stderr | 8 ---- ...ined-params-in-impl-due-to-overflow.stderr | 8 ---- .../unconstrained-params-in-impl.stderr | 8 ---- .../missing-lifetime-in-assoc-type-1.rs | 1 - .../missing-lifetime-in-assoc-type-1.stderr | 6 +-- .../missing-lifetime-in-assoc-type-5.rs | 1 - .../missing-lifetime-in-assoc-type-5.stderr | 6 +-- .../missing-lifetime-in-assoc-type-6.rs | 1 - .../missing-lifetime-in-assoc-type-6.stderr | 6 +-- ...ice-const-not-fully-resolved-113045.stderr | 6 --- ...assoc-type-suggestion-in-trait-impl.stderr | 8 ---- .../constrained-type-params-trait-impl.stderr | 37 ------------------- .../leaking-vars-in-cause-code-2.stderr | 6 +++ ...resolve-impl-before-constrain-check.stderr | 6 --- ...-projection-normalization-2.current.stderr | 5 --- ...ned-projection-normalization-2.next.stderr | 5 --- ...ed-projection-normalization.current.stderr | 5 --- ...ained-projection-normalization.next.stderr | 5 --- .../assoc-type-lifetime-unconstrained.stderr | 5 --- ...iled-to-resolve-instance-for-110696.stderr | 5 --- .../impl-with-unconstrained-param.stderr | 6 --- .../type-alias-impl-trait/issue-74244.stderr | 2 - .../issue-74761-2.stderr | 12 ------ .../type-alias-impl-trait/issue-74761.stderr | 12 ------ ...s-impl-trait-unconstrained-lifetime.stderr | 6 --- .../unconstrained-impl-param.stderr | 5 --- tests/ui/typeck/issue-13853-5.stderr | 8 ---- 55 files changed, 29 insertions(+), 285 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index c9033452e7378..05ea25181dcfe 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -383,6 +383,16 @@ fn suggest_to_remove_or_use_generic( // Option A: Remove (Only if not used in body) if !is_param_used { suggestions.push(vec![(hir_impl.generics.span_for_param_removal(index), String::new())]); + } else { + // there could be a case where the parameter is used in the body, but the self type is still missing the generic argument, so we want to suggest adding it in that case as well + // e.g. + // ``` + // struct S; + // impl<'a> S { + // fn foo(&self) -> &'a str { "" } + // } + // ``` + // in such a case we could make the suggestion to add 'a to S in the `sturct S` definition and the `impl S` definition } // Option B: Suggest adding only if there's an available slot diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr index ca51b0de3422c..4c0726d4ddca9 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr @@ -12,11 +12,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Foo { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> Foo { - | ++++ error[E0308]: mismatched types --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 diff --git a/tests/ui/associated-types/issue-26262.stderr b/tests/ui/associated-types/issue-26262.stderr index bad72773bb023..90e2d0d930164 100644 --- a/tests/ui/associated-types/issue-26262.stderr +++ b/tests/ui/associated-types/issue-26262.stderr @@ -3,22 +3,12 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl S { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl S { - | +++ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-26262.rs:17:6 | LL | impl<'a,T: Trait2<'a>> Trait1<>::Foo> for T { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a,T: Trait2<'a>> Trait1<>::Foo> for T<'a> { - | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/projection-dyn-associated-type.stderr b/tests/ui/associated-types/projection-dyn-associated-type.stderr index fa0fc3d56beba..58eb8cff163db 100644 --- a/tests/ui/associated-types/projection-dyn-associated-type.stderr +++ b/tests/ui/associated-types/projection-dyn-associated-type.stderr @@ -28,7 +28,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Mirror for A { | ^ unconstrained type parameter - | error[E0277]: the trait bound `(dyn B + 'static): Mirror` is not satisfied --> $DIR/projection-dyn-associated-type.rs:23:6 diff --git a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr index 6e07e616ee959..15d0820c895dd 100644 --- a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr +++ b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr @@ -3,11 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Fun for Holder { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> Fun for Holder<'a> { - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr index cea923c6d0375..ef7e4ef0eb85f 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr @@ -3,7 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Actor for () { | ^^ unconstrained lifetime parameter - | error: aborting due to 1 previous error diff --git a/tests/ui/async-await/issues/issue-78654.full.stderr b/tests/ui/async-await/issues/issue-78654.full.stderr index 058aafb9610f9..30b19b0a2e29b 100644 --- a/tests/ui/async-await/issues/issue-78654.full.stderr +++ b/tests/ui/async-await/issues/issue-78654.full.stderr @@ -17,8 +17,6 @@ help: either remove the unused type parameter `H`, or make use of it LL - impl Foo { LL + impl Foo { | -LL | impl Foo { - | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/issues/issue-78654.min.stderr b/tests/ui/async-await/issues/issue-78654.min.stderr index 058aafb9610f9..30b19b0a2e29b 100644 --- a/tests/ui/async-await/issues/issue-78654.min.stderr +++ b/tests/ui/async-await/issues/issue-78654.min.stderr @@ -17,8 +17,6 @@ help: either remove the unused type parameter `H`, or make use of it LL - impl Foo { LL + impl Foo { | -LL | impl Foo { - | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr index d538bb0af09aa..99e6cf77b533f 100644 --- a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr @@ -50,6 +50,11 @@ LL | impl Copy for S {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `N`, or make use of it + | +LL - impl Copy for S {} +LL + impl Copy for S {} + | error[E0207]: the const parameter `M` is not constrained by the impl trait, self type, or predicates --> $DIR/unsized-anon-const-err-2.rs:17:6 @@ -59,6 +64,11 @@ LL | impl Copy for S {} | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: either remove the unused type parameter `M`, or make use of it + | +LL - impl Copy for S {} +LL + impl Copy for S {} + | error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr index b56057bb4d74e..c34674604b51d 100644 --- a/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr +++ b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr @@ -13,12 +13,6 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Trait for () where (U,): AssocConst {} | ^ unconstrained type parameter - | -help: either remove the unused type parameter `U`, or make use of it - | -LL - impl Trait for () where (U,): AssocConst {} -LL + impl Trait for () where (U,): AssocConst {} - | error[E0282]: type annotations needed --> $DIR/unconstrained_impl_param.rs:21:5 diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr index a8005c05b83ba..7814a1888c040 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr @@ -42,8 +42,6 @@ help: either remove the unused type parameter `NUM`, or make use of it LL - impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo LL + impl<'a> std::ops::Add<&'a Foo> for Foo | -LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo - | +++++ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr b/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr index 466d3ea6b4896..311caaede09af 100644 --- a/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr +++ b/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr @@ -71,10 +71,6 @@ LL | impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, {}> { | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: make use of the type parameter `N` in the `self` type - | -LL | impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, {}, N> { - | +++ error: aborting due to 8 previous errors diff --git a/tests/ui/const-generics/issues/issue-68366.full.stderr b/tests/ui/const-generics/issues/issue-68366.full.stderr index f5e6adc38279b..a242f89846121 100644 --- a/tests/ui/const-generics/issues/issue-68366.full.stderr +++ b/tests/ui/const-generics/issues/issue-68366.full.stderr @@ -23,8 +23,6 @@ help: either remove the unused type parameter `N`, or make use of it LL - impl Collatz<{Some(N)}> {} LL + impl Collatz<{Some(N)}> {} | -LL | impl Collatz<{Some(N)}, N> {} - | +++ error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:19:6 @@ -39,8 +37,6 @@ help: either remove the unused type parameter `N`, or make use of it LL - impl Foo {} LL + impl Foo {} | -LL | impl Foo {} - | +++ error: overly complex generic constant --> $DIR/issue-68366.rs:12:31 diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index 3645f9a86791f..c53ebbcf33a49 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -32,8 +32,6 @@ help: either remove the unused type parameter `N`, or make use of it LL - impl Collatz<{Some(N)}> {} LL + impl Collatz<{Some(N)}> {} | -LL | impl Collatz<{Some(N)}, N> {} - | +++ error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:19:6 @@ -48,8 +46,6 @@ help: either remove the unused type parameter `N`, or make use of it LL - impl Foo {} LL + impl Foo {} | -LL | impl Foo {} - | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr index 8c4f0a8aad5e8..ad89705e1dca8 100644 --- a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr +++ b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr @@ -53,10 +53,6 @@ LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact< | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: make use of the type parameter `N` in the `self` type - | -LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}, N> { - | +++ error[E0308]: mismatched types --> $DIR/normalizing_with_unconstrained_impl_params.rs:6:27 diff --git a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr index cf795a6dee0f4..63a8d8680643f 100644 --- a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr +++ b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr @@ -31,8 +31,6 @@ help: either remove the unused type parameter `UNUSED`, or make use of it LL - impl Drop for Foo {} LL + impl Drop for Foo {} | -LL | impl Drop for Foo {} - | ++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/error-codes/E0207.stderr b/tests/ui/error-codes/E0207.stderr index d29c8c8e66361..01d7c41854412 100644 --- a/tests/ui/error-codes/E0207.stderr +++ b/tests/ui/error-codes/E0207.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Foo { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl Foo { - | +++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr index c87df9de07de3..c3f4f7a73f35f 100644 --- a/tests/ui/generic-associated-types/bugs/issue-87735.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl<'b, T, U> AsRef2 for Foo | ^ unconstrained type parameter - | -help: make use of the type parameter `U` in the `self` type - | -LL | impl<'b, T, U> AsRef2 for Foo - | +++ error[E0309]: the parameter type `U` may not live long enough --> $DIR/issue-87735.rs:34:3 diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.stderr b/tests/ui/generic-associated-types/bugs/issue-88526.stderr index 928f140310dfa..d391bbb496c73 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88526.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr @@ -9,8 +9,6 @@ help: either remove the unused type parameter `I`, or make use of it LL - impl<'q, Q, I, F> A for TestB LL + impl<'q, Q, F> A for TestB | -LL | impl<'q, Q, I, F> A for TestB - | +++ error[E0309]: the parameter type `F` may not live long enough --> $DIR/issue-88526.rs:16:5 diff --git a/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr index e00f5edc23851..42aa83c8f43e4 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr @@ -27,14 +27,6 @@ error[E0207]: the type parameter `T1` is not constrained by the impl trait, self | LL | impl Foo for T { | ^^ unconstrained type parameter - | -help: either remove the unused type parameter `T1`, or make use of it - | -LL - impl Foo for T { -LL + impl Foo for T { - | -LL | impl Foo for T { - | ++++ error: aborting due to 4 previous errors diff --git a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr index bd2d8f7a7c487..64b7d742aebff 100644 --- a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr +++ b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr @@ -9,8 +9,6 @@ help: either remove the unused type parameter `T`, or make use of it LL - impl MyType { LL + impl MyType { | -LL | impl MyType { - | +++ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained-type-params-inherent-impl.rs:20:9 @@ -23,8 +21,6 @@ help: either remove the unused type parameter `U`, or make use of it LL - impl MyType1 { LL + impl MyType1 { | -LL | impl MyType1 { - | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr index 0c1347a34a49b..af71e52b87d71 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr @@ -3,7 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Mirror for () { | ^ unconstrained type parameter - | error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/refine-resolution-errors.rs:11:18 diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr index 2c86ab91c236a..3a4d90dfd4e8d 100644 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr @@ -21,11 +21,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, T> Foo for T { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a, T> Foo for T<'a> { - | ++++ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/impl-trait/issues/issue-87340.stderr b/tests/ui/impl-trait/issues/issue-87340.stderr index c8c40680ae298..8513cb2881e1f 100644 --- a/tests/ui/impl-trait/issues/issue-87340.stderr +++ b/tests/ui/impl-trait/issues/issue-87340.stderr @@ -3,12 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl X for () { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl X for () { -LL + impl X for () { - | error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-16562.stderr b/tests/ui/issues/issue-16562.stderr index 83f4447aa26d0..2e73df9f2076e 100644 --- a/tests/ui/issues/issue-16562.stderr +++ b/tests/ui/issues/issue-16562.stderr @@ -9,8 +9,6 @@ help: either remove the unused type parameter `T`, or make use of it LL - impl Collection for Col { LL + impl Collection for Col { | -LL | impl Collection for Col { - | +++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-22886.stderr b/tests/ui/issues/issue-22886.stderr index cc5dbbce091ae..a04fa677f9ec5 100644 --- a/tests/ui/issues/issue-22886.stderr +++ b/tests/ui/issues/issue-22886.stderr @@ -3,11 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Iterator for Newtype { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> Iterator for Newtype<'a> { - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-29861.stderr b/tests/ui/issues/issue-29861.stderr index 303a7b7d7690b..a25cbf0515d84 100644 --- a/tests/ui/issues/issue-29861.stderr +++ b/tests/ui/issues/issue-29861.stderr @@ -3,11 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, T: 'a> MakeRef2 for T { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a, T: 'a> MakeRef2 for T<'a> { - | ++++ error[E0716]: temporary value dropped while borrowed --> $DIR/issue-29861.rs:16:43 diff --git a/tests/ui/issues/issue-35139.stderr b/tests/ui/issues/issue-35139.stderr index c402811c3b563..875af70483224 100644 --- a/tests/ui/issues/issue-35139.stderr +++ b/tests/ui/issues/issue-35139.stderr @@ -3,11 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> MethodType for MTFn<'a> { - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index f051df7e86415..82cd1217c4903 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -3,14 +3,6 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self | LL | impl A for u8 { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `C`, or make use of it - | -LL - impl A for u8 { -LL + impl A for u8 { - | -LL | impl A for u8 { - | +++ error[E0282]: type annotations needed --> $DIR/unconstrained-param-ice-137308.rs:18:16 diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr index 6745f4a372a63..d8270a0abddcd 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr @@ -3,14 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Loop {} | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl Loop {} -LL + impl Loop {} - | -LL | impl Loop {} - | +++ error[E0275]: overflow normalizing the type alias `Loop` --> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:1 diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr index 868a9379f4a28..2419c78cba8d9 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl.stderr @@ -3,14 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl NotInjective {} | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl NotInjective {} -LL + impl NotInjective {} - | -LL | impl NotInjective {} - | +++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs index 8537c385dc336..3d02d1bb1bd80 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -6,7 +6,6 @@ impl<'a> IntoIterator for &S { //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime - //~| HELP make use of the lifetime parameter `'a` in the `self` type type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index ce260201d31b9..3374c76bb76b9 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -1,5 +1,5 @@ error: missing lifetime in associated type - --> $DIR/missing-lifetime-in-assoc-type-1.rs:10:17 + --> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use @@ -24,10 +24,6 @@ help: consider using the named lifetime here instead of an implicit lifetime | LL | impl<'a> IntoIterator for &'a S { | ++ -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> IntoIterator for &S<'a> { - | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs index e55f0f0321059..853cc6dc8e4e9 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs @@ -6,7 +6,6 @@ impl<'a> IntoIterator for &'_ S { //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime - //~| HELP make use of the lifetime parameter `'a` in the `self` type type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr index d1e7a03c6592e..d58fd8995ef9c 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -1,5 +1,5 @@ error: missing lifetime in associated type - --> $DIR/missing-lifetime-in-assoc-type-5.rs:10:17 + --> $DIR/missing-lifetime-in-assoc-type-5.rs:9:17 | LL | impl<'a> IntoIterator for &'_ S { | ---- there is a named lifetime specified on the impl block you could use @@ -25,10 +25,6 @@ help: consider using the named lifetime here instead of an implicit lifetime LL - impl<'a> IntoIterator for &'_ S { LL + impl<'a> IntoIterator for &'a S { | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> IntoIterator for &'_ S<'a> { - | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs index 66af9529ddea7..b4fac575edb3b 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.rs @@ -13,7 +13,6 @@ impl<'a> Trait for &'_ S { //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter //~| HELP consider using the named lifetime here instead of an implicit lifetime - //~| HELP make use of the lifetime parameter `'a` in the `self` type type Item = &T; //~^ ERROR missing lifetime in associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr index 4a3bc044f1f23..6767243bf21ba 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-6.stderr @@ -1,5 +1,5 @@ error: missing lifetime in associated type - --> $DIR/missing-lifetime-in-assoc-type-6.rs:17:17 + --> $DIR/missing-lifetime-in-assoc-type-6.rs:16:17 | LL | impl<'a> Trait for &'_ S { | ---- there is a named lifetime specified on the impl block you could use @@ -24,10 +24,6 @@ help: consider using the named lifetime here instead of an implicit lifetime LL - impl<'a> Trait for &'_ S { LL + impl<'a> Trait for &'a S { | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> Trait for &'_ S<'a> { - | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr index c2e7f2c1fcc3e..acbdb9b0a308e 100644 --- a/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr +++ b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr @@ -3,12 +3,6 @@ error[E0207]: the type parameter `Unconstrained` is not constrained by the impl | LL | impl<'a, Unconstrained> X for [(); 0] {} | ^^^^^^^^^^^^^ unconstrained type parameter - | -help: either remove the unused type parameter `Unconstrained`, or make use of it - | -LL - impl<'a, Unconstrained> X for [(); 0] {} -LL + impl<'a> X for [(); 0] {} - | error: specialization impl does not specialize any associated items --> $DIR/ice-const-not-fully-resolved-113045.rs:11:1 diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr index 444563b9dfc5e..54c0cf8ebee91 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr @@ -15,14 +15,6 @@ error[E0207]: the type parameter `S` is not constrained by the impl trait, self | LL | impl Trait for i32 { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `S`, or make use of it - | -LL - impl Trait for i32 { -LL + impl Trait for i32 { - | -LL | impl Trait for i32 { - | +++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:12 diff --git a/tests/ui/traits/constrained-type-params-trait-impl.stderr b/tests/ui/traits/constrained-type-params-trait-impl.stderr index 0e2284f7dbc7d..e59fad6e72db1 100644 --- a/tests/ui/traits/constrained-type-params-trait-impl.stderr +++ b/tests/ui/traits/constrained-type-params-trait-impl.stderr @@ -34,14 +34,6 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Foo for [isize; 1] { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `U`, or make use of it - | -LL - impl Foo for [isize; 1] { -LL + impl Foo for [isize; 1] { - | -LL | impl Foo for [isize; 1] { - | +++ error[E0119]: conflicting implementations of trait `Bar` --> $DIR/constrained-type-params-trait-impl.rs:48:1 @@ -59,53 +51,24 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Bar for T { | ^ unconstrained type parameter - | -help: make use of the type parameter `U` in the `self` type - | -LL | impl Bar for T { - | +++ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/constrained-type-params-trait-impl.rs:48:9 | LL | impl Bar for T | ^ unconstrained type parameter - | -help: either remove the unused type parameter `U`, or make use of it - | -LL - impl Bar for T -LL + impl Bar for T - | -LL | impl Bar for T - | +++ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/constrained-type-params-trait-impl.rs:57:9 | LL | impl Foo for T | ^ unconstrained type parameter - | -help: either remove the unused type parameter `U`, or make use of it - | -LL - impl Foo for T -LL + impl Foo for T - | -LL | impl Foo for T - | +++ error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates --> $DIR/constrained-type-params-trait-impl.rs:57:12 | LL | impl Foo for T | ^ unconstrained type parameter - | -help: either remove the unused type parameter `V`, or make use of it - | -LL - impl Foo for T -LL + impl Foo for T - | -LL | impl Foo for T - | +++ error: aborting due to 9 previous errors diff --git a/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr b/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr index 9e8194b46c04f..d04109ad0985b 100644 --- a/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr +++ b/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr @@ -3,6 +3,12 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl Trait<()> for B | ^ unconstrained type parameter + | +help: either remove the unused type parameter `U`, or make use of it + | +LL - impl Trait<()> for B +LL + impl Trait<()> for B + | error[E0277]: the trait bound `(): IncompleteGuidance` is not satisfied --> $DIR/leaking-vars-in-cause-code-2.rs:29:19 diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index e087aec07c9ca..13fbfdb855cbf 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -3,12 +3,6 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self | LL | impl Callable for () { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `V`, or make use of it - | -LL - impl Callable for () { -LL + impl Callable for () { - | error[E0282]: type annotations needed --> $DIR/resolve-impl-before-constrain-check.rs:17:6 diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 6d15d4bf29c9f..9ce0e8d957dab 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl Every for Thing { - | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization-2.rs:16:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 1522efe97e5ec..2da655afa935c 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl Every for Thing { - | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization-2.rs:16:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization.current.stderr b/tests/ui/traits/unconstrained-projection-normalization.current.stderr index d6fd9817676f5..c52e8dd68aa87 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.current.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl Every for Thing { - | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization.rs:15:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index d6fd9817676f5..c52e8dd68aa87 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl Every for Thing { - | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization.rs:15:18 diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr index 08060ee467766..e6b94c525ff23 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr +++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr @@ -3,11 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, I> UnwrapItemsExt for I { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a, I> UnwrapItemsExt for I<'a> { - | ++++ error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/assoc-type-lifetime-unconstrained.rs:22:9 diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr index 236b72d3ef3c5..d18a824287c0c 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr @@ -3,11 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl>>, U> MyIndex> for Scope { | ^ unconstrained type parameter - | -help: make use of the type parameter `T` in the `self` type - | -LL | impl>>, U> MyIndex> for Scope { - | +++ error: item does not constrain `DummyT::{opaque#0}` --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:30:8 diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr index 5f686c5b0a3c5..137a4db81b563 100644 --- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr +++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -3,12 +3,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl X for () { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl X for () { -LL + impl X for () { - | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr index 0bbad183afa2a..4b0c9a10196ca 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr @@ -9,8 +9,6 @@ help: either remove the unused type parameter `T`, or make use of it LL - impl Allocator for DefaultAllocator { LL + impl Allocator for DefaultAllocator { | -LL | impl Allocator for DefaultAllocator { - | +++ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr index 1869354320a41..26babc29000c0 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -3,24 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter - | -help: either remove the unused lifetime parameter `'a`, or make use of it - | -LL - impl<'a, 'b> A for () { -LL + impl<'b> A for () { - | error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-74761-2.rs:7:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter - | -help: either remove the unused lifetime parameter `'b`, or make use of it - | -LL - impl<'a, 'b> A for () { -LL + impl<'a> A for () { - | error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/issue-74761-2.rs:12:28 diff --git a/tests/ui/type-alias-impl-trait/issue-74761.stderr b/tests/ui/type-alias-impl-trait/issue-74761.stderr index 6d2aa1d695cf9..a4826c293467e 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761.stderr @@ -3,24 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter - | -help: either remove the unused lifetime parameter `'a`, or make use of it - | -LL - impl<'a, 'b> A for () { -LL + impl<'b> A for () { - | error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-74761.rs:7:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter - | -help: either remove the unused lifetime parameter `'b`, or make use of it - | -LL - impl<'a, 'b> A for () { -LL + impl<'a> A for () { - | error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/issue-74761.rs:12:28 diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr index 6a8adb2c8a5ac..5f9c56f1ca9d0 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr @@ -3,12 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, I: Iterator> Trait for (i32, I) { | ^^ unconstrained lifetime parameter - | -help: either remove the unused lifetime parameter `'a`, or make use of it - | -LL - impl<'a, I: Iterator> Trait for (i32, I) { -LL + impl> Trait for (i32, I) { - | error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:14:9 diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr index 849f5059d1c54..7a86685787ced 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr @@ -3,11 +3,6 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Trait for Opaque<&'a str> { | ^^ unconstrained lifetime parameter - | -help: make use of the lifetime parameter `'a` in the `self` type - | -LL | impl<'a> Trait for Opaque<&'a str, 'a> { - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/issue-13853-5.stderr b/tests/ui/typeck/issue-13853-5.stderr index 2df273877b5f0..bb967b07b816f 100644 --- a/tests/ui/typeck/issue-13853-5.stderr +++ b/tests/ui/typeck/issue-13853-5.stderr @@ -12,14 +12,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl<'a, T: Deserializable> Deserializable for &'a str { | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl<'a, T: Deserializable> Deserializable for &'a str { -LL + impl<'a> Deserializable for &'a str { - | -LL | impl<'a, T: Deserializable> Deserializable for &'a str { - | +++ error[E0308]: mismatched types --> $DIR/issue-13853-5.rs:9:70 From c735d3823c74848358a77f62828e859232873636 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Fri, 6 Mar 2026 20:38:17 +1300 Subject: [PATCH 11/21] fixed some comments --- .../rustc_hir_analysis/src/impl_wf_check.rs | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 05ea25181dcfe..aeadf1413015f 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -383,17 +383,29 @@ fn suggest_to_remove_or_use_generic( // Option A: Remove (Only if not used in body) if !is_param_used { suggestions.push(vec![(hir_impl.generics.span_for_param_removal(index), String::new())]); - } else { - // there could be a case where the parameter is used in the body, but the self type is still missing the generic argument, so we want to suggest adding it in that case as well - // e.g. - // ``` - // struct S; - // impl<'a> S { - // fn foo(&self) -> &'a str { "" } - // } - // ``` - // in such a case we could make the suggestion to add 'a to S in the `sturct S` definition and the `impl S` definition } + // todo: there could be a case where the parameter is used in the body, but the self type is still missing the generic argument, so we want to suggest adding it in that case as well + // e.g. + // ``` + // struct S; + // impl S { + // fn foo(&self, x: T) { + // // use T here + // } + // } + // ``` + // in such a case we could make the suggestion to add 'a to S in the `struct S` definition and the `impl S` definition + // but finding out whether the parameter is used as a generic argument in a function which doesnt have the generic parameter set for itself is not trivial + // such a case can be seen here: + // ``` + // struct S; + // impl S { + // fn foo(&self, x: T) { + // // use T here + // } + // } + // ``` + // where it would be a good suggestion to remove the generic parameter `T` from the `impl` definition as the function `foo` can work without it. // Option B: Suggest adding only if there's an available slot if provided_slots < total_slots { From 8200d5ce108413991ed036b056880a52e7246b98 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Sun, 8 Mar 2026 12:40:51 +1300 Subject: [PATCH 12/21] moved from multi part suggestions, to multiple single suggestions --- .../rustc_hir_analysis/src/impl_wf_check.rs | 59 +++++++++++-------- .../issues/issue-78654.full.stderr | 10 ++-- .../async-await/issues/issue-78654.min.stderr | 10 ++-- .../unsized-anon-const-err-2.stderr | 20 +++---- ...post-analysis-user-facing-param-env.stderr | 10 ++-- .../issues/issue-68366.full.stderr | 20 +++---- .../issues/issue-68366.min.stderr | 20 +++---- .../unconstrained_const_param_on_drop.stderr | 10 ++-- .../bugs/issue-88526.stderr | 11 ++-- ...nstrained-type-params-inherent-impl.stderr | 22 +++---- tests/ui/issues/issue-16562.stderr | 11 ++-- .../leaking-vars-in-cause-code-2.stderr | 11 ++-- .../type-alias-impl-trait/issue-74244.stderr | 11 ++-- 13 files changed, 100 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index aeadf1413015f..0e35e8a8d4051 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -377,12 +377,11 @@ fn suggest_to_remove_or_use_generic( } let is_param_used = visitor.found; - // Build Suggestions let mut suggestions = vec![]; // Option A: Remove (Only if not used in body) if !is_param_used { - suggestions.push(vec![(hir_impl.generics.span_for_param_removal(index), String::new())]); + suggestions.push((hir_impl.generics.span_for_param_removal(index), String::new())); } // todo: there could be a case where the parameter is used in the body, but the self type is still missing the generic argument, so we want to suggest adding it in that case as well // e.g. @@ -396,7 +395,7 @@ fn suggest_to_remove_or_use_generic( // ``` // in such a case we could make the suggestion to add 'a to S in the `struct S` definition and the `impl S` definition // but finding out whether the parameter is used as a generic argument in a function which doesnt have the generic parameter set for itself is not trivial - // such a case can be seen here: + // such an edge case can be seen here: // ``` // struct S; // impl S { @@ -406,17 +405,17 @@ fn suggest_to_remove_or_use_generic( // } // ``` // where it would be a good suggestion to remove the generic parameter `T` from the `impl` definition as the function `foo` can work without it. + // The test case `tests/ui/associated-types/unconstrained-lifetime-assoc-type.rs` for example would benefit from such a suggestion. // Option B: Suggest adding only if there's an available slot if provided_slots < total_slots { if let Some(args) = last_segment_args { // Struct already has <...>, append to it - suggestions - .push(vec![(args.span().unwrap().shrink_to_hi(), format!(", {}", param.name))]); + suggestions.push((args.span().unwrap().shrink_to_hi(), format!(", {}", param.name))); } else if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind { // Struct has no <...> yet, add it let seg = path.segments.last().unwrap(); - suggestions.push(vec![(seg.ident.span.shrink_to_hi(), format!("<{}>", param.name))]); + suggestions.push((seg.ident.span.shrink_to_hi(), format!("<{}>", param.name))); } } @@ -424,23 +423,37 @@ fn suggest_to_remove_or_use_generic( return; } - let msg = if is_param_used { - format!("make use of the {} parameter `{}` in the `self` type", parameter_type, param.name) - } else { - format!( - "either remove the unused {} parameter `{}`, or make use of it", + if is_param_used { + let msg = format!( + "make use of the {} parameter `{}` in the `self` type", parameter_type, param.name - ) + ); + diag.span_suggestion( + suggestions[0].0, + msg, + suggestions[0].1.clone(), + Applicability::MaybeIncorrect, + ); + } else { + let msg = if suggestions.len() == 2 { + format!("either remove the unused {} parameter `{}`", parameter_type, param.name) + } else { + format!("remove the unused {} parameter `{}`", parameter_type, param.name) + }; + diag.span_suggestion( + suggestions[0].0, + msg, + suggestions[0].1.clone(), + Applicability::MaybeIncorrect, + ); + if suggestions.len() == 2 { + let msg = format!("or make use of it"); + diag.span_suggestion( + suggestions[1].0, + msg, + suggestions[1].1.clone(), + Applicability::MaybeIncorrect, + ); + } }; - - diag.multipart_suggestions(msg, suggestions, Applicability::MaybeIncorrect); } - -// fn extract_ty_as_path<'hir>(ty: &Ty<'hir>) -> Option<&'hir Path<'hir>> { -// match ty.kind { -// TyKind::Path(QPath::Resolved(_, path)) => Some(path), -// TyKind::Slice(ty) | TyKind::Array(ty, _) => extract_ty_as_path(ty), -// TyKind::Ptr(ty) | TyKind::Ref(_, ty) => extract_ty_as_path(ty.ty), -// _ => None, -// } -// } diff --git a/tests/ui/async-await/issues/issue-78654.full.stderr b/tests/ui/async-await/issues/issue-78654.full.stderr index 30b19b0a2e29b..e1f9aa9ce81e7 100644 --- a/tests/ui/async-await/issues/issue-78654.full.stderr +++ b/tests/ui/async-await/issues/issue-78654.full.stderr @@ -8,15 +8,13 @@ error[E0207]: the const parameter `H` is not constrained by the impl trait, self --> $DIR/issue-78654.rs:9:6 | LL | impl Foo { - | ^^^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `H` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `H`, or make use of it - | -LL - impl Foo { -LL + impl Foo { - | error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/issues/issue-78654.min.stderr b/tests/ui/async-await/issues/issue-78654.min.stderr index 30b19b0a2e29b..e1f9aa9ce81e7 100644 --- a/tests/ui/async-await/issues/issue-78654.min.stderr +++ b/tests/ui/async-await/issues/issue-78654.min.stderr @@ -8,15 +8,13 @@ error[E0207]: the const parameter `H` is not constrained by the impl trait, self --> $DIR/issue-78654.rs:9:6 | LL | impl Foo { - | ^^^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `H` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `H`, or make use of it - | -LL - impl Foo { -LL + impl Foo { - | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr index 99e6cf77b533f..962b83832ac0b 100644 --- a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr @@ -46,29 +46,25 @@ error[E0207]: the const parameter `N` is not constrained by the impl trait, self --> $DIR/unsized-anon-const-err-2.rs:14:6 | LL | impl Copy for S {} - | ^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `N` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `N`, or make use of it - | -LL - impl Copy for S {} -LL + impl Copy for S {} - | error[E0207]: the const parameter `M` is not constrained by the impl trait, self type, or predicates --> $DIR/unsized-anon-const-err-2.rs:17:6 | LL | impl Copy for S {} - | ^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `M` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `M`, or make use of it - | -LL - impl Copy for S {} -LL + impl Copy for S {} - | error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr index 7814a1888c040..9962a6814fcfd 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr @@ -33,15 +33,13 @@ error[E0207]: the const parameter `NUM` is not constrained by the impl trait, se --> $DIR/post-analysis-user-facing-param-env.rs:6:10 | LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo - | ^^^^^^^^^^^^^^^^ unconstrained const parameter + | --^^^^^^^^^^^^^^^^ + | | | + | | unconstrained const parameter + | help: remove the unused type parameter `NUM` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `NUM`, or make use of it - | -LL - impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo -LL + impl<'a> std::ops::Add<&'a Foo> for Foo - | error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/issues/issue-68366.full.stderr b/tests/ui/const-generics/issues/issue-68366.full.stderr index a242f89846121..a6accc2f1d023 100644 --- a/tests/ui/const-generics/issues/issue-68366.full.stderr +++ b/tests/ui/const-generics/issues/issue-68366.full.stderr @@ -14,29 +14,25 @@ error[E0207]: the const parameter `N` is not constrained by the impl trait, self --> $DIR/issue-68366.rs:12:7 | LL | impl Collatz<{Some(N)}> {} - | ^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `N` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `N`, or make use of it - | -LL - impl Collatz<{Some(N)}> {} -LL + impl Collatz<{Some(N)}> {} - | error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:19:6 | LL | impl Foo {} - | ^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `N` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `N`, or make use of it - | -LL - impl Foo {} -LL + impl Foo {} - | error: overly complex generic constant --> $DIR/issue-68366.rs:12:31 diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index c53ebbcf33a49..e5d3f5508420f 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -23,29 +23,25 @@ error[E0207]: the const parameter `N` is not constrained by the impl trait, self --> $DIR/issue-68366.rs:12:7 | LL | impl Collatz<{Some(N)}> {} - | ^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `N` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `N`, or make use of it - | -LL - impl Collatz<{Some(N)}> {} -LL + impl Collatz<{Some(N)}> {} - | error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:19:6 | LL | impl Foo {} - | ^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `N` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `N`, or make use of it - | -LL - impl Foo {} -LL + impl Foo {} - | error: aborting due to 4 previous errors diff --git a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr index 63a8d8680643f..6cf78a06752ba 100644 --- a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr +++ b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr @@ -22,15 +22,13 @@ error[E0207]: the const parameter `UNUSED` is not constrained by the impl trait, --> $DIR/unconstrained_const_param_on_drop.rs:3:6 | LL | impl Drop for Foo {} - | ^^^^^^^^^^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `UNUSED` | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -help: either remove the unused type parameter `UNUSED`, or make use of it - | -LL - impl Drop for Foo {} -LL + impl Drop for Foo {} - | error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.stderr b/tests/ui/generic-associated-types/bugs/issue-88526.stderr index d391bbb496c73..ea2962c693f0a 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88526.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr @@ -2,13 +2,10 @@ error[E0207]: the type parameter `I` is not constrained by the impl trait, self --> $DIR/issue-88526.rs:25:13 | LL | impl<'q, Q, I, F> A for TestB - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `I`, or make use of it - | -LL - impl<'q, Q, I, F> A for TestB -LL + impl<'q, Q, F> A for TestB - | + | ^-- + | | + | unconstrained type parameter + | help: remove the unused type parameter `I` error[E0309]: the parameter type `F` may not live long enough --> $DIR/issue-88526.rs:16:5 diff --git a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr index 64b7d742aebff..958b1ff0664ab 100644 --- a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr +++ b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr @@ -2,25 +2,19 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self --> $DIR/unconstrained-type-params-inherent-impl.rs:11:6 | LL | impl MyType { - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl MyType { -LL + impl MyType { - | + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `T` error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained-type-params-inherent-impl.rs:20:9 | LL | impl MyType1 { - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `U`, or make use of it - | -LL - impl MyType1 { -LL + impl MyType1 { - | + | --^ + | | | + | | unconstrained type parameter + | help: remove the unused type parameter `U` error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-16562.stderr b/tests/ui/issues/issue-16562.stderr index 2e73df9f2076e..ac957fdb069d0 100644 --- a/tests/ui/issues/issue-16562.stderr +++ b/tests/ui/issues/issue-16562.stderr @@ -2,13 +2,10 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self --> $DIR/issue-16562.rs:10:6 | LL | impl Collection for Col { - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl Collection for Col { -LL + impl Collection for Col { - | + | ^-- + | | + | unconstrained type parameter + | help: remove the unused type parameter `T` error: aborting due to 1 previous error diff --git a/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr b/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr index d04109ad0985b..193e144d17cd6 100644 --- a/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr +++ b/tests/ui/traits/error-reporting/leaking-vars-in-cause-code-2.stderr @@ -2,13 +2,10 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self --> $DIR/leaking-vars-in-cause-code-2.rs:19:9 | LL | impl Trait<()> for B - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `U`, or make use of it - | -LL - impl Trait<()> for B -LL + impl Trait<()> for B - | + | --^ + | | | + | | unconstrained type parameter + | help: remove the unused type parameter `U` error[E0277]: the trait bound `(): IncompleteGuidance` is not satisfied --> $DIR/leaking-vars-in-cause-code-2.rs:29:19 diff --git a/tests/ui/type-alias-impl-trait/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr index 4b0c9a10196ca..6e01425afec5e 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr @@ -2,13 +2,10 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self --> $DIR/issue-74244.rs:9:6 | LL | impl Allocator for DefaultAllocator { - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl Allocator for DefaultAllocator { -LL + impl Allocator for DefaultAllocator { - | + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `T` error: aborting due to 1 previous error From 71ecd9beb0502b86c9dfad928793508299d222ae Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Sun, 8 Mar 2026 15:18:58 +1300 Subject: [PATCH 13/21] fixed the two failing tests --- .../rustdoc-ui/not-wf-ambiguous-normalization.stderr | 11 ++++------- .../unconstrained-param-in-impl-ambiguity.stderr | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr index 62bfb8617b781..b19d965e7c198 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -2,13 +2,10 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self --> $DIR/not-wf-ambiguous-normalization.rs:14:6 | LL | impl Allocator for DefaultAllocator { - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `T`, or make use of it - | -LL - impl Allocator for DefaultAllocator { -LL + impl Allocator for DefaultAllocator { - | + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `T` error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr index c34607f8773c0..ba644957127ae 100644 --- a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr @@ -2,13 +2,10 @@ error[E0207]: the type parameter `Q` is not constrained by the impl trait, self --> $DIR/unconstrained-param-in-impl-ambiguity.rs:7:13 | LL | unsafe impl Send for Inner {} - | ^ unconstrained type parameter - | -help: either remove the unused type parameter `Q`, or make use of it - | -LL - unsafe impl Send for Inner {} -LL + unsafe impl Send for Inner {} - | + | -^-------- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `Q` error: aborting due to 1 previous error From 5d77bb2a3a41761c95d10de58b19dc32d17cb255 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Sun, 8 Mar 2026 17:19:57 +1300 Subject: [PATCH 14/21] more readable comments --- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 0e35e8a8d4051..633f188649969 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -277,10 +277,9 @@ impl<'tcx> Visitor<'tcx> for ParamUsageVisitor<'tcx> { if let Some(res_def_id) = path.res.opt_def_id() { if res_def_id == self.param_def_id { self.found = true; - return ControlFlow::Break(()); // Found it, stop visiting. + return ControlFlow::Break(()); } } - // If not found, continue walking down the HIR tree. intravisit::walk_path(self, path) } @@ -289,7 +288,7 @@ impl<'tcx> Visitor<'tcx> for ParamUsageVisitor<'tcx> { if let Some(local_def_id) = self.param_def_id.as_local() { if id == local_def_id { self.found = true; - return ControlFlow::Break(()); // Found it, stop visiting. + return ControlFlow::Break(()); } } } @@ -330,7 +329,7 @@ fn suggest_to_remove_or_use_generic( return; }; - // Count how many slots are DEFINED in the struct (N) + // Count how many slots are defined in the struct defintion let generics = tcx.generics_of(struct_def_id); let total_slots = generics .own_params @@ -344,7 +343,7 @@ fn suggest_to_remove_or_use_generic( }) .count(); - // Count how many arguments are CURRENTLY PROVIDED in the impl (J) + // Count how many arguments are currently provided in the impl let mut provided_slots = 0; let mut last_segment_args = None; @@ -367,7 +366,6 @@ fn suggest_to_remove_or_use_generic( } } - // Determine if the parameter is used in the impl body let mut visitor = ParamUsageVisitor { tcx, param_def_id: param.def_id, found: false }; for item_ref in hir_impl.items { let _ = visitor.visit_impl_item_ref(item_ref); From 48c4e3c67af3461f6ae6da1cda36fa4869c9c7f8 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Sun, 8 Mar 2026 17:30:03 +1300 Subject: [PATCH 15/21] fixed typo --- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 633f188649969..54445d70254c2 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -329,7 +329,7 @@ fn suggest_to_remove_or_use_generic( return; }; - // Count how many slots are defined in the struct defintion + // Count how many slots are defined in the struct definition let generics = tcx.generics_of(struct_def_id); let total_slots = generics .own_params From 78b460fb1d89f505dc824cc7f1ffc1ba7e2d21d9 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 9 Mar 2026 13:09:28 +1300 Subject: [PATCH 16/21] fmt --- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 54445d70254c2..ba8d121033cb4 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -9,7 +9,6 @@ //! fixed, but for the moment it's easier to do these checks early. use std::debug_assert_matches; - use std::ops::ControlFlow; use min_specialization::check_min_specialization; From d5406c4a929cfd08cf9ddd847da0abb3e76a7891 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 11 Mar 2026 15:04:59 +1300 Subject: [PATCH 17/21] moved the suggestion code to the error module Signed-off-by: janwi_mac --- compiler/rustc_hir_analysis/src/errors.rs | 2 + .../src/errors/remove_or_use_generic.rs | 217 +++++++++++++++++ .../rustc_hir_analysis/src/impl_wf_check.rs | 223 +----------------- 3 files changed, 225 insertions(+), 217 deletions(-) create mode 100644 compiler/rustc_hir_analysis/src/errors/remove_or_use_generic.rs diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1c999f1ffc93a..53556dfb2b8ab 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -15,6 +15,8 @@ pub(crate) mod wrong_number_of_generic_args; mod precise_captures; pub(crate) use precise_captures::*; +pub(crate) mod remove_or_use_generic; + #[derive(Diagnostic)] #[diag("ambiguous associated {$assoc_kind} `{$assoc_ident}` in bounds of `{$qself}`")] pub(crate) struct AmbiguousAssocItem<'a> { diff --git a/compiler/rustc_hir_analysis/src/errors/remove_or_use_generic.rs b/compiler/rustc_hir_analysis/src/errors/remove_or_use_generic.rs new file mode 100644 index 0000000000000..fe8ef454c35b6 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/errors/remove_or_use_generic.rs @@ -0,0 +1,217 @@ +use std::ops::ControlFlow; + +use rustc_errors::{Applicability, Diag}; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::{self, Visitor, walk_lifetime}; +use rustc_hir::{GenericArg, HirId, LifetimeKind, Path, QPath, TyKind}; +use rustc_middle::hir::nested_filter::All; +use rustc_middle::ty::{GenericParamDef, GenericParamDefKind, TyCtxt}; + +use crate::hir::def::Res; + +/// Use a Visitor to find usages of the type or lifetime parameter +struct ParamUsageVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + /// The `DefId` of the generic parameter we are looking for. + param_def_id: DefId, + found: bool, +} + +impl<'tcx> Visitor<'tcx> for ParamUsageVisitor<'tcx> { + type NestedFilter = All; + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx + } + + type Result = ControlFlow<()>; + + fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result { + if let Some(res_def_id) = path.res.opt_def_id() { + if res_def_id == self.param_def_id { + self.found = true; + return ControlFlow::Break(()); + } + } + intravisit::walk_path(self, path) + } + + fn visit_lifetime(&mut self, lifetime: &'tcx rustc_hir::Lifetime) -> Self::Result { + if let LifetimeKind::Param(id) = lifetime.kind { + if let Some(local_def_id) = self.param_def_id.as_local() { + if id == local_def_id { + self.found = true; + return ControlFlow::Break(()); + } + } + } + walk_lifetime(self, lifetime) + } +} + +/// Adds a suggestion to a diagnostic to either remove an unused generic parameter, or use it. +/// +/// # Examples +/// +/// - `impl Struct { ... }` where `T` is unused -> suggests removing `T` or using it. +/// - `impl<'a> Struct { ... }` where `'a` is unused -> suggests removing `'a`. +/// - `impl Struct { // T used in here }` where `T` is used in the body but not in the self type -> suggests adding `T` to the self type and struct definition. +/// - `impl Struct { ... }` where the struct has a generic parameter with a default -> suggests adding `T` to the self type. +pub(crate) fn suggest_to_remove_or_use_generic( + tcx: TyCtxt<'_>, + diag: &mut Diag<'_>, + impl_def_id: LocalDefId, + param: &GenericParamDef, + is_lifetime: bool, +) { + let node = tcx.hir_node_by_def_id(impl_def_id); + let hir_impl = node.expect_item().expect_impl(); + + let Some((index, _)) = hir_impl + .generics + .params + .iter() + .enumerate() + .find(|(_, par)| par.def_id.to_def_id() == param.def_id) + else { + return; + }; + + // Get the Struct/ADT definition ID from the self type + let struct_def_id = if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind + && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, def_id) = path.res + { + def_id + } else { + return; + }; + + // Count how many generic parameters are defined in the struct definition + let generics = tcx.generics_of(struct_def_id); + let total_params = generics + .own_params + .iter() + .filter(|p| { + if is_lifetime { + matches!(p.kind, GenericParamDefKind::Lifetime) + } else { + matches!(p.kind, GenericParamDefKind::Type { .. }) + } + }) + .count(); + + // Count how many arguments are currently provided in the impl + let mut provided_params = 0; + let mut last_segment_args = None; + + if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind + && let Some(seg) = path.segments.last() + && let Some(args) = seg.args + { + last_segment_args = Some(args); + provided_params = args + .args + .iter() + .filter(|arg| match arg { + GenericArg::Lifetime(_) => is_lifetime, + GenericArg::Type(_) => !is_lifetime, + _ => false, + }) + .count(); + } + + let mut visitor = ParamUsageVisitor { tcx, param_def_id: param.def_id, found: false }; + for item_ref in hir_impl.items { + let _ = visitor.visit_impl_item_ref(item_ref); + if visitor.found { + break; + } + } + let is_param_used = visitor.found; + + let mut suggestions = vec![]; + + // Option A: Remove (Only if not used in body) + if !is_param_used { + suggestions.push((hir_impl.generics.span_for_param_removal(index), String::new())); + } + + // Option B: Suggest adding only if there's an available parameter in the struct definition + // or the parameter is already used somewhere, then we suggest adding to the impl struct and the struct definition + if provided_params < total_params || is_param_used { + if let Some(args) = last_segment_args { + // Struct already has <...>, append to it + suggestions.push((args.span().unwrap().shrink_to_hi(), format!(", {}", param.name))); + } else if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind { + // Struct has no <...> yet, add it + let seg = path.segments.last().unwrap(); + suggestions.push((seg.ident.span.shrink_to_hi(), format!("<{}>", param.name))); + } + if is_param_used { + // If the parameter is used in the body, we also want to suggest adding it to the struct definition if it's not already there + let struct_span = tcx.def_span(struct_def_id); + let struct_generic_params = tcx + .hir_node_by_def_id(struct_def_id.expect_local()) + .expect_item() + .expect_struct() + .1 + .params; + if struct_generic_params.len() > 0 { + let last_param = struct_generic_params.last().unwrap(); + suggestions.push((last_param.span.shrink_to_hi(), format!(", {}", param.name))); + } else { + suggestions.push((struct_span.shrink_to_hi(), format!("<{}>", param.name))); + } + } + } + + if suggestions.is_empty() { + return; + } + + let parameter_type = if is_lifetime { "lifetime" } else { "type" }; + if is_param_used { + let msg = format!( + "make use of the {} parameter `{}` in the `self` type", + parameter_type, param.name + ); + diag.span_suggestion( + suggestions[0].0, + msg, + suggestions[0].1.clone(), + Applicability::MaybeIncorrect, + ); + let msg2 = format!( + "and add it to the struct definition of {} as well since it's used in the body of the impl", + tcx.def_path_str(struct_def_id) + ); + diag.span_suggestion( + suggestions[1].0, + msg2, + suggestions[1].1.clone(), + Applicability::MaybeIncorrect, + ); + } else { + let msg = if suggestions.len() == 2 { + format!("either remove the unused {} parameter `{}`", parameter_type, param.name) + } else { + format!("remove the unused {} parameter `{}`", parameter_type, param.name) + }; + diag.span_suggestion( + suggestions[0].0, + msg, + suggestions[0].1.clone(), + Applicability::MaybeIncorrect, + ); + if suggestions.len() == 2 { + let msg = format!("or make use of it"); + diag.span_suggestion( + suggestions[1].0, + msg, + suggestions[1].1.clone(), + Applicability::MaybeIncorrect, + ); + } + }; +} diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index ba8d121033cb4..4d638d378c425 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -9,23 +9,19 @@ //! fixed, but for the moment it's easier to do these checks early. use std::debug_assert_matches; -use std::ops::ControlFlow; use min_specialization::check_min_specialization; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Applicability; use rustc_errors::codes::*; -use rustc_errors::{Applicability, Diag}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::{self, Visitor, walk_lifetime}; -use rustc_hir::{GenericArg, HirId, LifetimeKind, Path, QPath, TyKind}; -use rustc_middle::hir::nested_filter::All; -use rustc_middle::ty::{self, GenericParamDef, GenericParamDefKind, TyCtxt, TypeVisitableExt}; +use rustc_hir::def_id::LocalDefId; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; use crate::errors::UnconstrainedGenericParameter; -use crate::hir::def::Res; +use crate::errors::remove_or_use_generic::suggest_to_remove_or_use_generic; mod min_specialization; @@ -177,13 +173,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( ); } } - suggest_to_remove_or_use_generic( - tcx, - &mut diag, - impl_def_id, - param, - "lifetime", - ); + suggest_to_remove_or_use_generic(tcx, &mut diag, impl_def_id, param, true); res = Err(diag.emit()); } } @@ -247,210 +237,9 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( const_param_note2: const_param_note, }); diag.code(E0207); - suggest_to_remove_or_use_generic(tcx, &mut diag, impl_def_id, ¶m, "type"); + suggest_to_remove_or_use_generic(tcx, &mut diag, impl_def_id, ¶m, false); res = Err(diag.emit()); } } res } - -/// Use a Visitor to find usages of the type or lifetime parameter -struct ParamUsageVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - /// The `DefId` of the generic parameter we are looking for. - param_def_id: DefId, - found: bool, -} - -// todo: maybe this can be done more efficiently by only searching for generics OR lifetimes and searching more effectively -impl<'tcx> Visitor<'tcx> for ParamUsageVisitor<'tcx> { - type NestedFilter = All; - - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { - self.tcx - } - - type Result = ControlFlow<()>; - - fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result { - if let Some(res_def_id) = path.res.opt_def_id() { - if res_def_id == self.param_def_id { - self.found = true; - return ControlFlow::Break(()); - } - } - intravisit::walk_path(self, path) - } - - fn visit_lifetime(&mut self, lifetime: &'tcx rustc_hir::Lifetime) -> Self::Result { - if let LifetimeKind::Param(id) = lifetime.kind { - if let Some(local_def_id) = self.param_def_id.as_local() { - if id == local_def_id { - self.found = true; - return ControlFlow::Break(()); - } - } - } - walk_lifetime(self, lifetime) - } -} - -fn suggest_to_remove_or_use_generic( - tcx: TyCtxt<'_>, - diag: &mut Diag<'_>, - impl_def_id: LocalDefId, - param: &GenericParamDef, - parameter_type: &str, -) { - let node = tcx.hir_node_by_def_id(impl_def_id); - let hir_impl = node.expect_item().expect_impl(); - - let Some((index, _)) = hir_impl - .generics - .params - .iter() - .enumerate() - .find(|(_, par)| par.def_id.to_def_id() == param.def_id) - else { - return; - }; - - // Get the Struct/ADT definition ID from the self type - let Some(struct_def_id) = (|| { - if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind - && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, def_id) = path.res - { - Some(def_id) - } else { - None - } - })() else { - return; - }; - - // Count how many slots are defined in the struct definition - let generics = tcx.generics_of(struct_def_id); - let total_slots = generics - .own_params - .iter() - .filter(|p| { - if parameter_type == "lifetime" { - matches!(p.kind, GenericParamDefKind::Lifetime) - } else { - matches!(p.kind, GenericParamDefKind::Type { .. }) - } - }) - .count(); - - // Count how many arguments are currently provided in the impl - let mut provided_slots = 0; - let mut last_segment_args = None; - - if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind { - if let Some(seg) = path.segments.last() { - if let Some(args) = seg.args { - last_segment_args = Some(args); - provided_slots = args - .args - .iter() - .filter(|arg| { - if parameter_type == "lifetime" { - matches!(arg, GenericArg::Lifetime(_)) - } else { - matches!(arg, GenericArg::Type(_)) - } - }) - .count(); - } - } - } - - let mut visitor = ParamUsageVisitor { tcx, param_def_id: param.def_id, found: false }; - for item_ref in hir_impl.items { - let _ = visitor.visit_impl_item_ref(item_ref); - if visitor.found { - break; - } - } - let is_param_used = visitor.found; - - let mut suggestions = vec![]; - - // Option A: Remove (Only if not used in body) - if !is_param_used { - suggestions.push((hir_impl.generics.span_for_param_removal(index), String::new())); - } - // todo: there could be a case where the parameter is used in the body, but the self type is still missing the generic argument, so we want to suggest adding it in that case as well - // e.g. - // ``` - // struct S; - // impl S { - // fn foo(&self, x: T) { - // // use T here - // } - // } - // ``` - // in such a case we could make the suggestion to add 'a to S in the `struct S` definition and the `impl S` definition - // but finding out whether the parameter is used as a generic argument in a function which doesnt have the generic parameter set for itself is not trivial - // such an edge case can be seen here: - // ``` - // struct S; - // impl S { - // fn foo(&self, x: T) { - // // use T here - // } - // } - // ``` - // where it would be a good suggestion to remove the generic parameter `T` from the `impl` definition as the function `foo` can work without it. - // The test case `tests/ui/associated-types/unconstrained-lifetime-assoc-type.rs` for example would benefit from such a suggestion. - - // Option B: Suggest adding only if there's an available slot - if provided_slots < total_slots { - if let Some(args) = last_segment_args { - // Struct already has <...>, append to it - suggestions.push((args.span().unwrap().shrink_to_hi(), format!(", {}", param.name))); - } else if let TyKind::Path(QPath::Resolved(_, path)) = hir_impl.self_ty.kind { - // Struct has no <...> yet, add it - let seg = path.segments.last().unwrap(); - suggestions.push((seg.ident.span.shrink_to_hi(), format!("<{}>", param.name))); - } - } - - if suggestions.is_empty() { - return; - } - - if is_param_used { - let msg = format!( - "make use of the {} parameter `{}` in the `self` type", - parameter_type, param.name - ); - diag.span_suggestion( - suggestions[0].0, - msg, - suggestions[0].1.clone(), - Applicability::MaybeIncorrect, - ); - } else { - let msg = if suggestions.len() == 2 { - format!("either remove the unused {} parameter `{}`", parameter_type, param.name) - } else { - format!("remove the unused {} parameter `{}`", parameter_type, param.name) - }; - diag.span_suggestion( - suggestions[0].0, - msg, - suggestions[0].1.clone(), - Applicability::MaybeIncorrect, - ); - if suggestions.len() == 2 { - let msg = format!("or make use of it"); - diag.span_suggestion( - suggestions[1].0, - msg, - suggestions[1].1.clone(), - Applicability::MaybeIncorrect, - ); - } - }; -} From 2461e5debd6ac6e122a3c7e99ba7374ba77f65d6 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 11 Mar 2026 15:05:17 +1300 Subject: [PATCH 18/21] added doc comments for the new functions Signed-off-by: janwi_mac --- compiler/rustc_hir/src/hir.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e9261773b7fe2..78d27b71015f6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1096,6 +1096,28 @@ impl<'hir> Generics<'hir> { } } + /// Computes the span representing the removal of a generic parameter at `param_index`. + /// + /// This function identifies the correct slice of source code to delete so that the + /// remaining generic list remains syntactically valid (handling commas and brackets). + /// + /// ### Examples + /// + /// 1. **With a following parameter:** (Includes the trailing comma) + /// - Input: `` (index 0) + /// - Produces span for: `T, ` + /// + /// 2. **With a previous parameter:** (Includes the leading comma and bounds) + /// - Input: `` (index 1) + /// - Produces span for: `, U` + /// + /// 3. **The only parameter:** (Includes the angle brackets) + /// - Input: `` (index 0) + /// - Produces span for: `` + /// + /// 4. **Parameter with where-clause bounds:** + /// - Input: `fn foo() where T: Copy` (index 0) + /// - Produces span for: `T, ` (The where-clause remains for other logic to handle). pub fn span_for_param_removal(&self, param_index: usize) -> Span { if param_index >= self.params.len() { return self.span.shrink_to_hi(); @@ -1133,6 +1155,16 @@ impl<'hir> Generics<'hir> { } } + /// Returns the span of the `WherePredicate` associated with the given `GenericParam`, if any. + /// + /// This looks specifically for predicates in the `where` clause that were generated + /// from the parameter definition (e.g., `T` in `where T: Bound`). + /// + /// ### Example + /// + /// - Input: `param` representing `T` + /// - Context: `where T: Clone + Default, U: Copy` + /// - Returns: Span of `T: Clone + Default` fn span_for_param_bounds(&self, param: &GenericParam<'hir>) -> Option { self.predicates .iter() From 1cdc8cb92023d1930d1aebda149fd535c0ce066b Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 11 Mar 2026 15:06:26 +1300 Subject: [PATCH 19/21] added new test cases for to exercise the new branches added in the `suggest_to_remove_or_use_generic` function Signed-off-by: janwi_mac --- .../unconstrained-param-default-available.rs | 18 ++++++++++ ...constrained-param-default-available.stderr | 35 +++++++++++++++++++ tests/ui/generics/unconstrained-used-param.rs | 23 ++++++++++++ .../generics/unconstrained-used-param.stderr | 33 +++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 tests/ui/generics/unconstrained-param-default-available.rs create mode 100644 tests/ui/generics/unconstrained-param-default-available.stderr create mode 100644 tests/ui/generics/unconstrained-used-param.rs create mode 100644 tests/ui/generics/unconstrained-used-param.stderr diff --git a/tests/ui/generics/unconstrained-param-default-available.rs b/tests/ui/generics/unconstrained-param-default-available.rs new file mode 100644 index 0000000000000..a602a88cb6d6e --- /dev/null +++ b/tests/ui/generics/unconstrained-param-default-available.rs @@ -0,0 +1,18 @@ +//! Test that making use of parameter is suggested when a parameter with default type is available + +struct S { + _u: U, +} +impl MyTrait for S {} +//~^ ERROR the type parameter `V` is not constrained by the impl trait, self type, or predicates + +struct S2 { + _t: T, + _u: U, +} +impl MyTrait for S2 {} +//~^ ERROR the type parameter `V` is not constrained by the impl trait, self type, or predicates + +trait MyTrait {} + +fn main() {} diff --git a/tests/ui/generics/unconstrained-param-default-available.stderr b/tests/ui/generics/unconstrained-param-default-available.stderr new file mode 100644 index 0000000000000..ea8f02a4cb8a5 --- /dev/null +++ b/tests/ui/generics/unconstrained-param-default-available.stderr @@ -0,0 +1,35 @@ +error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-param-default-available.rs:6:6 + | +LL | impl MyTrait for S {} + | ^ unconstrained type parameter + | +help: either remove the unused type parameter `V` + | +LL - impl MyTrait for S {} +LL + impl MyTrait for S {} + | +help: or make use of it + | +LL | impl MyTrait for S {} + | +++ + +error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-param-default-available.rs:13:9 + | +LL | impl MyTrait for S2 {} + | ^ unconstrained type parameter + | +help: either remove the unused type parameter `V` + | +LL - impl MyTrait for S2 {} +LL + impl MyTrait for S2 {} + | +help: or make use of it + | +LL | impl MyTrait for S2 {} + | +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/generics/unconstrained-used-param.rs b/tests/ui/generics/unconstrained-used-param.rs new file mode 100644 index 0000000000000..592880fcf7527 --- /dev/null +++ b/tests/ui/generics/unconstrained-used-param.rs @@ -0,0 +1,23 @@ +//! Test that making use of parameter is suggested when the parameter is used in the impl +//! but not in the trait or self type + +struct S; +impl S { +//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates + fn foo(&self, x: T) { + // use T here + } +} + + +struct S2 { + _f: F, +} +impl S2 { +//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates + fn foo(&self, x: T) { + // use T here + } +} + +fn main() {} diff --git a/tests/ui/generics/unconstrained-used-param.stderr b/tests/ui/generics/unconstrained-used-param.stderr new file mode 100644 index 0000000000000..039e7fce62d35 --- /dev/null +++ b/tests/ui/generics/unconstrained-used-param.stderr @@ -0,0 +1,33 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-used-param.rs:5:6 + | +LL | impl S { + | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl S { + | +++ +help: and add it to the struct definition of S as well since it's used in the body of the impl + | +LL | struct S; + | +++ + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-used-param.rs:16:9 + | +LL | impl S2 { + | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl S2 { + | +++ +help: and add it to the struct definition of S2 as well since it's used in the body of the impl + | +LL | struct S2 { + | +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. From 0b83de8dae024d3034a16c0f84b0989148e768d1 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 11 Mar 2026 15:08:52 +1300 Subject: [PATCH 20/21] adapted test outputs to the new behaviour: suggesting adding the parameter to the impl struct and the struct definition if used in the impl body Signed-off-by: janwi_mac --- .../hr-do-not-blame-outlives-static-ice.stderr | 9 +++++++++ tests/ui/associated-types/issue-26262.stderr | 9 +++++++++ .../unconstrained-lifetime-assoc-type.stderr | 9 +++++++++ .../ice-unexpected-inference-var-122549.stderr | 8 ++++++++ .../normalizing_with_unconstrained_impl_params.stderr | 8 ++++++++ tests/ui/error-codes/E0207.stderr | 9 +++++++++ .../ui/generic-associated-types/bugs/issue-87735.stderr | 9 +++++++++ tests/ui/issues/issue-22886.stderr | 9 +++++++++ tests/ui/issues/issue-35139.stderr | 9 +++++++++ ...constrained-projection-normalization-2.current.stderr | 9 +++++++++ .../unconstrained-projection-normalization-2.next.stderr | 9 +++++++++ ...unconstrained-projection-normalization.current.stderr | 9 +++++++++ .../unconstrained-projection-normalization.next.stderr | 9 +++++++++ .../ice-failed-to-resolve-instance-for-110696.stderr | 9 +++++++++ 14 files changed, 124 insertions(+) diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr index 4c0726d4ddca9..bada38b639dbf 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr @@ -12,6 +12,15 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Foo { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Foo { + | ++++ +help: and add it to the struct definition of Foo as well since it's used in the body of the impl + | +LL | struct Foo(T); + | ++++ error[E0308]: mismatched types --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 diff --git a/tests/ui/associated-types/issue-26262.stderr b/tests/ui/associated-types/issue-26262.stderr index 90e2d0d930164..fd0cabaa67a25 100644 --- a/tests/ui/associated-types/issue-26262.stderr +++ b/tests/ui/associated-types/issue-26262.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl S { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl S { + | +++ +help: and add it to the struct definition of S as well since it's used in the body of the impl + | +LL | struct S(T); + | +++ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-26262.rs:17:6 diff --git a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr index 15d0820c895dd..0087e69672cb9 100644 --- a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr +++ b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr @@ -3,6 +3,15 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Fun for Holder { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Fun for Holder<'a> { + | ++++ +help: and add it to the struct definition of Holder as well since it's used in the body of the impl + | +LL | struct Holder<'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr b/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr index 311caaede09af..f20c9ab7273d1 100644 --- a/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr +++ b/tests/ui/const-generics/ice-unexpected-inference-var-122549.stderr @@ -71,6 +71,14 @@ LL | impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, {}> { | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: make use of the type parameter `N` in the `self` type + | +LL | impl<'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, {}, N> { + | +++ +help: and add it to the struct definition of ConstChunksExact as well since it's used in the body of the impl + | +LL | struct ConstChunksExact<'rem, T: 'a, const N: usize, N> {} + | +++ error: aborting due to 8 previous errors diff --git a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr index ad89705e1dca8..b084601278956 100644 --- a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr +++ b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr @@ -53,6 +53,14 @@ LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact< | = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +help: make use of the type parameter `N` in the `self` type + | +LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}, N> { + | +++ +help: and add it to the struct definition of ConstChunksExact as well since it's used in the body of the impl + | +LL | struct ConstChunksExact<'a, T: '_, const assert: usize, N> {} + | +++ error[E0308]: mismatched types --> $DIR/normalizing_with_unconstrained_impl_params.rs:6:27 diff --git a/tests/ui/error-codes/E0207.stderr b/tests/ui/error-codes/E0207.stderr index 01d7c41854412..6d656a6b8c5f7 100644 --- a/tests/ui/error-codes/E0207.stderr +++ b/tests/ui/error-codes/E0207.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Foo { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Foo { + | +++ +help: and add it to the struct definition of Foo as well since it's used in the body of the impl + | +LL | struct Foo; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr index c3f4f7a73f35f..3e3258d8bedf4 100644 --- a/tests/ui/generic-associated-types/bugs/issue-87735.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self | LL | impl<'b, T, U> AsRef2 for Foo | ^ unconstrained type parameter + | +help: make use of the type parameter `U` in the `self` type + | +LL | impl<'b, T, U> AsRef2 for Foo + | +++ +help: and add it to the struct definition of Foo as well since it's used in the body of the impl + | +LL | struct Foo(T); + | +++ error[E0309]: the parameter type `U` may not live long enough --> $DIR/issue-87735.rs:34:3 diff --git a/tests/ui/issues/issue-22886.stderr b/tests/ui/issues/issue-22886.stderr index a04fa677f9ec5..0d27b14e0a2a1 100644 --- a/tests/ui/issues/issue-22886.stderr +++ b/tests/ui/issues/issue-22886.stderr @@ -3,6 +3,15 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Iterator for Newtype { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> Iterator for Newtype<'a> { + | ++++ +help: and add it to the struct definition of Newtype as well since it's used in the body of the impl + | +LL | struct Newtype<'a>(Option>); + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-35139.stderr b/tests/ui/issues/issue-35139.stderr index 875af70483224..c6af22100360c 100644 --- a/tests/ui/issues/issue-35139.stderr +++ b/tests/ui/issues/issue-35139.stderr @@ -3,6 +3,15 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter + | +help: make use of the lifetime parameter `'a` in the `self` type + | +LL | impl<'a> MethodType for MTFn<'a> { + | ++++ +help: and add it to the struct definition of MTFn as well since it's used in the body of the impl + | +LL | pub struct MTFn<'a>; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 9ce0e8d957dab..ee178fd5720e7 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ +help: and add it to the struct definition of Thing as well since it's used in the body of the impl + | +LL | struct Thing; + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization-2.rs:16:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 2da655afa935c..6cabb1ad1216a 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ +help: and add it to the struct definition of Thing as well since it's used in the body of the impl + | +LL | struct Thing; + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization-2.rs:16:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization.current.stderr b/tests/ui/traits/unconstrained-projection-normalization.current.stderr index c52e8dd68aa87..f2b1a30ff111e 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.current.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ +help: and add it to the struct definition of Thing as well since it's used in the body of the impl + | +LL | struct Thing; + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization.rs:15:18 diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index c52e8dd68aa87..f2b1a30ff111e 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Every for Thing { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl Every for Thing { + | +++ +help: and add it to the struct definition of Thing as well since it's used in the body of the impl + | +LL | struct Thing; + | +++ error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unconstrained-projection-normalization.rs:15:18 diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr index d18a824287c0c..4a06b95485690 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr @@ -3,6 +3,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl>>, U> MyIndex> for Scope { | ^ unconstrained type parameter + | +help: make use of the type parameter `T` in the `self` type + | +LL | impl>>, U> MyIndex> for Scope { + | +++ +help: and add it to the struct definition of Scope as well since it's used in the body of the impl + | +LL | struct Scope(Phantom2>); + | +++ error: item does not constrain `DummyT::{opaque#0}` --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:30:8 From 7664723dcbfa729df6714f7c59bf6960c0a81927 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 11 Mar 2026 16:28:32 +1300 Subject: [PATCH 21/21] fixed test Signed-off-by: janwi_mac --- .../inherent-assoc-ty-mismatch-issue-153539.stderr | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr b/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr index 74d88889223f3..459f5f4c6d68f 100644 --- a/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr +++ b/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr @@ -2,7 +2,10 @@ error[E0207]: the type parameter `X` is not constrained by the impl trait, self --> $DIR/inherent-assoc-ty-mismatch-issue-153539.rs:9:6 | LL | impl S<'_> { - | ^ unconstrained type parameter + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `X` error[E0308]: mismatched types --> $DIR/inherent-assoc-ty-mismatch-issue-153539.rs:17:5