Skip to content

Commit

Permalink
Support bindings with anon consts in generics
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Sep 27, 2022
1 parent 05267b5 commit 92561f4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
47 changes: 45 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
&& e.hir_id == hir_id =>
{
let Some(trait_def_id) = trait_ref.trait_def_id() else {
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
};
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
};
let assoc_items = tcx.associated_items(trait_def_id);
let assoc_item = assoc_items.find_by_name_and_kind(
tcx,
Expand All @@ -461,6 +461,49 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
}

Node::TypeBinding(
binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. },
) if let Node::TraitRef(trait_ref) =
tcx.hir().get(tcx.hir().get_parent_node(binding_id))
&& let Some((idx, _)) =
gen_args.args.iter().enumerate().find(|(_, arg)| {
if let GenericArg::Const(ct) = arg {
ct.value.hir_id == hir_id
} else {
false
}
}) =>
{
let Some(trait_def_id) = trait_ref.trait_def_id() else {
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
};
let assoc_items = tcx.associated_items(trait_def_id);
let assoc_item = assoc_items.find_by_name_and_kind(
tcx,
binding.ident,
match kind {
// I think `<A: T>` type bindings requires that `A` is a type
TypeBindingKind::Constraint { .. }
| TypeBindingKind::Equality { term: Term::Ty(..) } => {
ty::AssocKind::Type
}
TypeBindingKind::Equality { term: Term::Const(..) } => {
ty::AssocKind::Const
}
},
def_id.to_def_id(),
);
if let Some(assoc_item) = assoc_item {
tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id)
} else {
// FIXME(associated_const_equality): add a useful error message here.
tcx.ty_error_with_message(
DUMMY_SP,
"Could not find associated const on trait",
)
}
}

Node::GenericParam(&GenericParam {
hir_id: param_hir_id,
kind: GenericParamKind::Const { default: Some(ct), .. },
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/generic-associated-types/issue-102333.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// check-pass

trait A {
type T: B<U<1i32> = ()>;
}

trait B {
type U<const C: i32>;
}

fn f<T: A>() {
let _: <<T as A>::T as B>::U<1i32> = ();
}

fn main() {}

0 comments on commit 92561f4

Please sign in to comment.