mirror of
https://github.com/astral-sh/ruff
synced 2026-01-20 21:10:48 -05:00
[ty] Pass slice to specialize (#22421)
This commit is contained in:
@@ -1671,7 +1671,7 @@ mod implicit_globals {
|
||||
Place::Defined(
|
||||
DefinedPlace::new(KnownClass::Dict.to_specialized_instance(
|
||||
db,
|
||||
[Type::any(), KnownClass::Int.to_instance(db)],
|
||||
&[Type::any(), KnownClass::Int.to_instance(db)],
|
||||
))
|
||||
.with_definedness(Definedness::PossiblyUndefined),
|
||||
)
|
||||
@@ -1689,7 +1689,7 @@ mod implicit_globals {
|
||||
),
|
||||
KnownClass::Dict.to_specialized_instance(
|
||||
db,
|
||||
[KnownClass::Str.to_instance(db), Type::any()],
|
||||
&[KnownClass::Str.to_instance(db), Type::any()],
|
||||
),
|
||||
);
|
||||
Place::Defined(
|
||||
|
||||
@@ -4127,7 +4127,7 @@ impl<'db> Type<'db> {
|
||||
.with_annotated_type(
|
||||
KnownClass::Dict.to_specialized_instance(
|
||||
db,
|
||||
[str_instance, Type::any()],
|
||||
&[str_instance, Type::any()],
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -4377,7 +4377,7 @@ impl<'db> Type<'db> {
|
||||
.with_annotated_type(
|
||||
KnownClass::Iterable.to_specialized_instance(
|
||||
db,
|
||||
[Type::TypeVar(element_ty)],
|
||||
&[Type::TypeVar(element_ty)],
|
||||
),
|
||||
)],
|
||||
),
|
||||
@@ -5840,7 +5840,7 @@ impl<'db> Type<'db> {
|
||||
pub(crate) fn dunder_class(self, db: &'db dyn Db) -> Type<'db> {
|
||||
if self.is_typed_dict() {
|
||||
return KnownClass::Dict
|
||||
.to_specialized_class_type(db, [KnownClass::Str.to_instance(db), Type::object()])
|
||||
.to_specialized_class_type(db, &[KnownClass::Str.to_instance(db), Type::object()])
|
||||
.map(Type::from)
|
||||
// Guard against user-customized typesheds with a broken `dict` class
|
||||
.unwrap_or_else(Type::unknown);
|
||||
@@ -8370,7 +8370,7 @@ impl<'db> BoundTypeVarInstance<'db> {
|
||||
let upper_bound = TypeVarBoundOrConstraints::UpperBound(match kind {
|
||||
ParamSpecAttrKind::Args => Type::homogeneous_tuple(db, Type::object()),
|
||||
ParamSpecAttrKind::Kwargs => KnownClass::Dict
|
||||
.to_specialized_instance(db, [KnownClass::Str.to_instance(db), Type::any()])
|
||||
.to_specialized_instance(db, &[KnownClass::Str.to_instance(db), Type::any()])
|
||||
.top_materialization(db),
|
||||
});
|
||||
|
||||
@@ -13079,11 +13079,11 @@ pub(crate) mod tests {
|
||||
let recursive = UnionType::from_elements(
|
||||
&db,
|
||||
[
|
||||
KnownClass::List.to_specialized_instance(&db, [div]),
|
||||
KnownClass::List.to_specialized_instance(&db, &[div]),
|
||||
Type::none(&db),
|
||||
],
|
||||
);
|
||||
let nested_rec = KnownClass::List.to_specialized_instance(&db, [recursive]);
|
||||
let nested_rec = KnownClass::List.to_specialized_instance(&db, &[recursive]);
|
||||
assert_eq!(
|
||||
nested_rec.display(&db).to_string(),
|
||||
"list[list[Divergent] | None]"
|
||||
|
||||
@@ -603,7 +603,7 @@ impl<'db> BoundSuperType<'db> {
|
||||
}
|
||||
return delegate_to(
|
||||
KnownClass::Dict
|
||||
.to_specialized_instance(db, [key_builder.build(), value_builder.build()]),
|
||||
.to_specialized_instance(db, &[key_builder.build(), value_builder.build()]),
|
||||
);
|
||||
}
|
||||
Type::NewTypeInstance(newtype) => {
|
||||
|
||||
@@ -662,7 +662,7 @@ impl<'db> Bindings<'db> {
|
||||
if let Some(enum_instance) = bound_method.self_instance(db).to_instance(db)
|
||||
{
|
||||
overload.set_return_type(
|
||||
KnownClass::Iterator.to_specialized_instance(db, [enum_instance]),
|
||||
KnownClass::Iterator.to_specialized_instance(db, &[enum_instance]),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -993,7 +993,7 @@ impl<'db> Bindings<'db> {
|
||||
let specialization = UnionType::from_elements(db, member_names);
|
||||
overload.set_return_type(
|
||||
KnownClass::FrozenSet
|
||||
.to_specialized_instance(db, [specialization]),
|
||||
.to_specialized_instance(db, &[specialization]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Write;
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
@@ -1091,7 +1092,7 @@ impl<'db> ClassType<'db> {
|
||||
let mut tuple_elements = tuple.iter_all_elements();
|
||||
iterable_parameter = iterable_parameter.with_annotated_type(
|
||||
KnownClass::Iterable
|
||||
.to_specialized_instance(db, [tuple_elements.next().unwrap()]),
|
||||
.to_specialized_instance(db, &[tuple_elements.next().unwrap()]),
|
||||
);
|
||||
assert_eq!(
|
||||
tuple_elements.next(),
|
||||
@@ -2061,7 +2062,7 @@ impl<'db> ClassLiteral<'db> {
|
||||
let name = Type::string_literal(db, self.name(db));
|
||||
let bases = Type::heterogeneous_tuple(db, self.explicit_bases(db));
|
||||
let namespace = KnownClass::Dict
|
||||
.to_specialized_instance(db, [KnownClass::Str.to_instance(db), Type::any()]);
|
||||
.to_specialized_instance(db, &[KnownClass::Str.to_instance(db), Type::any()]);
|
||||
|
||||
// TODO: Other keyword arguments?
|
||||
let arguments = CallArguments::positional([name, bases, namespace]);
|
||||
@@ -2308,9 +2309,9 @@ impl<'db> ClassLiteral<'db> {
|
||||
return Member {
|
||||
inner: Place::declared(KnownClass::Dict.to_specialized_instance(
|
||||
db,
|
||||
[
|
||||
&[
|
||||
KnownClass::Str.to_instance(db),
|
||||
KnownClass::Field.to_specialized_instance(db, [Type::any()]),
|
||||
KnownClass::Field.to_specialized_instance(db, &[Type::any()]),
|
||||
],
|
||||
))
|
||||
.with_qualifiers(TypeQualifiers::CLASS_VAR),
|
||||
@@ -5197,18 +5198,26 @@ impl KnownClass {
|
||||
///
|
||||
/// If the class cannot be found in typeshed, or if you provide a specialization with the wrong
|
||||
/// number of types, a debug-level log message will be emitted stating this.
|
||||
pub(crate) fn to_specialized_class_type<'db>(
|
||||
pub(crate) fn to_specialized_class_type<'t, 'db, T>(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
specialization: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Option<ClassType<'db>> {
|
||||
fn to_specialized_class_type_impl<'db>(
|
||||
specialization: T,
|
||||
) -> Option<ClassType<'db>>
|
||||
where
|
||||
T: Into<Cow<'t, [Type<'db>]>>,
|
||||
'db: 't,
|
||||
{
|
||||
fn inner<'db>(
|
||||
db: &'db dyn Db,
|
||||
class: KnownClass,
|
||||
class_literal: ClassLiteral<'db>,
|
||||
specialization: Box<[Type<'db>]>,
|
||||
generic_context: GenericContext<'db>,
|
||||
) -> ClassType<'db> {
|
||||
specialization: Cow<[Type<'db>]>,
|
||||
) -> Option<ClassType<'db>> {
|
||||
let Type::ClassLiteral(class_literal) = class.to_class_literal(db) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let generic_context = class_literal.generic_context(db)?;
|
||||
|
||||
if specialization.len() != generic_context.len(db) {
|
||||
// a cache of the `KnownClass`es that we have already seen mismatched-arity
|
||||
// specializations for (and therefore that we've already logged a warning for)
|
||||
@@ -5217,31 +5226,21 @@ impl KnownClass {
|
||||
if MESSAGES.lock().unwrap().insert(class) {
|
||||
tracing::info!(
|
||||
"Wrong number of types when specializing {}. \
|
||||
Falling back to default specialization for the symbol instead.",
|
||||
Falling back to default specialization for the symbol instead.",
|
||||
class.display(db)
|
||||
);
|
||||
}
|
||||
return class_literal.default_specialization(db);
|
||||
return Some(class_literal.default_specialization(db));
|
||||
}
|
||||
|
||||
class_literal
|
||||
.apply_specialization(db, |_| generic_context.specialize(db, specialization))
|
||||
Some(
|
||||
class_literal
|
||||
.apply_specialization(db, |_| generic_context.specialize(db, specialization)),
|
||||
)
|
||||
}
|
||||
|
||||
let Type::ClassLiteral(class_literal) = self.to_class_literal(db) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let generic_context = class_literal.generic_context(db)?;
|
||||
let types = specialization.into_iter().collect::<Box<[_]>>();
|
||||
|
||||
Some(to_specialized_class_type_impl(
|
||||
db,
|
||||
self,
|
||||
class_literal,
|
||||
types,
|
||||
generic_context,
|
||||
))
|
||||
let specialization = specialization.into();
|
||||
inner(db, self, specialization)
|
||||
}
|
||||
|
||||
/// Lookup a [`KnownClass`] in typeshed and return a [`Type`]
|
||||
@@ -5250,11 +5249,15 @@ impl KnownClass {
|
||||
/// If the class cannot be found in typeshed, or if you provide a specialization with the wrong
|
||||
/// number of types, a debug-level log message will be emitted stating this.
|
||||
#[track_caller]
|
||||
pub(crate) fn to_specialized_instance<'db>(
|
||||
pub(crate) fn to_specialized_instance<'t, 'db, T>(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
specialization: impl IntoIterator<Item = Type<'db>>,
|
||||
) -> Type<'db> {
|
||||
specialization: T,
|
||||
) -> Type<'db>
|
||||
where
|
||||
T: Into<Cow<'t, [Type<'db>]>>,
|
||||
'db: 't,
|
||||
{
|
||||
debug_assert_ne!(
|
||||
self,
|
||||
KnownClass::Tuple,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt::Display;
|
||||
@@ -500,13 +501,17 @@ impl<'db> GenericContext<'db> {
|
||||
|
||||
/// Returns a specialization of this generic context where each typevar is mapped to itself.
|
||||
pub(crate) fn identity_specialization(self, db: &'db dyn Db) -> Specialization<'db> {
|
||||
let types = self.variables(db).map(Type::TypeVar).collect();
|
||||
let types: Vec<Type> = self.variables(db).map(Type::TypeVar).collect();
|
||||
self.specialize(db, types)
|
||||
}
|
||||
|
||||
pub(crate) fn unknown_specialization(self, db: &'db dyn Db) -> Specialization<'db> {
|
||||
let types = vec![Type::unknown(); self.len(db)];
|
||||
self.specialize(db, types.into())
|
||||
match self.len(db) {
|
||||
0 => self.specialize(db, &[]),
|
||||
1 => self.specialize(db, &[Type::unknown(); 1]),
|
||||
2 => self.specialize(db, &[Type::unknown(); 2]),
|
||||
len => self.specialize(db, vec![Type::unknown(); len]),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_subset_of(self, db: &'db dyn Db, other: GenericContext<'db>) -> bool {
|
||||
@@ -545,11 +550,13 @@ impl<'db> GenericContext<'db> {
|
||||
/// otherwise, you will be left with a partial specialization. (Use
|
||||
/// [`specialize_recursive`](Self::specialize_recursive) if your types might mention typevars
|
||||
/// in this generic context.)
|
||||
pub(crate) fn specialize(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
types: Box<[Type<'db>]>,
|
||||
) -> Specialization<'db> {
|
||||
pub(crate) fn specialize<'t, T>(self, db: &'db dyn Db, types: T) -> Specialization<'db>
|
||||
where
|
||||
T: Into<Cow<'t, [Type<'db>]>>,
|
||||
'db: 't,
|
||||
{
|
||||
let types = types.into();
|
||||
|
||||
assert_eq!(self.len(db), types.len());
|
||||
Specialization::new(db, self, types, None, None)
|
||||
}
|
||||
|
||||
@@ -2836,7 +2836,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
}
|
||||
KnownClass::Dict.to_specialized_instance(
|
||||
self.db(),
|
||||
[KnownClass::Str.to_instance(self.db()), Type::unknown()],
|
||||
&[KnownClass::Str.to_instance(self.db()), Type::unknown()],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2848,14 +2848,14 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
// The diagnostic for this case is handled in `in_type_expression`.
|
||||
KnownClass::Dict.to_specialized_instance(
|
||||
self.db(),
|
||||
[KnownClass::Str.to_instance(self.db()), Type::unknown()],
|
||||
&[KnownClass::Str.to_instance(self.db()), Type::unknown()],
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
KnownClass::Dict.to_specialized_instance(
|
||||
self.db(),
|
||||
[KnownClass::Str.to_instance(self.db()), annotated_type],
|
||||
&[KnownClass::Str.to_instance(self.db()), annotated_type],
|
||||
)
|
||||
};
|
||||
self.add_declaration_with_binding(
|
||||
@@ -2866,7 +2866,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
} else {
|
||||
let inferred_ty = KnownClass::Dict.to_specialized_instance(
|
||||
self.db(),
|
||||
[KnownClass::Str.to_instance(self.db()), Type::unknown()],
|
||||
&[KnownClass::Str.to_instance(self.db()), Type::unknown()],
|
||||
);
|
||||
|
||||
self.add_binding(parameter.into(), definition)
|
||||
@@ -3392,7 +3392,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
} else {
|
||||
KnownClass::BaseExceptionGroup
|
||||
};
|
||||
class.to_specialized_instance(self.db(), [symbol_ty])
|
||||
class.to_specialized_instance(self.db(), &[symbol_ty])
|
||||
} else {
|
||||
symbol_ty
|
||||
}
|
||||
@@ -8007,7 +8007,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
let infer_elt_ty = |builder: &mut Self, elt, tcx| builder.infer_expression(elt, tcx);
|
||||
self.infer_collection_literal(elts, tcx, infer_elt_ty, KnownClass::List)
|
||||
.unwrap_or_else(|| {
|
||||
KnownClass::List.to_specialized_instance(self.db(), [Type::unknown()])
|
||||
KnownClass::List.to_specialized_instance(self.db(), &[Type::unknown()])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8022,7 +8022,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
let infer_elt_ty = |builder: &mut Self, elt, tcx| builder.infer_expression(elt, tcx);
|
||||
self.infer_collection_literal(elts, tcx, infer_elt_ty, KnownClass::Set)
|
||||
.unwrap_or_else(|| {
|
||||
KnownClass::Set.to_specialized_instance(self.db(), [Type::unknown()])
|
||||
KnownClass::Set.to_specialized_instance(self.db(), &[Type::unknown()])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8049,7 +8049,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
// unsupported.
|
||||
if let Some(Type::Dynamic(DynamicType::Todo(_))) = tcx.annotation {
|
||||
return KnownClass::Dict
|
||||
.to_specialized_instance(self.db(), [Type::unknown(), Type::unknown()]);
|
||||
.to_specialized_instance(self.db(), &[Type::unknown(), Type::unknown()]);
|
||||
}
|
||||
|
||||
let items = items
|
||||
@@ -8069,7 +8069,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
self.infer_collection_literal(items, tcx, infer_elt_ty, KnownClass::Dict)
|
||||
.unwrap_or_else(|| {
|
||||
KnownClass::Dict
|
||||
.to_specialized_instance(self.db(), [Type::unknown(), Type::unknown()])
|
||||
.to_specialized_instance(self.db(), &[Type::unknown(), Type::unknown()])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8339,11 +8339,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
|
||||
if evaluation_mode.is_async() {
|
||||
KnownClass::AsyncGeneratorType
|
||||
.to_specialized_instance(self.db(), [yield_type, Type::none(self.db())])
|
||||
.to_specialized_instance(self.db(), &[yield_type, Type::none(self.db())])
|
||||
} else {
|
||||
KnownClass::GeneratorType.to_specialized_instance(
|
||||
self.db(),
|
||||
[yield_type, Type::none(self.db()), Type::none(self.db())],
|
||||
&[yield_type, Type::none(self.db()), Type::none(self.db())],
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -8373,20 +8373,22 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
.zip(inferred_element_types.iter())
|
||||
.all(|(annotated, inferred)| inferred.is_assignable_to(self.db(), *annotated))
|
||||
{
|
||||
collection_class
|
||||
.to_specialized_instance(self.db(), annotated_element_types.iter().copied())
|
||||
collection_class.to_specialized_instance(self.db(), annotated_element_types)
|
||||
} else {
|
||||
collection_class.to_specialized_instance(
|
||||
self.db(),
|
||||
inferred_element_types.iter().map(|ty| {
|
||||
UnionType::from_elements(
|
||||
self.db(),
|
||||
[
|
||||
ty.promote_literals(self.db(), TypeContext::default()),
|
||||
Type::unknown(),
|
||||
],
|
||||
)
|
||||
}),
|
||||
inferred_element_types
|
||||
.iter()
|
||||
.map(|ty| {
|
||||
UnionType::from_elements(
|
||||
self.db(),
|
||||
[
|
||||
ty.promote_literals(self.db(), TypeContext::default()),
|
||||
Type::unknown(),
|
||||
],
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -12195,7 +12197,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
.expect("A known stdlib class is available");
|
||||
|
||||
return class
|
||||
.to_specialized_class_type(self.db(), [element_ty])
|
||||
.to_specialized_class_type(self.db(), &[element_ty])
|
||||
.map(Type::from)
|
||||
.unwrap_or_else(Type::unknown);
|
||||
}
|
||||
@@ -12253,7 +12255,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
.expect("Stdlib class available");
|
||||
|
||||
return class
|
||||
.to_specialized_class_type(self.db(), [first_ty, second_ty])
|
||||
.to_specialized_class_type(self.db(), &[first_ty, second_ty])
|
||||
.map(Type::from)
|
||||
.unwrap_or_else(Type::unknown);
|
||||
}
|
||||
@@ -13115,7 +13117,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
type_to_slice_argument(ty_step),
|
||||
) {
|
||||
(SliceArg::Arg(lower), SliceArg::Arg(upper), SliceArg::Arg(step)) => {
|
||||
KnownClass::Slice.to_specialized_instance(self.db(), [lower, upper, step])
|
||||
KnownClass::Slice.to_specialized_instance(self.db(), &[lower, upper, step])
|
||||
}
|
||||
_ => KnownClass::Slice.to_instance(self.db()),
|
||||
}
|
||||
|
||||
@@ -793,7 +793,7 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
||||
todo_type!("specialized recursive generic type alias"),
|
||||
generic_context.len(db),
|
||||
)
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
);
|
||||
return if in_type_expression {
|
||||
@@ -1131,7 +1131,9 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
||||
}
|
||||
let ty = class.to_specialized_instance(
|
||||
self.db(),
|
||||
args.iter().map(|node| self.infer_type_expression(node)),
|
||||
args.iter()
|
||||
.map(|node| self.infer_type_expression(node))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
if arguments.is_tuple_expr() {
|
||||
self.store_expression_type(arguments, ty);
|
||||
|
||||
@@ -235,7 +235,7 @@ mod stable {
|
||||
// `Iterable` but assigns `__iter__ = None` in the class body (or similar).
|
||||
type_property_test!(
|
||||
all_types_assignable_to_iterable_are_iterable, db,
|
||||
forall types t. t.is_assignable_to(db, KnownClass::Iterable.to_specialized_instance(db, [Type::object()])) => t.try_iterate(db).is_ok()
|
||||
forall types t. t.is_assignable_to(db, KnownClass::Iterable.to_specialized_instance(db, &[Type::object()])) => t.try_iterate(db).is_ok()
|
||||
);
|
||||
|
||||
// Our optimized `Type::negate()` function should always produce the exact same type
|
||||
|
||||
@@ -1015,7 +1015,7 @@ impl<'db> Type<'db> {
|
||||
// key types are a supertype of the extra items type?)
|
||||
(Type::TypedDict(_), _) => relation_visitor.visit((self, target, relation), || {
|
||||
KnownClass::Mapping
|
||||
.to_specialized_instance(db, [KnownClass::Str.to_instance(db), Type::object()])
|
||||
.to_specialized_instance(db, &[KnownClass::Str.to_instance(db), Type::object()])
|
||||
.has_relation_to_impl(
|
||||
db,
|
||||
target,
|
||||
@@ -2384,7 +2384,7 @@ impl<'db> Type<'db> {
|
||||
// `dict` *itself* is almost always disjoint from `TypedDict` -- but it's a good
|
||||
// approximation, and some false negatives are acceptable.
|
||||
(Type::TypedDict(_), other) | (other, Type::TypedDict(_)) => KnownClass::Dict
|
||||
.to_specialized_instance(db, [KnownClass::Str.to_instance(db), Type::any()])
|
||||
.to_specialized_instance(db, &[KnownClass::Str.to_instance(db), Type::any()])
|
||||
.has_relation_to_impl(
|
||||
db,
|
||||
other,
|
||||
|
||||
@@ -699,7 +699,7 @@ impl<'db> Signature<'db> {
|
||||
|
||||
pub(super) fn wrap_coroutine_return_type(self, db: &'db dyn Db) -> Self {
|
||||
let return_ty = KnownClass::CoroutineType
|
||||
.to_specialized_instance(db, [Type::any(), Type::any(), self.return_ty]);
|
||||
.to_specialized_instance(db, &[Type::any(), Type::any(), self.return_ty]);
|
||||
Self { return_ty, ..self }
|
||||
}
|
||||
|
||||
|
||||
@@ -1898,7 +1898,7 @@ impl<'db> TupleUnpacker<'db> {
|
||||
.into_all_elements_with_kind()
|
||||
.map(|builder| match builder {
|
||||
TupleElement::Variable(builder) => builder.try_build().unwrap_or_else(|| {
|
||||
KnownClass::List.to_specialized_instance(self.db, [Type::unknown()])
|
||||
KnownClass::List.to_specialized_instance(self.db, &[Type::unknown()])
|
||||
}),
|
||||
TupleElement::Fixed(builder)
|
||||
| TupleElement::Prefix(builder)
|
||||
@@ -1927,7 +1927,7 @@ impl<'db> VariableLengthTuple<UnionBuilder<'db>> {
|
||||
target.add_in_place(value);
|
||||
}
|
||||
self.variable_element_mut()
|
||||
.add_in_place(KnownClass::List.to_specialized_instance(db, [values.variable()]));
|
||||
.add_in_place(KnownClass::List.to_specialized_instance(db, &[values.variable()]));
|
||||
for (target, value) in
|
||||
(self.suffix_elements_mut().iter_mut()).zip(values.iter_suffix_elements())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user