Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21243 from ChayimFriedman2/assoc-defaults
feat: Support `#[feature(associated_type_defaults)]`
Shoyu Vanilla (Flint) 4 months ago
parent 4c2aa73 · parent 425f385 · commit 3e3f994
-rw-r--r--crates/hir-ty/src/next_solver/interner.rs9
-rw-r--r--crates/hir-ty/src/next_solver/solver.rs85
-rw-r--r--crates/hir-ty/src/tests/traits.rs20
3 files changed, 67 insertions, 47 deletions
diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs
index 2edf442a8c..8b24a20a5b 100644
--- a/crates/hir-ty/src/next_solver/interner.rs
+++ b/crates/hir-ty/src/next_solver/interner.rs
@@ -1104,14 +1104,7 @@ impl<'db> Interner for DbInterner<'db> {
fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
match def_id {
- SolverDefId::TypeAliasId(id) => {
- use hir_def::Lookup;
- match id.lookup(self.db()).container {
- ItemContainerId::ImplId(it) => it,
- _ => panic!("assoc ty value should be in impl"),
- };
- self.db().ty(id.into())
- }
+ SolverDefId::TypeAliasId(id) => self.db().ty(id.into()),
SolverDefId::AdtId(id) => self.db().ty(id.into()),
// FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
//
diff --git a/crates/hir-ty/src/next_solver/solver.rs b/crates/hir-ty/src/next_solver/solver.rs
index 859e26e376..40a3f17cf1 100644
--- a/crates/hir-ty/src/next_solver/solver.rs
+++ b/crates/hir-ty/src/next_solver/solver.rs
@@ -177,45 +177,52 @@ impl<'db> SolverDelegate for SolverContext<'db> {
impl_id: ImplIdWrapper,
) -> Result<Option<SolverDefId>, ErrorGuaranteed> {
let impl_items = impl_id.0.impl_items(self.0.interner.db());
- let id = match trait_assoc_def_id {
- SolverDefId::TypeAliasId(trait_assoc_id) => {
- let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id);
- impl_items
- .items
- .iter()
- .find_map(|(impl_assoc_name, impl_assoc_id)| {
- if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
- && *impl_assoc_name == trait_assoc_data.name
- {
- Some(impl_assoc_id)
- } else {
- None
- }
- })
- .map(SolverDefId::TypeAliasId)
- }
- SolverDefId::ConstId(trait_assoc_id) => {
- let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id);
- let trait_assoc_name = trait_assoc_data
- .name
- .as_ref()
- .expect("unnamed consts should not get passed to the solver");
- impl_items
- .items
- .iter()
- .find_map(|(impl_assoc_name, impl_assoc_id)| {
- if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
- && impl_assoc_name == trait_assoc_name
- {
- Some(impl_assoc_id)
- } else {
- None
- }
- })
- .map(SolverDefId::ConstId)
- }
- _ => panic!("Unexpected SolverDefId"),
- };
+ let id =
+ match trait_assoc_def_id {
+ SolverDefId::TypeAliasId(trait_assoc_id) => {
+ let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id);
+ impl_items
+ .items
+ .iter()
+ .find_map(|(impl_assoc_name, impl_assoc_id)| {
+ if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
+ && *impl_assoc_name == trait_assoc_data.name
+ {
+ Some(impl_assoc_id)
+ } else {
+ None
+ }
+ })
+ .or_else(|| {
+ if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None }
+ })
+ .map(SolverDefId::TypeAliasId)
+ }
+ SolverDefId::ConstId(trait_assoc_id) => {
+ let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id);
+ let trait_assoc_name = trait_assoc_data
+ .name
+ .as_ref()
+ .expect("unnamed consts should not get passed to the solver");
+ impl_items
+ .items
+ .iter()
+ .find_map(|(impl_assoc_name, impl_assoc_id)| {
+ if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
+ && impl_assoc_name == trait_assoc_name
+ {
+ Some(impl_assoc_id)
+ } else {
+ None
+ }
+ })
+ .or_else(|| {
+ if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None }
+ })
+ .map(SolverDefId::ConstId)
+ }
+ _ => panic!("Unexpected SolverDefId"),
+ };
Ok(id)
}
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 677e35775d..a54c0a799d 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -5079,3 +5079,23 @@ fn foo(base_layer_two: &dyn BaseLayerOne) {
"#,
);
}
+
+#[test]
+fn default_assoc_types() {
+ check_types(
+ r#"
+trait Trait<T> {
+ type Assoc<U> = (T, U);
+ fn method(self) -> Self::Assoc<i32> { loop {} }
+}
+
+struct Struct<T>(T);
+impl<T> Trait<((), T)> for Struct<T> {}
+
+fn foo(v: Struct<f32>) {
+ v.method();
+ // ^^^^^^^^^^ (((), f32), i32)
+}
+ "#,
+ );
+}