Skip to content

Commit 03173a7

Browse files
Fix opaque generics
The parent generics were incorrectly not considered for TAIT. I'm not convinced we should follow rustc here, also there are items (opaques) with more than 1 parent (opaque -> fn/type alias -> impl/trait) and I'm not sure we properly account for that in all places, but for now I left it as-is. Also fix a bug where lifetimes' indices were incorrect when there is a self param (they started from 0 instead of 1).
1 parent e6cd085 commit 03173a7

File tree

4 files changed

+54
-43
lines changed

4 files changed

+54
-43
lines changed

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

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_def::{
1212
},
1313
};
1414
use hir_expand::name::Name;
15-
use intern::Symbol;
15+
use intern::{Symbol, sym};
1616
use la_arena::Arena;
1717
use rustc_type_ir::inherent::Ty as _;
1818
use triomphe::Arc;
@@ -24,52 +24,39 @@ use super::{Const, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, Solver
2424
use super::{DbInterner, GenericArg};
2525

2626
pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
27-
let mk_lt = |(index, (_, lt)): (usize, (_, &LifetimeParamData))| {
27+
let mk_lt = |index, lt: &LifetimeParamData| {
2828
let name = lt.name.symbol().clone();
29-
let index = index as u32;
3029
let kind = GenericParamDefKind::Lifetime;
3130
GenericParamDef { name, index, kind }
3231
};
33-
let mk_ty = |len_lt, (index, p): (usize, &TypeOrConstParamData)| {
34-
let name = p
35-
.name()
36-
.map(|n| n.symbol().clone())
37-
.unwrap_or_else(|| Name::missing().symbol().clone());
38-
let index = (len_lt + index) as u32;
32+
let mk_ty = |index, p: &TypeOrConstParamData| {
33+
let name = p.name().map(|n| n.symbol().clone()).unwrap_or_else(|| sym::MISSING_NAME);
3934
let kind = match p {
4035
TypeOrConstParamData::TypeParamData(_) => GenericParamDefKind::Type,
4136
TypeOrConstParamData::ConstParamData(_) => GenericParamDefKind::Const,
4237
};
4338
GenericParamDef { name, index, kind }
4439
};
4540
let own_params_for_generic_params = |params: &GenericParams| {
46-
if params.trait_self_param().is_some() {
47-
let len_lt = params.len_lifetimes() + 1;
48-
params
49-
.iter_type_or_consts()
50-
.take(1)
51-
.enumerate()
52-
.map(|t| mk_ty(0, (t.0, t.1.1)))
53-
.chain(params.iter_lt().enumerate().map(mk_lt))
54-
.chain(
55-
params
56-
.iter_type_or_consts()
57-
.skip(1)
58-
.enumerate()
59-
.map(|t| mk_ty(len_lt, (t.0, t.1.1))),
60-
)
61-
.collect()
62-
} else {
63-
let len_lt = params.len_lifetimes();
64-
params
65-
.iter_lt()
66-
.enumerate()
67-
.map(mk_lt)
68-
.chain(
69-
params.iter_type_or_consts().enumerate().map(|t| mk_ty(len_lt, (t.0, t.1.1))),
70-
)
71-
.collect()
41+
let mut result = Vec::with_capacity(params.len());
42+
let mut type_and_consts = params.iter_type_or_consts();
43+
let mut index = 0;
44+
if let Some(self_param) = params.trait_self_param() {
45+
result.push(mk_ty(0, &params[self_param]));
46+
type_and_consts.next();
47+
index += 1;
7248
}
49+
result.extend(params.iter_lt().map(|(_, data)| {
50+
let lt = mk_lt(index, data);
51+
index += 1;
52+
lt
53+
}));
54+
result.extend(type_and_consts.map(|(_, data)| {
55+
let ty = mk_ty(index, data);
56+
index += 1;
57+
ty
58+
}));
59+
result
7360
};
7461

7562
let (parent, own_params) = match (def.try_into(), def) {
@@ -82,20 +69,17 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
8269
// The opaque type itself does not have generics - only the parent function
8370
(Some(GenericDefId::FunctionId(function_id)), vec![])
8471
}
85-
crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => (
86-
None,
87-
own_params_for_generic_params(
88-
&db.generic_params(GenericDefId::TypeAliasId(type_alias_id)),
89-
),
90-
),
72+
crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
73+
(Some(type_alias_id.into()), Vec::new())
74+
}
9175
crate::ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
9276
let param = TypeOrConstParamData::TypeParamData(TypeParamData {
9377
name: None,
9478
default: None,
9579
provenance: TypeParamProvenance::TypeParamList,
9680
});
9781
// Yes, there is a parent but we don't include it in the generics
98-
(None, vec![mk_ty(0, (0, &param))])
82+
(None, vec![mk_ty(0, &param)])
9983
}
10084
}
10185
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,6 @@ pub fn explicit_item_bounds<'db>(
685685
LifetimeElisionKind::AnonymousReportError,
686686
);
687687

688-
let trait_args = GenericArgs::identity_for_item(interner, trait_.into());
689688
let item_args = GenericArgs::identity_for_item(interner, def_id);
690689
let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args);
691690

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod new_solver;
2+
13
use expect_test::expect;
24

35
use super::{check_infer, check_no_mismatches, check_types};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use expect_test::expect;
2+
3+
use super::check_infer;
4+
5+
#[test]
6+
fn opaque_generics() {
7+
check_infer(
8+
r#"
9+
//- minicore: iterator
10+
pub struct Grid {}
11+
12+
impl<'a> IntoIterator for &'a Grid {
13+
type Item = &'a ();
14+
15+
type IntoIter = impl Iterator<Item = &'a ()>;
16+
17+
fn into_iter(self) -> Self::IntoIter {
18+
}
19+
}
20+
"#,
21+
expect![[r#"
22+
150..154 'self': &'a Grid
23+
174..181 '{ }': impl Iterator<Item = &'a ()>
24+
"#]],
25+
);
26+
}

0 commit comments

Comments
 (0)