about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-07-19 14:21:30 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-07-19 14:21:56 +0000
commita0db06bdebfef83b4424415bd6e64cfb5bdcc978 (patch)
tree525832fa4efa062d4116f3201723fcdce490eb48 /compiler/rustc_hir_analysis/src
parent3d68afc9e821b00d59058abc9bda670b07639955 (diff)
downloadrust-a0db06bdebfef83b4424415bd6e64cfb5bdcc978.tar.gz
rust-a0db06bdebfef83b4424415bd6e64cfb5bdcc978.zip
Use structured suggestions for unconstrained generic parameters on impl blocks
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs76
2 files changed, 34 insertions, 56 deletions
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 03311fed396..8e88f33a079 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1605,6 +1605,20 @@ pub(crate) enum UnusedGenericParameterHelp {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_unconstrained_generic_parameter)]
+pub(crate) struct UnconstrainedGenericParameter {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub param_name: Symbol,
+    pub param_def_kind: &'static str,
+    #[note(hir_analysis_const_param_note)]
+    pub const_param_note: Option<()>,
+    #[note(hir_analysis_const_param_note2)]
+    pub const_param_note2: Option<()>,
+}
+
+#[derive(Diagnostic)]
 pub enum UnnamedFieldsRepr<'a> {
     #[diag(hir_analysis_unnamed_fields_repr_missing_repr_c)]
     MissingReprC {
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 5cc1ec71757..f0fcbd5528f 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -8,15 +8,15 @@
 //! specialization errors. These things can (and probably should) be
 //! fixed, but for the moment it's easier to do these checks early.
 
-use crate::constrained_generic_params as cgp;
+use crate::{constrained_generic_params as cgp, errors::UnconstrainedGenericParameter};
 use min_specialization::check_min_specialization;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{codes::*, struct_span_code_err};
+use rustc_errors::codes::*;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
-use rustc_span::{ErrorGuaranteed, Span, Symbol};
+use rustc_span::ErrorGuaranteed;
 
 mod min_specialization;
 
@@ -117,43 +117,34 @@ fn enforce_impl_params_are_constrained(
 
     let mut res = Ok(());
     for param in &impl_generics.own_params {
-        match param.kind {
+        let err = match param.kind {
             // Disallow ANY unconstrained type parameters.
             ty::GenericParamDefKind::Type { .. } => {
                 let param_ty = ty::ParamTy::for_def(param);
-                if !input_parameters.contains(&cgp::Parameter::from(param_ty)) {
-                    res = Err(report_unused_parameter(
-                        tcx,
-                        tcx.def_span(param.def_id),
-                        "type",
-                        param_ty.name,
-                    ));
-                }
+                !input_parameters.contains(&cgp::Parameter::from(param_ty))
             }
             ty::GenericParamDefKind::Lifetime => {
                 let param_lt = cgp::Parameter::from(param.to_early_bound_region_data());
-                if lifetimes_in_associated_types.contains(&param_lt) && // (*)
+                lifetimes_in_associated_types.contains(&param_lt) && // (*)
                     !input_parameters.contains(&param_lt)
-                {
-                    res = Err(report_unused_parameter(
-                        tcx,
-                        tcx.def_span(param.def_id),
-                        "lifetime",
-                        param.name,
-                    ));
-                }
             }
             ty::GenericParamDefKind::Const { .. } => {
                 let param_ct = ty::ParamConst::for_def(param);
-                if !input_parameters.contains(&cgp::Parameter::from(param_ct)) {
-                    res = Err(report_unused_parameter(
-                        tcx,
-                        tcx.def_span(param.def_id),
-                        "const",
-                        param_ct.name,
-                    ));
-                }
+                !input_parameters.contains(&cgp::Parameter::from(param_ct))
             }
+        };
+        if err {
+            let const_param_note =
+                matches!(param.kind, ty::GenericParamDefKind::Const { .. }).then_some(());
+            let mut diag = tcx.dcx().create_err(UnconstrainedGenericParameter {
+                span: tcx.def_span(param.def_id),
+                param_name: param.name,
+                param_def_kind: tcx.def_descr(param.def_id),
+                const_param_note,
+                const_param_note2: const_param_note,
+            });
+            diag.code(E0207);
+            res = Err(diag.emit());
         }
     }
     res
@@ -177,30 +168,3 @@ fn enforce_impl_params_are_constrained(
     // associated types. I believe this is sound, because lifetimes
     // used elsewhere are not projected back out.
 }
-
-fn report_unused_parameter(
-    tcx: TyCtxt<'_>,
-    span: Span,
-    kind: &str,
-    name: Symbol,
-) -> ErrorGuaranteed {
-    let mut err = struct_span_code_err!(
-        tcx.dcx(),
-        span,
-        E0207,
-        "the {} parameter `{}` is not constrained by the \
-        impl trait, self type, or predicates",
-        kind,
-        name
-    );
-    err.span_label(span, format!("unconstrained {kind} parameter"));
-    if kind == "const" {
-        err.note(
-            "expressions using a const parameter must map each value to a distinct output value",
-        );
-        err.note(
-            "proving the result of expressions other than the parameter are unique is not supported",
-        );
-    }
-    err.emit()
-}