Skip to content

Commit 328b53f

Browse files
compiler-errorscuviper
authored andcommitted
Support bindings with anon consts in generics
(cherry picked from commit 92561f4)
1 parent 99a8cc1 commit 328b53f

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

Diff for: compiler/rustc_typeck/src/collect/type_of.rs

+45-2
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
441441
&& e.hir_id == hir_id =>
442442
{
443443
let Some(trait_def_id) = trait_ref.trait_def_id() else {
444-
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
445-
};
444+
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
445+
};
446446
let assoc_items = tcx.associated_items(trait_def_id);
447447
let assoc_item = assoc_items.find_by_name_and_kind(
448448
tcx,
@@ -461,6 +461,49 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
461461
}
462462
}
463463

464+
Node::TypeBinding(
465+
binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. },
466+
) if let Node::TraitRef(trait_ref) =
467+
tcx.hir().get(tcx.hir().get_parent_node(binding_id))
468+
&& let Some((idx, _)) =
469+
gen_args.args.iter().enumerate().find(|(_, arg)| {
470+
if let GenericArg::Const(ct) = arg {
471+
ct.value.hir_id == hir_id
472+
} else {
473+
false
474+
}
475+
}) =>
476+
{
477+
let Some(trait_def_id) = trait_ref.trait_def_id() else {
478+
return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
479+
};
480+
let assoc_items = tcx.associated_items(trait_def_id);
481+
let assoc_item = assoc_items.find_by_name_and_kind(
482+
tcx,
483+
binding.ident,
484+
match kind {
485+
// I think `<A: T>` type bindings requires that `A` is a type
486+
TypeBindingKind::Constraint { .. }
487+
| TypeBindingKind::Equality { term: Term::Ty(..) } => {
488+
ty::AssocKind::Type
489+
}
490+
TypeBindingKind::Equality { term: Term::Const(..) } => {
491+
ty::AssocKind::Const
492+
}
493+
},
494+
def_id.to_def_id(),
495+
);
496+
if let Some(assoc_item) = assoc_item {
497+
tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id)
498+
} else {
499+
// FIXME(associated_const_equality): add a useful error message here.
500+
tcx.ty_error_with_message(
501+
DUMMY_SP,
502+
"Could not find associated const on trait",
503+
)
504+
}
505+
}
506+
464507
Node::GenericParam(&GenericParam {
465508
hir_id: param_hir_id,
466509
kind: GenericParamKind::Const { default: Some(ct), .. },

Diff for: src/test/ui/generic-associated-types/issue-102333.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// check-pass
2+
3+
trait A {
4+
type T: B<U<1i32> = ()>;
5+
}
6+
7+
trait B {
8+
type U<const C: i32>;
9+
}
10+
11+
fn f<T: A>() {
12+
let _: <<T as A>::T as B>::U<1i32> = ();
13+
}
14+
15+
fn main() {}

0 commit comments

Comments
 (0)