From c18b48e862f4bd8215968c392739f0923e7400f3 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:31:52 +0100 Subject: [PATCH 1/7] Fix unconstrained parameter issue --- compiler/rustc_hir/src/hir.rs | 55 +++++++ .../rustc_hir_analysis/src/impl_wf_check.rs | 139 +++++++++++++++++- 2 files changed, 191 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 62013958c7e55..f091fdf256552 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1066,6 +1066,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 cadbc54c34108..f8d85463a1f6d 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -9,14 +9,18 @@ //! fixed, but for the moment it's easier to do these checks early. use std::assert_matches::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 +176,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 +246,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 73b49d761455bde4a262501e28d077814f561f9d Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:32:11 +0100 Subject: [PATCH 2/7] 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 fb612ef8af15098ec68852d1fb7be200f99d60e4 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:40:43 +0100 Subject: [PATCH 3/7] 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 1230bc707f877e3d81cc2bd3cb7f0325c7a7cc06 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 15:16:39 +0100 Subject: [PATCH 4/7] 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 c61a0863a6b31..ad1489a978cbc 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:22: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_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr index 4106c500215b9..ea30e6380a35a 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr +++ b/tests/ui/const-generics/associated_const_equality/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 fd53c9fef4434..786240335e5a0 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 3bf7583d9b4eedd66cab3f261d29a92fab8aa615 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 18:02:24 +0100 Subject: [PATCH 5/7] 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 c8905fab45760859c6478c3c7d8cb28eb7e88f56 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 23:17:32 +0100 Subject: [PATCH 6/7] 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 de845c2c7619153846699f2aa3d69c256064b083 Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Wed, 12 Nov 2025 14:35:12 +0100 Subject: [PATCH 7/7] 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 f8d85463a1f6d..282451b17c7f1 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -25,6 +25,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; @@ -253,8 +254,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. @@ -270,10 +270,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 { @@ -318,12 +316,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);