Skip to content

Commit 3e3f994

Browse files
authored
Merge pull request #21243 from ChayimFriedman2/assoc-defaults
feat: Support `#[feature(associated_type_defaults)]`
2 parents 4c2aa73 + 425f385 commit 3e3f994

File tree

3 files changed

+67
-47
lines changed

3 files changed

+67
-47
lines changed

crates/hir-ty/src/next_solver/interner.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,14 +1104,7 @@ impl<'db> Interner for DbInterner<'db> {
11041104

11051105
fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
11061106
match def_id {
1107-
SolverDefId::TypeAliasId(id) => {
1108-
use hir_def::Lookup;
1109-
match id.lookup(self.db()).container {
1110-
ItemContainerId::ImplId(it) => it,
1111-
_ => panic!("assoc ty value should be in impl"),
1112-
};
1113-
self.db().ty(id.into())
1114-
}
1107+
SolverDefId::TypeAliasId(id) => self.db().ty(id.into()),
11151108
SolverDefId::AdtId(id) => self.db().ty(id.into()),
11161109
// FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
11171110
//

crates/hir-ty/src/next_solver/solver.rs

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -177,45 +177,52 @@ impl<'db> SolverDelegate for SolverContext<'db> {
177177
impl_id: ImplIdWrapper,
178178
) -> Result<Option<SolverDefId>, ErrorGuaranteed> {
179179
let impl_items = impl_id.0.impl_items(self.0.interner.db());
180-
let id = match trait_assoc_def_id {
181-
SolverDefId::TypeAliasId(trait_assoc_id) => {
182-
let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id);
183-
impl_items
184-
.items
185-
.iter()
186-
.find_map(|(impl_assoc_name, impl_assoc_id)| {
187-
if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
188-
&& *impl_assoc_name == trait_assoc_data.name
189-
{
190-
Some(impl_assoc_id)
191-
} else {
192-
None
193-
}
194-
})
195-
.map(SolverDefId::TypeAliasId)
196-
}
197-
SolverDefId::ConstId(trait_assoc_id) => {
198-
let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id);
199-
let trait_assoc_name = trait_assoc_data
200-
.name
201-
.as_ref()
202-
.expect("unnamed consts should not get passed to the solver");
203-
impl_items
204-
.items
205-
.iter()
206-
.find_map(|(impl_assoc_name, impl_assoc_id)| {
207-
if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
208-
&& impl_assoc_name == trait_assoc_name
209-
{
210-
Some(impl_assoc_id)
211-
} else {
212-
None
213-
}
214-
})
215-
.map(SolverDefId::ConstId)
216-
}
217-
_ => panic!("Unexpected SolverDefId"),
218-
};
180+
let id =
181+
match trait_assoc_def_id {
182+
SolverDefId::TypeAliasId(trait_assoc_id) => {
183+
let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id);
184+
impl_items
185+
.items
186+
.iter()
187+
.find_map(|(impl_assoc_name, impl_assoc_id)| {
188+
if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
189+
&& *impl_assoc_name == trait_assoc_data.name
190+
{
191+
Some(impl_assoc_id)
192+
} else {
193+
None
194+
}
195+
})
196+
.or_else(|| {
197+
if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None }
198+
})
199+
.map(SolverDefId::TypeAliasId)
200+
}
201+
SolverDefId::ConstId(trait_assoc_id) => {
202+
let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id);
203+
let trait_assoc_name = trait_assoc_data
204+
.name
205+
.as_ref()
206+
.expect("unnamed consts should not get passed to the solver");
207+
impl_items
208+
.items
209+
.iter()
210+
.find_map(|(impl_assoc_name, impl_assoc_id)| {
211+
if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
212+
&& impl_assoc_name == trait_assoc_name
213+
{
214+
Some(impl_assoc_id)
215+
} else {
216+
None
217+
}
218+
})
219+
.or_else(|| {
220+
if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None }
221+
})
222+
.map(SolverDefId::ConstId)
223+
}
224+
_ => panic!("Unexpected SolverDefId"),
225+
};
219226
Ok(id)
220227
}
221228

crates/hir-ty/src/tests/traits.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5079,3 +5079,23 @@ fn foo(base_layer_two: &dyn BaseLayerOne) {
50795079
"#,
50805080
);
50815081
}
5082+
5083+
#[test]
5084+
fn default_assoc_types() {
5085+
check_types(
5086+
r#"
5087+
trait Trait<T> {
5088+
type Assoc<U> = (T, U);
5089+
fn method(self) -> Self::Assoc<i32> { loop {} }
5090+
}
5091+
5092+
struct Struct<T>(T);
5093+
impl<T> Trait<((), T)> for Struct<T> {}
5094+
5095+
fn foo(v: Struct<f32>) {
5096+
v.method();
5097+
// ^^^^^^^^^^ (((), f32), i32)
5098+
}
5099+
"#,
5100+
);
5101+
}

0 commit comments

Comments
 (0)