diff options
| author | Michael Goulet <michael@errs.io> | 2022-09-26 23:57:33 +0000 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2022-10-06 10:07:34 -0700 |
| commit | 328b53f5f09e571046a38e39be459a188d02631b (patch) | |
| tree | 94a89816b02e62de4c6d833566a3b3be374bd2ae | |
| parent | 99a8cc16d83c209a2886dcff049fe8382c5be0bd (diff) | |
| download | rust-328b53f5f09e571046a38e39be459a188d02631b.tar.gz rust-328b53f5f09e571046a38e39be459a188d02631b.zip | |
Support bindings with anon consts in generics
(cherry picked from commit 92561f43f185b54c81167ddc89fbe2dcd94b4efb)
| -rw-r--r-- | compiler/rustc_typeck/src/collect/type_of.rs | 47 | ||||
| -rw-r--r-- | src/test/ui/generic-associated-types/issue-102333.rs | 15 |
2 files changed, 60 insertions, 2 deletions
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 16e995b02fe..a1d1f125f78 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -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, @@ -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), .. }, diff --git a/src/test/ui/generic-associated-types/issue-102333.rs b/src/test/ui/generic-associated-types/issue-102333.rs new file mode 100644 index 00000000000..6c72563322f --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102333.rs @@ -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() {} |
