From cfc3f0f27157d2af2cb114153c22ca341c25e93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 10 Jan 2024 03:00:50 +0100 Subject: [PATCH] Actually print the overly generic type --- compiler/rustc_hir_analysis/messages.ftl | 2 ++ .../rustc_hir_analysis/src/collect/type_of.rs | 5 +++++ compiler/rustc_hir_analysis/src/errors.rs | 15 +++++++++++++-- .../assoc-const-eq-esc-bound-var-in-ty.rs | 1 + .../assoc-const-eq-esc-bound-var-in-ty.stderr | 2 ++ .../assoc-const-eq-param-in-ty.rs | 4 ++++ .../assoc-const-eq-param-in-ty.stderr | 12 ++++++++++-- 7 files changed, 37 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index ea60808194992..1d0b4c5b18ae8 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -420,6 +420,8 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de .label = needs at most one field with non-trivial size or alignment, but has {$field_count} .labels = this field has non-zero size or requires alignment +hir_analysis_ty_of_assoc_const_binding_note = `{$assoc_const}` has type `{$ty}` + hir_analysis_ty_param_first_local = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`) .label = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`) .note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c30c134341716..01791e8ff89f6 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -319,6 +319,9 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>( } let mut reported = None; + let ty_note = ty + .make_suggestable(tcx, false) + .map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty }); let body_owner = tcx.hir().enclosing_body_owner(hir_id); let generics = tcx.generics_of(body_owner); @@ -331,6 +334,7 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>( param_def_kind: tcx.def_descr(param_def.def_id), synthetic: param_def.kind.is_synthetic(), param_defined_here_label: tcx.def_ident_span(param_def.def_id).unwrap(), + ty_note, })); } for (var_def_id, var_name) in collector.vars { @@ -341,6 +345,7 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>( var_name, var_def_kind: tcx.def_descr(var_def_id), var_defined_here_label: tcx.def_ident_span(var_def_id).unwrap(), + ty_note, }, )); } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index fa3e6ba4c757d..300f2ea49508d 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -256,7 +256,7 @@ pub struct AssocTypeBindingNotAllowed { #[derive(Diagnostic)] #[diag(hir_analysis_param_in_ty_of_assoc_const_binding)] -pub(crate) struct ParamInTyOfAssocConstBinding { +pub(crate) struct ParamInTyOfAssocConstBinding<'tcx> { #[primary_span] #[label] pub span: Span, @@ -266,11 +266,13 @@ pub(crate) struct ParamInTyOfAssocConstBinding { pub synthetic: bool, #[label(hir_analysis_param_defined_here_label)] pub param_defined_here_label: Span, + #[subdiagnostic] + pub ty_note: Option>, } #[derive(Diagnostic)] #[diag(hir_analysis_escaping_bound_var_in_ty_of_assoc_const_binding)] -pub(crate) struct EscapingBoundVarInTyOfAssocConstBinding { +pub(crate) struct EscapingBoundVarInTyOfAssocConstBinding<'tcx> { #[primary_span] #[label] pub span: Span, @@ -279,6 +281,15 @@ pub(crate) struct EscapingBoundVarInTyOfAssocConstBinding { pub var_def_kind: &'static str, #[label(hir_analysis_var_defined_here_label)] pub var_defined_here_label: Span, + #[subdiagnostic] + pub ty_note: Option>, +} + +#[derive(Subdiagnostic, Clone, Copy)] +#[note(hir_analysis_ty_of_assoc_const_binding_note)] +pub(crate) struct TyOfAssocConstBindingNote<'tcx> { + pub assoc_const: Ident, + pub ty: Ty<'tcx>, } #[derive(Subdiagnostic)] diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 22f746f91523f..6db1e85ccfa6a 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -10,5 +10,6 @@ fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} //~^ ERROR the type of the associated constant `K` cannot capture late-bound generic parameters //~| NOTE its type cannot capture the late-bound lifetime parameter `'r` //~| NOTE the late-bound lifetime parameter `'r` is defined here +//~| NOTE `K` has type `&'r ()` fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr index a2b83b728765c..349fddcafe8b7 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr @@ -5,6 +5,8 @@ LL | fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` | | | the late-bound lifetime parameter `'r` is defined here + | + = note: `K` has type `&'r ()` error: aborting due to 1 previous error diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 78faa5398ca24..0c1ba5851e109 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -10,12 +10,15 @@ fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} //~^ ERROR the type of the associated constant `K` must not depend on generic parameters //~| NOTE its type must not depend on the lifetime parameter `'r` //~| NOTE the lifetime parameter `'r` is defined here +//~| NOTE `K` has type `&'r [A; Q]` //~| ERROR the type of the associated constant `K` must not depend on generic parameters //~| NOTE its type must not depend on the type parameter `A` //~| NOTE the type parameter `A` is defined here +//~| NOTE `K` has type `&'r [A; Q]` //~| ERROR the type of the associated constant `K` must not depend on generic parameters //~| NOTE its type must not depend on the const parameter `Q` //~| NOTE the const parameter `Q` is defined here +//~| NOTE `K` has type `&'r [A; Q]` trait Project { const SELF: Self; @@ -30,5 +33,6 @@ fn take2>(_: P) {} //~^ ERROR the type of the associated constant `SELF` must not depend on generic parameters //~| NOTE its type must not depend on the type parameter `P` //~| NOTE the type parameter `P` is defined here +//~| NOTE `SELF` has type `P` fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index 045c30d941344..8d7ad1b848979 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -3,12 +3,16 @@ error: the type of the associated constant `K` must not depend on generic parame | LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` + | + = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters --> $DIR/assoc-const-eq-param-in-ty.rs:9:61 | LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` + | + = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters --> $DIR/assoc-const-eq-param-in-ty.rs:9:61 @@ -17,9 +21,11 @@ LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} } | - ^ its type must not depend on the const parameter `Q` | | | the const parameter `Q` is defined here + | + = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:24:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:27:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------ @@ -28,12 +34,14 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:29:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:32:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` | | | the type parameter `P` is defined here + | + = note: `SELF` has type `P` error: aborting due to 5 previous errors