diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 472fe8e777d2..815190abca7e 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -416,6 +416,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 bb7f2755b105..cc32c54550e9 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -322,6 +322,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); @@ -334,6 +337,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 { @@ -344,6 +348,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 f3cd1eab73db..39473f77e7b7 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