From d38acdb2317d1d323065f1920c837c26c5d24dea Mon Sep 17 00:00:00 2001 From: janwi_mac Date: Mon, 10 Nov 2025 14:31:52 +0100 Subject: [PATCH] Improve suggestions for unconstrained parameters in `impl` blocks When an unconstrained type or lifetime parameter is detected in an `impl`, provide more specific help based on its usage: - If the parameter is entirely unused, suggest removing it. - If it is used in the `impl` body but not the `Self` type, suggest including it in the `Self` type and the struct definition. This also adds a comprehensive UI test for these cases. --- compiler/rustc_hir/src/hir.rs | 87 ++++++++ compiler/rustc_hir_analysis/src/errors.rs | 2 + .../src/errors/remove_or_use_generic.rs | 211 ++++++++++++++++++ .../rustc_hir_analysis/src/impl_wf_check.rs | 3 + .../not-wf-ambiguous-normalization.stderr | 5 +- ...constrained-param-in-impl-ambiguity.stderr | 5 +- ...hr-do-not-blame-outlives-static-ice.stderr | 7 + ...rent-assoc-ty-mismatch-issue-153539.stderr | 5 +- ...opaque-inherent-fn-ptr-issue-155204.stderr | 5 +- .../next-solver-opaque-inherent-no-ice.stderr | 5 +- tests/ui/associated-types/issue-26262.stderr | 9 + .../unconstrained-lifetime-assoc-type.stderr | 9 + .../issues/issue-78654.full.stderr | 5 +- .../async-await/issues/issue-78654.min.stderr | 5 +- .../unsized-anon-const-err-2.stderr | 10 +- ...post-analysis-user-facing-param-env.stderr | 5 +- ...ice-unexpected-inference-var-122549.stderr | 8 + .../issues/issue-68366.full.stderr | 10 +- .../issues/issue-68366.min.stderr | 10 +- ...zing_with_unconstrained_impl_params.stderr | 8 + .../unconstrained_const_param_on_drop.stderr | 5 +- tests/ui/error-codes/E0207.stderr | 7 + .../bugs/issue-87735.stderr | 9 + .../bugs/issue-88526.stderr | 5 +- .../unconstrained-param-default-available.rs | 18 ++ ...constrained-param-default-available.stderr | 35 +++ ...nstrained-type-params-inherent-impl.stderr | 10 +- tests/ui/generics/unconstrained-used-param.rs | 23 ++ .../generics/unconstrained-used-param.stderr | 29 +++ tests/ui/issues/issue-16562.stderr | 5 +- tests/ui/issues/issue-22886.stderr | 7 + tests/ui/issues/issue-35139.stderr | 7 + .../auxiliary/generics_other_crate.rs | 4 + tests/ui/suggestions/unconstrained-params.rs | 54 +++++ .../suggestions/unconstrained-params.stderr | 68 ++++++ .../leaking-vars-in-cause-code-2.stderr | 5 +- ...-projection-normalization-2.current.stderr | 9 + ...ned-projection-normalization-2.next.stderr | 9 + ...ed-projection-normalization.current.stderr | 9 + ...ained-projection-normalization.next.stderr | 9 + ...iled-to-resolve-instance-for-110696.stderr | 9 + .../type-alias-impl-trait/issue-74244.stderr | 5 +- 42 files changed, 734 insertions(+), 21 deletions(-) create mode 100644 compiler/rustc_hir_analysis/src/errors/remove_or_use_generic.rs 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 create mode 100644 tests/ui/suggestions/auxiliary/generics_other_crate.rs create mode 100644 tests/ui/suggestions/unconstrained-params.rs create mode 100644 tests/ui/suggestions/unconstrained-params.stderr diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 9f1a20355f7de..66ba1112d346f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1087,6 +1087,93 @@ impl<'hir> Generics<'hir> { bound_span.with_lo(bounds[bound_pos - 1].span().hi()) } } + + /// 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(); + } + + let is_param_explicit = |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_param_explicit) { + self.params[param_index].span.until(next.span) + } else if let Some(prev) = self.params[..param_index].iter().rfind(is_param_explicit) { + 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 + } + } + + /// 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() + .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/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1bb54f27dcbdd..ae42a9bb06fe2 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..41d22ff041853 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/errors/remove_or_use_generic.rs @@ -0,0 +1,211 @@ +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 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 last_param_span = if let Some(local_def_id) = struct_def_id.as_local() { + let hir_struct = tcx.hir_node_by_def_id(local_def_id).expect_item().expect_struct(); + hir_struct.1.params.last().map(|param| param.span) + } else { + let generics = tcx.generics_of(struct_def_id); + generics.own_params.last().map(|param| tcx.def_span(param.def_id)) + }; + + if let Some(last_param_span) = last_param_span { + 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!( + "use the {} parameter `{}` in the `{}` type and use it in the type definition", + parameter_type, + param.name, + tcx.def_path_str(struct_def_id) + ); + diag.multipart_suggestion( + msg, + vec![ + (suggestions[0].0, suggestions[0].1.clone()), + (suggestions[1].0, 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 use 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 82081fd40a274..bbb40ef0a87ad 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -21,6 +21,7 @@ use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; use crate::errors::UnconstrainedGenericParameter; +use crate::errors::remove_or_use_generic::suggest_to_remove_or_use_generic; mod min_specialization; @@ -177,6 +178,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( ); } } + suggest_to_remove_or_use_generic(tcx, &mut diag, impl_def_id, param, true); res = Err(diag.emit()); } } @@ -242,6 +244,7 @@ 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, false); res = Err(diag.emit()); } } diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr index 55ab144b92419..b19d965e7c198 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -2,7 +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 + | -^- + | || + | |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 38d1a537fe458..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,7 +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 + | -^-------- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `Q` error: aborting due to 1 previous error 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 b06add2f5db5d..efb8a38e09955 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 @@ -3,6 +3,13 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Foo { | ^^ unconstrained lifetime parameter + | +help: use the lifetime parameter `'a` in the `Foo` type and use it in the type definition + | +LL ~ struct Foo(T); +LL | +LL ~ impl<'a> Foo { + | error[E0308]: mismatched types --> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:11 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 diff --git a/tests/ui/associated-inherent-types/next-solver-opaque-inherent-fn-ptr-issue-155204.stderr b/tests/ui/associated-inherent-types/next-solver-opaque-inherent-fn-ptr-issue-155204.stderr index 8974ed53bc0fa..9bdcbac7264da 100644 --- a/tests/ui/associated-inherent-types/next-solver-opaque-inherent-fn-ptr-issue-155204.stderr +++ b/tests/ui/associated-inherent-types/next-solver-opaque-inherent-fn-ptr-issue-155204.stderr @@ -27,7 +27,10 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:7:6 | LL | impl Windows { - | ^ unconstrained type parameter + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `T` error[E0282]: type annotations needed --> $DIR/next-solver-opaque-inherent-fn-ptr-issue-155204.rs:12:22 diff --git a/tests/ui/associated-inherent-types/next-solver-opaque-inherent-no-ice.stderr b/tests/ui/associated-inherent-types/next-solver-opaque-inherent-no-ice.stderr index 03f369359c0d8..416466d197004 100644 --- a/tests/ui/associated-inherent-types/next-solver-opaque-inherent-no-ice.stderr +++ b/tests/ui/associated-inherent-types/next-solver-opaque-inherent-no-ice.stderr @@ -24,7 +24,10 @@ error[E0207]: the const parameter `X` is not constrained by the impl trait, self --> $DIR/next-solver-opaque-inherent-no-ice.rs:6:6 | LL | impl Foo { - | ^^^^^^^^^^ unconstrained const parameter + | -^^^^^^^^^^- + | || + | |unconstrained const parameter + | help: remove the unused type parameter `X` | = 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 diff --git a/tests/ui/associated-types/issue-26262.stderr b/tests/ui/associated-types/issue-26262.stderr index 90e2d0d930164..4ac7416755039 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: use the type parameter `T` in the `S` type and use it in the type definition + | +LL ~ struct S(T); +LL | +LL | trait Tr { type Assoc; fn test(); } +LL | +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 diff --git a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr index 15d0820c895dd..e190dfdbf70b8 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: use the lifetime parameter `'a` in the `Holder` type and use it in the type definition + | +LL ~ struct Holder<'a> { +LL | x: String, +LL | } +LL | +LL ~ impl<'a> Fun for Holder<'a> { + | 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..e1f9aa9ce81e7 100644 --- a/tests/ui/async-await/issues/issue-78654.full.stderr +++ b/tests/ui/async-await/issues/issue-78654.full.stderr @@ -8,7 +8,10 @@ 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 diff --git a/tests/ui/async-await/issues/issue-78654.min.stderr b/tests/ui/async-await/issues/issue-78654.min.stderr index 0d12a948c68bd..e1f9aa9ce81e7 100644 --- a/tests/ui/async-await/issues/issue-78654.min.stderr +++ b/tests/ui/async-await/issues/issue-78654.min.stderr @@ -8,7 +8,10 @@ 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 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 8112613f3bf80..f304bfc8e4cec 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 @@ -37,7 +37,10 @@ error[E0207]: the const parameter `N` is not constrained by the impl trait, self --> $DIR/unsized-anon-const-err-2.rs:13: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 @@ -46,7 +49,10 @@ error[E0207]: the const parameter `M` is not constrained by the impl trait, self --> $DIR/unsized-anon-const-err-2.rs:16: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 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 d58bc67232758..d214c31675a3b 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 @@ -24,7 +24,10 @@ error[E0207]: the const parameter `NUM` is not constrained by the impl trait, se --> $DIR/post-analysis-user-facing-param-env.rs:5: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 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..e4287fae20f1f 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: use the type parameter `N` in the `ConstChunksExact` type and use it in the type definition + | +LL ~ struct ConstChunksExact<'rem, T: 'a, const N: usize, N> {} +LL | +LL | +LL | +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 02c34b8256d6d..53e42b1219732 100644 --- a/tests/ui/const-generics/issues/issue-68366.full.stderr +++ b/tests/ui/const-generics/issues/issue-68366.full.stderr @@ -14,7 +14,10 @@ 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 @@ -23,7 +26,10 @@ error[E0207]: the const parameter `N` is not constrained by the impl trait, self --> $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 diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index 4b544c49af8c1..40bf7dc6deeab 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -23,7 +23,10 @@ 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 @@ -32,7 +35,10 @@ error[E0207]: the const parameter `N` is not constrained by the impl trait, self --> $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 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..f5a57f864564d 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: use the type parameter `N` in the `ConstChunksExact` type and use it in the type definition + | +LL ~ struct ConstChunksExact<'a, T: '_, const assert: usize, N> {} +LL | +LL | +LL | +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..6cf78a06752ba 100644 --- a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr +++ b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr @@ -22,7 +22,10 @@ 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 diff --git a/tests/ui/error-codes/E0207.stderr b/tests/ui/error-codes/E0207.stderr index 01d7c41854412..97e2fa0ae3f45 100644 --- a/tests/ui/error-codes/E0207.stderr +++ b/tests/ui/error-codes/E0207.stderr @@ -3,6 +3,13 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self | LL | impl Foo { | ^ unconstrained type parameter + | +help: use the type parameter `T` in the `Foo` type and use it in the type definition + | +LL ~ struct Foo; +LL | +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..60e1d71cdac7d 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: use the type parameter `U` in the `Foo` type and use it in the type definition + | +LL ~ struct Foo(T); +LL | #[derive(Debug)] +LL | struct FooRef<'a, U>(&'a [U]); +LL | +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..ea2962c693f0a 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88526.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr @@ -2,7 +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 + | ^-- + | | + | 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-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..f1eac56b366cf --- /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 use 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 use 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-type-params-inherent-impl.stderr b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr index 19b02ad396cd3..958b1ff0664ab 100644 --- a/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr +++ b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr @@ -2,13 +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 + | -^- + | || + | |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 + | --^ + | | | + | | unconstrained type parameter + | help: remove the unused type parameter `U` error: aborting due to 2 previous errors 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..b0d9320602b2f --- /dev/null +++ b/tests/ui/generics/unconstrained-used-param.stderr @@ -0,0 +1,29 @@ +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: use the type parameter `T` in the `S` type and use it in the type definition + | +LL ~ struct S; +LL ~ impl 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: use the type parameter `T` in the `S2` type and use it in the type definition + | +LL ~ struct S2 { +LL | _f: F, +LL | } +LL ~ impl S2 { + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/issues/issue-16562.stderr b/tests/ui/issues/issue-16562.stderr index efbd7f712a45a..ac957fdb069d0 100644 --- a/tests/ui/issues/issue-16562.stderr +++ b/tests/ui/issues/issue-16562.stderr @@ -2,7 +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 + | ^-- + | | + | unconstrained type parameter + | help: remove the unused type parameter `T` 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..aebbdf8a2ec12 100644 --- a/tests/ui/issues/issue-22886.stderr +++ b/tests/ui/issues/issue-22886.stderr @@ -3,6 +3,13 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Iterator for Newtype { | ^^ unconstrained lifetime parameter + | +help: use the lifetime parameter `'a` in the `Newtype` type and use it in the type definition + | +LL ~ struct Newtype<'a>(Option>); +LL | +LL ~ impl<'a> Iterator for Newtype<'a> { + | 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..4568b9b70f412 100644 --- a/tests/ui/issues/issue-35139.stderr +++ b/tests/ui/issues/issue-35139.stderr @@ -3,6 +3,13 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter + | +help: use the lifetime parameter `'a` in the `MTFn` type and use it in the type definition + | +LL ~ pub struct MTFn<'a>; +LL | +LL ~ impl<'a> MethodType for MTFn<'a> { + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/auxiliary/generics_other_crate.rs b/tests/ui/suggestions/auxiliary/generics_other_crate.rs new file mode 100644 index 0000000000000..2345257eddfb8 --- /dev/null +++ b/tests/ui/suggestions/auxiliary/generics_other_crate.rs @@ -0,0 +1,4 @@ +//! This file is used to test suggestions for generics in other crates. + +pub struct External; +pub struct ExternalGeneric(T); diff --git a/tests/ui/suggestions/unconstrained-params.rs b/tests/ui/suggestions/unconstrained-params.rs new file mode 100644 index 0000000000000..4983ee6330c34 --- /dev/null +++ b/tests/ui/suggestions/unconstrained-params.rs @@ -0,0 +1,54 @@ +//@ aux-build:generics_other_crate.rs + +extern crate generics_other_crate; +use generics_other_crate::External; + +struct Local; +struct Defaulted(T); + +// Case 1: Unused parameter -> suggests removing T +impl Local {} +//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates +//~| HELP: remove the unused type parameter `T` + +// Case 2: T used in body but not in self type +// -> suggests adding T to self type and struct definition +impl Local { + //~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates + //~| HELP: use the type parameter `T` in the `Local` type and use it in the type definition + fn check() { + let _: T; + } +} + + +// Case 3: Struct has a generic parameter with a default +// -> suggests adding T to the self type +impl Defaulted {} +//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates +//~| HELP: either remove the unused type parameter `T` +//~| HELP: or use it + +// Case 4: Generated from a macro +macro_rules! make_impl { + ($t:ident) => { + impl<$t> Local {} + //~^ HELP: remove the unused type parameter `U` + } +} +make_impl!(U); +//~^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates + +// Case 5: Type defined in another crate +impl External { + //~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates + //~| ERROR: cannot define inherent `impl` for a type outside of the crate where the type is defined [E0116] + //~| HELP: use the type parameter `T` in the `External` type and use it in the type definition + //~| HELP: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + fn check() { + let _: T; + } +} + + +fn main() {} diff --git a/tests/ui/suggestions/unconstrained-params.stderr b/tests/ui/suggestions/unconstrained-params.stderr new file mode 100644 index 0000000000000..f6f899a93055e --- /dev/null +++ b/tests/ui/suggestions/unconstrained-params.stderr @@ -0,0 +1,68 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-params.rs:10:6 + | +LL | impl Local {} + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `T` + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-params.rs:16:6 + | +LL | impl Local { + | ^ unconstrained type parameter + | +help: use the type parameter `T` in the `Local` type and use it in the type definition + | +LL ~ struct Local; +LL | struct Defaulted(T); +... +LL | // -> suggests adding T to self type and struct definition +LL ~ impl Local { + | + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-params.rs:27:6 + | +LL | impl Defaulted {} + | ^ unconstrained type parameter + | +help: either remove the unused type parameter `T` + | +LL - impl Defaulted {} +LL + impl Defaulted {} + | +help: or use it + | +LL | impl Defaulted {} + | +++ + +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-params.rs:39:12 + | +LL | impl<$t> Local {} + | ---- help: remove the unused type parameter `U` +... +LL | make_impl!(U); + | ^ unconstrained type parameter + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-params.rs:43:6 + | +LL | impl External { + | ^ unconstrained type parameter + +error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined + --> $DIR/unconstrained-params.rs:43:1 + | +LL | impl External { + | ^^^^^^^^^^^^^^^^ impl for type defined outside of crate + | + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0116, E0207. +For more information about an error, try `rustc --explain E0116`. 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..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,7 +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 + | --^ + | | | + | | 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/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 9ce0e8d957dab..e8742e7f09902 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: use the type parameter `T` in the `Thing` type and use it in the type definition + | +LL ~ struct Thing; +LL | +... +LL | } +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..0944e31ca38c0 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: use the type parameter `T` in the `Thing` type and use it in the type definition + | +LL ~ struct Thing; +LL | +... +LL | } +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..6e908df0aba2d 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: use the type parameter `T` in the `Thing` type and use it in the type definition + | +LL ~ struct Thing; +LL | +... +LL | } +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..6e908df0aba2d 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: use the type parameter `T` in the `Thing` type and use it in the type definition + | +LL ~ struct Thing; +LL | +... +LL | } +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/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..4b050f362c9ca 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: use the type parameter `T` in the `Scope` type and use it in the type definition + | +LL ~ struct Scope(Phantom2>); +LL | +... +LL | +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/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr index f5ca56bacccf6..6e01425afec5e 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr @@ -2,7 +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 + | -^- + | || + | |unconstrained type parameter + | help: remove the unused type parameter `T` error: aborting due to 1 previous error