From e4cf708d2fff1ebc8aa7a21a1be152b5247206a1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 11 Aug 2023 21:27:52 +0000 Subject: [PATCH] Don't add associated type bound for non-types --- compiler/rustc_hir_analysis/messages.ftl | 3 ++ .../rustc_hir_analysis/src/astconv/bounds.rs | 29 ++++++++++++------- compiler/rustc_hir_analysis/src/errors.rs | 9 ++++++ tests/ui/associated-type-bounds/consts.rs | 10 +++++++ tests/ui/associated-type-bounds/consts.stderr | 10 +++++++ 5 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 tests/ui/associated-type-bounds/consts.rs create mode 100644 tests/ui/associated-type-bounds/consts.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 166760166c108..597cae6ff33ca 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -1,6 +1,9 @@ hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required +hir_analysis_assoc_bound_on_const = expected associated type, found {$descr} + .note = trait bounds not allowed on {$descr} + hir_analysis_assoc_type_binding_not_allowed = associated type bindings are not allowed here .label = associated type not allowed here diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index 30145b1a185ac..ba152cd48dea4 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -13,7 +13,7 @@ use crate::astconv::{ AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter, }; use crate::bounds::Bounds; -use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified}; +use crate::errors; impl<'tcx> dyn AstConv<'tcx> + '_ { /// Sets `implicitly_sized` to true on `Bounds` if necessary @@ -35,7 +35,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { if unbound.is_none() { unbound = Some(&ptr.trait_ref); } else { - tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span }); + tcx.sess.emit_err(errors::MultipleRelaxedDefaultBounds { span }); } } } @@ -326,7 +326,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { dup_bindings .entry(assoc_item.def_id) .and_modify(|prev_span| { - tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified { + tcx.sess.emit_err(errors::ValueOfAssociatedStructAlreadySpecified { span: binding.span, prev_span: *prev_span, item_name: binding.item_name, @@ -488,6 +488,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { } } + let assoc_item_def_id = projection_ty.skip_binder().def_id; + let def_kind = tcx.def_kind(assoc_item_def_id); match binding.kind { ConvertedBindingKind::Equality(..) if return_type_notation => { return Err(self.tcx().sess.emit_err( @@ -499,11 +501,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { // the "projection predicate" for: // // `::Item = u32` - let assoc_item_def_id = projection_ty.skip_binder().def_id; - let def_kind = tcx.def_kind(assoc_item_def_id); match (def_kind, term.unpack()) { - (hir::def::DefKind::AssocTy, ty::TermKind::Ty(_)) - | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (), + (DefKind::AssocTy, ty::TermKind::Ty(_)) + | (DefKind::AssocConst, ty::TermKind::Const(_)) => (), (_, _) => { let got = if let Some(_) = term.ty() { "type" } else { "constant" }; let expected = tcx.def_descr(assoc_item_def_id); @@ -516,7 +516,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { format!("{expected} defined here"), ); - if let hir::def::DefKind::AssocConst = def_kind + if let DefKind::AssocConst = def_kind && let Some(t) = term.ty() && (t.is_enum() || t.references_error()) && tcx.features().associated_const_equality { err.span_suggestion( @@ -528,8 +528,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { } let reported = err.emit(); term = match def_kind { - hir::def::DefKind::AssocTy => Ty::new_error(tcx, reported).into(), - hir::def::DefKind::AssocConst => ty::Const::new_error( + DefKind::AssocTy => Ty::new_error(tcx, reported).into(), + DefKind::AssocConst => ty::Const::new_error( tcx, reported, tcx.type_of(assoc_item_def_id) @@ -548,6 +548,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { ); } ConvertedBindingKind::Constraint(ast_bounds) => { + match def_kind { + DefKind::AssocTy => {} + _ => { + return Err(tcx.sess.emit_err(errors::AssocBoundOnConst { + span: assoc_ident.span, + descr: tcx.def_descr(assoc_item_def_id), + })); + } + } // "Desugar" a constraint like `T: Iterator` to // // `::Item: Debug` diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 0babdf7e5b3e7..9471ad9ca9063 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -918,3 +918,12 @@ pub struct UnusedAssociatedTypeBounds { #[suggestion(code = "")] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_assoc_bound_on_const)] +#[note] +pub struct AssocBoundOnConst { + #[primary_span] + pub span: Span, + pub descr: &'static str, +} diff --git a/tests/ui/associated-type-bounds/consts.rs b/tests/ui/associated-type-bounds/consts.rs new file mode 100644 index 0000000000000..9b95b1b52c05a --- /dev/null +++ b/tests/ui/associated-type-bounds/consts.rs @@ -0,0 +1,10 @@ +#![feature(associated_type_bounds)] + +pub fn accept(_: impl Trait) {} +//~^ ERROR expected associated type, found associated constant + +pub trait Trait { + const K: i32; +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/consts.stderr b/tests/ui/associated-type-bounds/consts.stderr new file mode 100644 index 0000000000000..ddfb6612b081f --- /dev/null +++ b/tests/ui/associated-type-bounds/consts.stderr @@ -0,0 +1,10 @@ +error: expected associated type, found associated constant + --> $DIR/consts.rs:3:29 + | +LL | pub fn accept(_: impl Trait) {} + | ^ + | + = note: trait bounds not allowed on associated constant + +error: aborting due to previous error +