Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/generics.rs')
-rw-r--r--crates/hir-ty/src/next_solver/generics.rs56
1 files changed, 42 insertions, 14 deletions
diff --git a/crates/hir-ty/src/next_solver/generics.rs b/crates/hir-ty/src/next_solver/generics.rs
index a798582cb9..49dbbcb06b 100644
--- a/crates/hir-ty/src/next_solver/generics.rs
+++ b/crates/hir-ty/src/next_solver/generics.rs
@@ -1,6 +1,9 @@
//! Things related to generics in the next-trait-solver.
-use hir_def::{GenericDefId, GenericParamId};
+use hir_def::{
+ GenericDefId, GenericParamId, TypeParamId,
+ hir::generics::{GenericParamDataRef, LifetimeParamData},
+};
use crate::db::HirDatabase;
@@ -10,11 +13,13 @@ use super::DbInterner;
pub(crate) fn generics(interner: DbInterner<'_>, def: SolverDefId) -> Generics<'_> {
let db = interner.db;
- let def = match (def.try_into(), def) {
- (Ok(def), _) => def,
+ let (def, consider_late_bound) = match (def.try_into(), def) {
+ (Ok(def), _) => (def, false),
(_, SolverDefId::InternedOpaqueTyId(id)) => match id.loc(db) {
- crate::ImplTraitId::ReturnTypeImplTrait(function_id, _) => function_id.into(),
- crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => type_alias_id.into(),
+ crate::ImplTraitId::ReturnTypeImplTrait(function_id, _) => (function_id.into(), true),
+ crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
+ (type_alias_id.into(), true)
+ }
},
(_, SolverDefId::BuiltinDeriveImplId(id)) => {
return crate::builtin_derive::generics_of(interner, id);
@@ -23,7 +28,7 @@ pub(crate) fn generics(interner: DbInterner<'_>, def: SolverDefId) -> Generics<'
let loc = id.loc(db);
let generic_def = loc.owner.generic_def(db);
return if loc.allow_using_generic_params {
- Generics::from_generic_def(db, generic_def)
+ Generics::from_generic_def(db, generic_def, false)
} else {
#[expect(
deprecated,
@@ -33,13 +38,14 @@ pub(crate) fn generics(interner: DbInterner<'_>, def: SolverDefId) -> Generics<'
Generics {
generics: crate::generics::Generics::empty(generic_def),
additional_param: None,
+ consider_late_bound: false,
}
};
}
_ => panic!("No generics for {def:?}"),
};
- Generics::from_generic_def(db, def)
+ Generics::from_generic_def(db, def, consider_late_bound)
}
#[derive(Debug)]
@@ -47,31 +53,53 @@ pub struct Generics<'db> {
generics: crate::generics::Generics<'db>,
/// This is used for builtin derives, specifically `CoercePointee`.
additional_param: Option<GenericParamId>,
+ consider_late_bound: bool,
}
impl<'db> Generics<'db> {
- pub(crate) fn from_generic_def(db: &'db dyn HirDatabase, def: GenericDefId) -> Generics<'db> {
- Generics { generics: crate::generics::generics(db, def), additional_param: None }
+ pub(crate) fn from_generic_def(
+ db: &'db dyn HirDatabase,
+ def: GenericDefId,
+ consider_late_bound: bool,
+ ) -> Generics<'db> {
+ Generics {
+ generics: crate::generics::generics(db, def),
+ additional_param: None,
+ consider_late_bound,
+ }
}
pub(crate) fn from_generic_def_plus_one(
db: &'db dyn HirDatabase,
def: GenericDefId,
- additional_param: GenericParamId,
+ additional_param: TypeParamId,
+ consider_late_bound: bool,
) -> Generics<'db> {
Generics {
generics: crate::generics::generics(db, def),
- additional_param: Some(additional_param),
+ additional_param: Some(additional_param.into()),
+ consider_late_bound,
}
}
- pub(super) fn iter_id(&self) -> impl Iterator<Item = GenericParamId> {
- self.generics.iter_id().chain(self.additional_param)
+ pub(super) fn iter(
+ &self,
+ ) -> impl Iterator<Item = (GenericParamId, Option<&LifetimeParamData>)> {
+ self.generics
+ .iter(self.consider_late_bound)
+ .map(|(id, data)| {
+ if let GenericParamDataRef::LifetimeParamData(lt_param) = data {
+ (id, Some(lt_param))
+ } else {
+ (id, None)
+ }
+ })
+ .chain(self.additional_param.zip(None))
}
}
impl<'db> rustc_type_ir::inherent::GenericsOf<DbInterner<'db>> for Generics<'db> {
fn count(&self) -> usize {
- self.generics.len() + usize::from(self.additional_param.is_some())
+ self.generics.len(self.consider_late_bound) + usize::from(self.additional_param.is_some())
}
}