Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 26 additions & 42 deletions crates/hir-ty/src/next_solver/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use hir_def::{
},
};
use hir_expand::name::Name;
use intern::Symbol;
use intern::{Symbol, sym};
use la_arena::Arena;
use rustc_type_ir::inherent::Ty as _;
use triomphe::Arc;
Expand All @@ -24,52 +24,39 @@ use super::{Const, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, Solver
use super::{DbInterner, GenericArg};

pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
let mk_lt = |(index, (_, lt)): (usize, (_, &LifetimeParamData))| {
let mk_lt = |index, lt: &LifetimeParamData| {
let name = lt.name.symbol().clone();
let index = index as u32;
let kind = GenericParamDefKind::Lifetime;
GenericParamDef { name, index, kind }
};
let mk_ty = |len_lt, (index, p): (usize, &TypeOrConstParamData)| {
let name = p
.name()
.map(|n| n.symbol().clone())
.unwrap_or_else(|| Name::missing().symbol().clone());
let index = (len_lt + index) as u32;
let mk_ty = |index, p: &TypeOrConstParamData| {
let name = p.name().map(|n| n.symbol().clone()).unwrap_or_else(|| sym::MISSING_NAME);
let kind = match p {
TypeOrConstParamData::TypeParamData(_) => GenericParamDefKind::Type,
TypeOrConstParamData::ConstParamData(_) => GenericParamDefKind::Const,
};
GenericParamDef { name, index, kind }
};
let own_params_for_generic_params = |params: &GenericParams| {
if params.trait_self_param().is_some() {
let len_lt = params.len_lifetimes() + 1;
params
.iter_type_or_consts()
.take(1)
.enumerate()
.map(|t| mk_ty(0, (t.0, t.1.1)))
.chain(params.iter_lt().enumerate().map(mk_lt))
.chain(
params
.iter_type_or_consts()
.skip(1)
.enumerate()
.map(|t| mk_ty(len_lt, (t.0, t.1.1))),
)
.collect()
} else {
let len_lt = params.len_lifetimes();
params
.iter_lt()
.enumerate()
.map(mk_lt)
.chain(
params.iter_type_or_consts().enumerate().map(|t| mk_ty(len_lt, (t.0, t.1.1))),
)
.collect()
let mut result = Vec::with_capacity(params.len());
let mut type_and_consts = params.iter_type_or_consts();
let mut index = 0;
if let Some(self_param) = params.trait_self_param() {
result.push(mk_ty(0, &params[self_param]));
type_and_consts.next();
index += 1;
}
result.extend(params.iter_lt().map(|(_, data)| {
let lt = mk_lt(index, data);
index += 1;
lt
}));
result.extend(type_and_consts.map(|(_, data)| {
let ty = mk_ty(index, data);
index += 1;
ty
}));
result
};

let (parent, own_params) = match (def.try_into(), def) {
Expand All @@ -82,20 +69,17 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
// The opaque type itself does not have generics - only the parent function
(Some(GenericDefId::FunctionId(function_id)), vec![])
}
crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => (
None,
own_params_for_generic_params(
&db.generic_params(GenericDefId::TypeAliasId(type_alias_id)),
),
),
crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
(Some(type_alias_id.into()), Vec::new())
}
crate::ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
let param = TypeOrConstParamData::TypeParamData(TypeParamData {
name: None,
default: None,
provenance: TypeParamProvenance::TypeParamList,
});
// Yes, there is a parent but we don't include it in the generics
(None, vec![mk_ty(0, (0, &param))])
(None, vec![mk_ty(0, &param)])
}
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/hir-ty/src/next_solver/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ pub fn explicit_item_bounds<'db>(
LifetimeElisionKind::AnonymousReportError,
);

let trait_args = GenericArgs::identity_for_item(interner, trait_.into());
let item_args = GenericArgs::identity_for_item(interner, def_id);
let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args);

Expand Down
2 changes: 2 additions & 0 deletions crates/hir-ty/src/tests/regression.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod new_solver;

use expect_test::expect;

use super::{check_infer, check_no_mismatches, check_types};
Expand Down
26 changes: 26 additions & 0 deletions crates/hir-ty/src/tests/regression/new_solver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use expect_test::expect;

use super::check_infer;

#[test]
fn opaque_generics() {
check_infer(
r#"
//- minicore: iterator
pub struct Grid {}

impl<'a> IntoIterator for &'a Grid {
type Item = &'a ();

type IntoIter = impl Iterator<Item = &'a ()>;

fn into_iter(self) -> Self::IntoIter {
}
}
"#,
expect![[r#"
150..154 'self': &'a Grid
174..181 '{ }': impl Iterator<Item = &'a ()>
"#]],
);
}
Loading