Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20523 from ChayimFriedman2/opaque-generics
fix: Fix opaque generics
Shoyu Vanilla (Flint) 8 months ago
parent 05b7cbc · parent 03173a7 · commit db7b3b1
-rw-r--r--crates/hir-ty/src/next_solver/generics.rs68
-rw-r--r--crates/hir-ty/src/next_solver/util.rs1
-rw-r--r--crates/hir-ty/src/tests/regression.rs2
-rw-r--r--crates/hir-ty/src/tests/regression/new_solver.rs26
4 files changed, 54 insertions, 43 deletions
diff --git a/crates/hir-ty/src/next_solver/generics.rs b/crates/hir-ty/src/next_solver/generics.rs
index 48f5e73f25..a3ba8eb834 100644
--- a/crates/hir-ty/src/next_solver/generics.rs
+++ b/crates/hir-ty/src/next_solver/generics.rs
@@ -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;
@@ -24,18 +24,13 @@ 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,
@@ -43,33 +38,25 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
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) {
@@ -82,12 +69,9 @@ 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,
@@ -95,7 +79,7 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
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)])
}
}
}
diff --git a/crates/hir-ty/src/next_solver/util.rs b/crates/hir-ty/src/next_solver/util.rs
index cedc203f7f..1db02e9eb6 100644
--- a/crates/hir-ty/src/next_solver/util.rs
+++ b/crates/hir-ty/src/next_solver/util.rs
@@ -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);
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 966433369a..6a3f228621 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -1,3 +1,5 @@
+mod new_solver;
+
use expect_test::expect;
use super::{check_infer, check_no_mismatches, check_types};
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
new file mode 100644
index 0000000000..059f4ad32a
--- /dev/null
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -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 ()>
+ "#]],
+ );
+}