diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index ea6080819499..1d0b4c5b18ae 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 c30c13434171..01791e8ff89f 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 fa3e6ba4c757..300f2ea49508 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 22f746f91523..6db1e85ccfa6 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 a2b83b728765..349fddcafe8b 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 78faa5398ca2..0c1ba5851e10 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 045c30d94134..8d7ad1b84897 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