about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-08-11 21:27:52 +0000
committerMichael Goulet <michael@errs.io>2023-08-11 21:33:08 +0000
commite4cf708d2fff1ebc8aa7a21a1be152b5247206a1 (patch)
tree28cf9b6f3ec2e4e9084389f845d164252787304d
parentb03864d546c9ded43242265abd4089e887ccc72e (diff)
downloadrust-e4cf708d2fff1ebc8aa7a21a1be152b5247206a1.tar.gz
rust-e4cf708d2fff1ebc8aa7a21a1be152b5247206a1.zip
Don't add associated type bound for non-types
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl3
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs9
-rw-r--r--tests/ui/associated-type-bounds/consts.rs10
-rw-r--r--tests/ui/associated-type-bounds/consts.stderr10
5 files changed, 51 insertions, 10 deletions
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 166760166c1..597cae6ff33 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 30145b1a185..ba152cd48de 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:
                 //
                 // `<T as Iterator>::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<Item: Debug>` to
                 //
                 // `<T as Iterator>::Item: Debug`
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 0babdf7e5b3..9471ad9ca90 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 00000000000..9b95b1b52c0
--- /dev/null
+++ b/tests/ui/associated-type-bounds/consts.rs
@@ -0,0 +1,10 @@
+#![feature(associated_type_bounds)]
+
+pub fn accept(_: impl Trait<K: Copy>) {}
+//~^ 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 00000000000..ddfb6612b08
--- /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<K: Copy>) {}
+   |                             ^
+   |
+   = note: trait bounds not allowed on associated constant
+
+error: aborting due to previous error
+