Skip to content

Commit

Permalink
Don't add associated type bound for non-types
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 11, 2023
1 parent b03864d commit e4cf708
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 10 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
29 changes: 19 additions & 10 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 });
}
}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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);
Expand All @@ -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(
Expand All @@ -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)
Expand All @@ -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`
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
10 changes: 10 additions & 0 deletions tests/ui/associated-type-bounds/consts.rs
Original file line number Diff line number Diff line change
@@ -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() {}
10 changes: 10 additions & 0 deletions tests/ui/associated-type-bounds/consts.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit e4cf708

Please sign in to comment.