partial spec is an enum
This commit is contained in:
@@ -568,7 +568,7 @@ impl<'db> GenericContext<'db> {
|
||||
loop {
|
||||
let mut any_changed = false;
|
||||
for i in 0..len {
|
||||
let partial = PartialSpecialization {
|
||||
let partial = PartialSpecialization::FromGenericContext {
|
||||
generic_context: self,
|
||||
types: &types,
|
||||
// Don't recursively substitute type[i] in itself. Ideally, we could instead
|
||||
@@ -646,7 +646,7 @@ impl<'db> GenericContext<'db> {
|
||||
// Typevars are only allowed to refer to _earlier_ typevars in their defaults. (This is
|
||||
// statically enforced for PEP-695 contexts, and is explicitly called out as a
|
||||
// requirement for legacy contexts.)
|
||||
let partial = PartialSpecialization {
|
||||
let partial = PartialSpecialization::FromGenericContext {
|
||||
generic_context: self,
|
||||
types: &expanded[0..idx],
|
||||
skip: None,
|
||||
@@ -1452,12 +1452,14 @@ impl<'db> Specialization<'db> {
|
||||
/// You will usually use [`Specialization`] instead of this type. This type is used when we need to
|
||||
/// substitute types for type variables before we have fully constructed a [`Specialization`].
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub struct PartialSpecialization<'a, 'db> {
|
||||
generic_context: GenericContext<'db>,
|
||||
types: &'a [Type<'db>],
|
||||
/// An optional typevar to _not_ substitute when applying the specialization. We use this to
|
||||
/// avoid recursively substituting a type inside of itself.
|
||||
skip: Option<usize>,
|
||||
pub enum PartialSpecialization<'a, 'db> {
|
||||
FromGenericContext {
|
||||
generic_context: GenericContext<'db>,
|
||||
types: &'a [Type<'db>],
|
||||
/// An optional typevar to _not_ substitute when applying the specialization. We use this to
|
||||
/// avoid recursively substituting a type inside of itself.
|
||||
skip: Option<usize>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'db> PartialSpecialization<'_, 'db> {
|
||||
@@ -1468,14 +1470,21 @@ impl<'db> PartialSpecialization<'_, 'db> {
|
||||
db: &'db dyn Db,
|
||||
bound_typevar: BoundTypeVarInstance<'db>,
|
||||
) -> Option<Type<'db>> {
|
||||
let index = self
|
||||
.generic_context
|
||||
.variables_inner(db)
|
||||
.get_index_of(&bound_typevar.identity(db))?;
|
||||
if self.skip.is_some_and(|skip| skip == index) {
|
||||
return Some(Type::Never);
|
||||
match self {
|
||||
PartialSpecialization::FromGenericContext {
|
||||
generic_context,
|
||||
types,
|
||||
skip,
|
||||
} => {
|
||||
let index = generic_context
|
||||
.variables_inner(db)
|
||||
.get_index_of(&bound_typevar.identity(db))?;
|
||||
if skip.is_some_and(|skip| skip == index) {
|
||||
return Some(Type::Never);
|
||||
}
|
||||
types.get(index).copied()
|
||||
}
|
||||
}
|
||||
self.types.get(index).copied()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user