mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-17 13:57:25 +00:00
[ty] Rename Type unwrapping methods (#20857)
## Summary Rename "unwrapping" methods on `Type` from e.g. `Type::into_class_literal` to `Type::as_class_literal`. I personally find that name more intuitive, since no transformation of any kind is happening. We are just unwrapping from certain enum variants. An alternative would be `try_as_class_literal`, which would follow the [`strum` naming scheme](https://docs.rs/strum/latest/strum/derive.EnumTryAs.html), but is slightly longer. Also rename `Type::into_callable` to `Type::try_upcast_to_callable`. Note that I intentionally kept names like `FunctionType::into_callable_type`, because those return `CallableType`, not `Option<Type<…>>`. ## Test Plan Pure refactoring
This commit is contained in:
parent
e338d2095e
commit
f73bb45be6
17 changed files with 81 additions and 87 deletions
|
@ -1447,7 +1447,7 @@ mod implicit_globals {
|
|||
fn module_type_symbols<'db>(db: &'db dyn Db) -> smallvec::SmallVec<[ast::name::Name; 8]> {
|
||||
let Some(module_type) = KnownClass::ModuleType
|
||||
.to_class_literal(db)
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
else {
|
||||
// The most likely way we get here is if a user specified a `--custom-typeshed-dir`
|
||||
// without a `types.pyi` stub in the `stdlib/` directory
|
||||
|
|
|
@ -854,7 +854,7 @@ impl ReachabilityConstraints {
|
|||
}
|
||||
|
||||
let overloads_iterator =
|
||||
if let Some(Type::Callable(callable)) = ty.into_callable(db) {
|
||||
if let Some(Type::Callable(callable)) = ty.try_upcast_to_callable(db) {
|
||||
callable.signatures(db).overloads.iter()
|
||||
} else {
|
||||
return Truthiness::AlwaysFalse.negate_if(!predicate.is_positive);
|
||||
|
|
|
@ -982,39 +982,39 @@ impl<'db> Type<'db> {
|
|||
matches!(self, Type::TypeVar(_))
|
||||
}
|
||||
|
||||
pub(crate) const fn into_type_var(self) -> Option<BoundTypeVarInstance<'db>> {
|
||||
pub(crate) const fn as_typevar(self) -> Option<BoundTypeVarInstance<'db>> {
|
||||
match self {
|
||||
Type::TypeVar(bound_typevar) => Some(bound_typevar),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn has_type_var(self, db: &'db dyn Db) -> bool {
|
||||
pub(crate) fn has_typevar(self, db: &'db dyn Db) -> bool {
|
||||
any_over_type(db, self, &|ty| matches!(ty, Type::TypeVar(_)), false)
|
||||
}
|
||||
|
||||
pub(crate) const fn into_class_literal(self) -> Option<ClassLiteral<'db>> {
|
||||
pub(crate) const fn as_class_literal(self) -> Option<ClassLiteral<'db>> {
|
||||
match self {
|
||||
Type::ClassLiteral(class_type) => Some(class_type),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn into_type_alias(self) -> Option<TypeAliasType<'db>> {
|
||||
pub(crate) const fn as_type_alias(self) -> Option<TypeAliasType<'db>> {
|
||||
match self {
|
||||
Type::KnownInstance(KnownInstanceType::TypeAliasType(type_alias)) => Some(type_alias),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn into_dynamic(self) -> Option<DynamicType<'db>> {
|
||||
pub(crate) const fn as_dynamic(self) -> Option<DynamicType<'db>> {
|
||||
match self {
|
||||
Type::Dynamic(dynamic_type) => Some(dynamic_type),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn unwrap_as_callable_type(self) -> Option<CallableType<'db>> {
|
||||
pub(crate) const fn as_callable(self) -> Option<CallableType<'db>> {
|
||||
match self {
|
||||
Type::Callable(callable_type) => Some(callable_type),
|
||||
_ => None,
|
||||
|
@ -1022,11 +1022,10 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub(crate) const fn expect_dynamic(self) -> DynamicType<'db> {
|
||||
self.into_dynamic()
|
||||
.expect("Expected a Type::Dynamic variant")
|
||||
self.as_dynamic().expect("Expected a Type::Dynamic variant")
|
||||
}
|
||||
|
||||
pub(crate) const fn into_protocol_instance(self) -> Option<ProtocolInstanceType<'db>> {
|
||||
pub(crate) const fn as_protocol_instance(self) -> Option<ProtocolInstanceType<'db>> {
|
||||
match self {
|
||||
Type::ProtocolInstance(instance) => Some(instance),
|
||||
_ => None,
|
||||
|
@ -1035,7 +1034,7 @@ impl<'db> Type<'db> {
|
|||
|
||||
#[track_caller]
|
||||
pub(crate) fn expect_class_literal(self) -> ClassLiteral<'db> {
|
||||
self.into_class_literal()
|
||||
self.as_class_literal()
|
||||
.expect("Expected a Type::ClassLiteral variant")
|
||||
}
|
||||
|
||||
|
@ -1048,7 +1047,7 @@ impl<'db> Type<'db> {
|
|||
matches!(self, Type::ClassLiteral(..))
|
||||
}
|
||||
|
||||
pub(crate) fn into_enum_literal(self) -> Option<EnumLiteralType<'db>> {
|
||||
pub(crate) fn as_enum_literal(self) -> Option<EnumLiteralType<'db>> {
|
||||
match self {
|
||||
Type::EnumLiteral(enum_literal) => Some(enum_literal),
|
||||
_ => None,
|
||||
|
@ -1058,7 +1057,7 @@ impl<'db> Type<'db> {
|
|||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
pub(crate) fn expect_enum_literal(self) -> EnumLiteralType<'db> {
|
||||
self.into_enum_literal()
|
||||
self.as_enum_literal()
|
||||
.expect("Expected a Type::EnumLiteral variant")
|
||||
}
|
||||
|
||||
|
@ -1066,7 +1065,7 @@ impl<'db> Type<'db> {
|
|||
matches!(self, Type::TypedDict(..))
|
||||
}
|
||||
|
||||
pub(crate) fn into_typed_dict(self) -> Option<TypedDictType<'db>> {
|
||||
pub(crate) fn as_typed_dict(self) -> Option<TypedDictType<'db>> {
|
||||
match self {
|
||||
Type::TypedDict(typed_dict) => Some(typed_dict),
|
||||
_ => None,
|
||||
|
@ -1100,14 +1099,14 @@ impl<'db> Type<'db> {
|
|||
))
|
||||
}
|
||||
|
||||
pub(crate) const fn into_module_literal(self) -> Option<ModuleLiteralType<'db>> {
|
||||
pub(crate) const fn as_module_literal(self) -> Option<ModuleLiteralType<'db>> {
|
||||
match self {
|
||||
Type::ModuleLiteral(module) => Some(module),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn into_union(self) -> Option<UnionType<'db>> {
|
||||
pub(crate) const fn as_union(self) -> Option<UnionType<'db>> {
|
||||
match self {
|
||||
Type::Union(union_type) => Some(union_type),
|
||||
_ => None,
|
||||
|
@ -1117,10 +1116,10 @@ impl<'db> Type<'db> {
|
|||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
pub(crate) fn expect_union(self) -> UnionType<'db> {
|
||||
self.into_union().expect("Expected a Type::Union variant")
|
||||
self.as_union().expect("Expected a Type::Union variant")
|
||||
}
|
||||
|
||||
pub(crate) const fn into_function_literal(self) -> Option<FunctionType<'db>> {
|
||||
pub(crate) const fn as_function_literal(self) -> Option<FunctionType<'db>> {
|
||||
match self {
|
||||
Type::FunctionLiteral(function_type) => Some(function_type),
|
||||
_ => None,
|
||||
|
@ -1130,7 +1129,7 @@ impl<'db> Type<'db> {
|
|||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
pub(crate) fn expect_function_literal(self) -> FunctionType<'db> {
|
||||
self.into_function_literal()
|
||||
self.as_function_literal()
|
||||
.expect("Expected a Type::FunctionLiteral variant")
|
||||
}
|
||||
|
||||
|
@ -1139,7 +1138,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub(crate) fn is_union_of_single_valued(&self, db: &'db dyn Db) -> bool {
|
||||
self.into_union().is_some_and(|union| {
|
||||
self.as_union().is_some_and(|union| {
|
||||
union.elements(db).iter().all(|ty| {
|
||||
ty.is_single_valued(db)
|
||||
|| ty.is_bool(db)
|
||||
|
@ -1152,7 +1151,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub(crate) fn is_union_with_single_valued(&self, db: &'db dyn Db) -> bool {
|
||||
self.into_union().is_some_and(|union| {
|
||||
self.as_union().is_some_and(|union| {
|
||||
union.elements(db).iter().any(|ty| {
|
||||
ty.is_single_valued(db)
|
||||
|| ty.is_bool(db)
|
||||
|
@ -1164,7 +1163,7 @@ impl<'db> Type<'db> {
|
|||
|| (self.is_enum(db) && !self.overrides_equality(db))
|
||||
}
|
||||
|
||||
pub(crate) fn into_string_literal(self) -> Option<StringLiteralType<'db>> {
|
||||
pub(crate) fn as_string_literal(self) -> Option<StringLiteralType<'db>> {
|
||||
match self {
|
||||
Type::StringLiteral(string_literal) => Some(string_literal),
|
||||
_ => None,
|
||||
|
@ -1404,7 +1403,7 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_callable(self, db: &'db dyn Db) -> Option<Type<'db>> {
|
||||
pub(crate) fn try_upcast_to_callable(self, db: &'db dyn Db) -> Option<Type<'db>> {
|
||||
match self {
|
||||
Type::Callable(_) => Some(self),
|
||||
|
||||
|
@ -1427,7 +1426,7 @@ impl<'db> Type<'db> {
|
|||
.place;
|
||||
|
||||
if let Place::Type(ty, Boundness::Bound) = call_symbol {
|
||||
ty.into_callable(db)
|
||||
ty.try_upcast_to_callable(db)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1447,13 +1446,13 @@ impl<'db> Type<'db> {
|
|||
)),
|
||||
},
|
||||
|
||||
Type::Union(union) => union.try_map(db, |element| element.into_callable(db)),
|
||||
Type::Union(union) => union.try_map(db, |element| element.try_upcast_to_callable(db)),
|
||||
|
||||
Type::EnumLiteral(enum_literal) => {
|
||||
enum_literal.enum_class_instance(db).into_callable(db)
|
||||
}
|
||||
Type::EnumLiteral(enum_literal) => enum_literal
|
||||
.enum_class_instance(db)
|
||||
.try_upcast_to_callable(db),
|
||||
|
||||
Type::TypeAlias(alias) => alias.value_type(db).into_callable(db),
|
||||
Type::TypeAlias(alias) => alias.value_type(db).try_upcast_to_callable(db),
|
||||
|
||||
Type::KnownBoundMethod(method) => Some(Type::Callable(CallableType::new(
|
||||
db,
|
||||
|
@ -1943,7 +1942,7 @@ impl<'db> Type<'db> {
|
|||
}),
|
||||
|
||||
(_, Type::Callable(_)) => relation_visitor.visit((self, target, relation), || {
|
||||
self.into_callable(db).when_some_and(|callable| {
|
||||
self.try_upcast_to_callable(db).when_some_and(|callable| {
|
||||
callable.has_relation_to_impl(
|
||||
db,
|
||||
target,
|
||||
|
@ -8083,7 +8082,7 @@ impl<'db> TypeVarInstance<'db> {
|
|||
TypeVarBoundOrConstraints::UpperBound(upper_bound.to_instance(db)?)
|
||||
}
|
||||
TypeVarBoundOrConstraints::Constraints(constraints) => {
|
||||
TypeVarBoundOrConstraints::Constraints(constraints.to_instance(db)?.into_union()?)
|
||||
TypeVarBoundOrConstraints::Constraints(constraints.to_instance(db)?.as_union()?)
|
||||
}
|
||||
};
|
||||
let identity = TypeVarIdentity::new(
|
||||
|
@ -8131,7 +8130,7 @@ impl<'db> TypeVarInstance<'db> {
|
|||
DefinitionKind::TypeVar(typevar) => {
|
||||
let typevar_node = typevar.node(&module);
|
||||
definition_expression_type(db, definition, typevar_node.bound.as_ref()?)
|
||||
.into_union()?
|
||||
.as_union()?
|
||||
}
|
||||
// legacy typevar
|
||||
DefinitionKind::Assignment(assignment) => {
|
||||
|
@ -10713,7 +10712,7 @@ impl<'db> TypeAliasType<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_pep_695_type_alias(self) -> Option<PEP695TypeAliasType<'db>> {
|
||||
pub(crate) fn as_pep_695_type_alias(self) -> Option<PEP695TypeAliasType<'db>> {
|
||||
match self {
|
||||
TypeAliasType::PEP695(type_alias) => Some(type_alias),
|
||||
TypeAliasType::ManualPEP695(_) => None,
|
||||
|
|
|
@ -421,7 +421,7 @@ impl<'db> UnionBuilder<'db> {
|
|||
.elements
|
||||
.iter()
|
||||
.filter_map(UnionElement::to_type_element)
|
||||
.filter_map(Type::into_enum_literal)
|
||||
.filter_map(Type::as_enum_literal)
|
||||
.map(|literal| literal.name(self.db).clone())
|
||||
.chain(std::iter::once(enum_member_to_add.name(self.db).clone()))
|
||||
.collect::<FxOrderSet<_>>();
|
||||
|
@ -650,7 +650,7 @@ impl<'db> IntersectionBuilder<'db> {
|
|||
for intersection in &self.intersections {
|
||||
if intersection.negative.iter().any(|negative| {
|
||||
negative
|
||||
.into_enum_literal()
|
||||
.as_enum_literal()
|
||||
.is_some_and(|lit| lit.enum_class_instance(self.db) == ty)
|
||||
}) {
|
||||
contains_enum_literal_as_negative_element = true;
|
||||
|
|
|
@ -378,7 +378,7 @@ impl<'db> Bindings<'db> {
|
|||
..,
|
||||
] if property.getter(db).is_some_and(|getter| {
|
||||
getter
|
||||
.into_function_literal()
|
||||
.as_function_literal()
|
||||
.is_some_and(|f| f.name(db) == "__name__")
|
||||
}) =>
|
||||
{
|
||||
|
@ -392,7 +392,7 @@ impl<'db> Bindings<'db> {
|
|||
] => {
|
||||
match property
|
||||
.getter(db)
|
||||
.and_then(Type::into_function_literal)
|
||||
.and_then(Type::as_function_literal)
|
||||
.map(|f| f.name(db).as_str())
|
||||
{
|
||||
Some("__name__") => {
|
||||
|
@ -785,7 +785,7 @@ impl<'db> Bindings<'db> {
|
|||
// be a "(specialised) protocol class", but `typing.is_protocol(SupportsAbs[int])` returns
|
||||
// `False` at runtime, so we do not set the return type to `Literal[True]` in this case.
|
||||
overload.set_return_type(Type::BooleanLiteral(
|
||||
ty.into_class_literal()
|
||||
ty.as_class_literal()
|
||||
.is_some_and(|class| class.is_protocol(db)),
|
||||
));
|
||||
}
|
||||
|
@ -817,7 +817,7 @@ impl<'db> Bindings<'db> {
|
|||
continue;
|
||||
};
|
||||
|
||||
let Some(attr_name) = attr_name.into_string_literal() else {
|
||||
let Some(attr_name) = attr_name.as_string_literal() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
|
@ -1724,7 +1724,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
/// Determine if this is an abstract class.
|
||||
pub(super) fn is_abstract(self, db: &'db dyn Db) -> bool {
|
||||
self.metaclass(db)
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
.is_some_and(|metaclass| metaclass.is_known(db, KnownClass::ABCMeta))
|
||||
}
|
||||
|
||||
|
@ -1758,7 +1758,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
) -> impl Iterator<Item = KnownFunction> + 'db {
|
||||
self.decorators(db)
|
||||
.iter()
|
||||
.filter_map(|deco| deco.into_function_literal())
|
||||
.filter_map(|deco| deco.as_function_literal())
|
||||
.filter_map(|decorator| decorator.known(db))
|
||||
}
|
||||
|
||||
|
@ -2398,7 +2398,7 @@ impl<'db> ClassLiteral<'db> {
|
|||
(CodeGeneratorKind::NamedTuple, name) if name != "__init__" => {
|
||||
KnownClass::NamedTupleFallback
|
||||
.to_class_literal(db)
|
||||
.into_class_literal()?
|
||||
.as_class_literal()?
|
||||
.own_class_member(db, self.inherited_generic_context(db), None, name)
|
||||
.ignore_possibly_unbound()
|
||||
.map(|ty| {
|
||||
|
@ -5250,7 +5250,7 @@ impl KnownClass {
|
|||
};
|
||||
|
||||
overload.set_return_type(Type::KnownInstance(KnownInstanceType::Deprecated(
|
||||
DeprecatedInstance::new(db, message.into_string_literal()),
|
||||
DeprecatedInstance::new(db, message.as_string_literal()),
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -5270,7 +5270,7 @@ impl KnownClass {
|
|||
return;
|
||||
};
|
||||
|
||||
let Some(name) = name.into_string_literal() else {
|
||||
let Some(name) = name.as_string_literal() else {
|
||||
if let Some(builder) =
|
||||
context.report_lint(&INVALID_TYPE_ALIAS_TYPE, call_expression)
|
||||
{
|
||||
|
|
|
@ -192,7 +192,7 @@ impl<'db, 'ast> InferContext<'db, 'ast> {
|
|||
.ancestor_scopes(scope_id)
|
||||
.filter_map(|(_, scope)| scope.node().as_function())
|
||||
.map(|node| binding_type(self.db, index.expect_single_definition(node)))
|
||||
.filter_map(Type::into_function_literal);
|
||||
.filter_map(Type::as_function_literal);
|
||||
|
||||
// Iterate over all functions and test if any is decorated with `@no_type_check`.
|
||||
function_scope_tys.any(|function_ty| {
|
||||
|
|
|
@ -1145,7 +1145,7 @@ fn is_instance_truthiness<'db>(
|
|||
fn is_mode_with_nontrivial_return_type<'db>(db: &'db dyn Db, mode: Type<'db>) -> bool {
|
||||
// Return true for any mode that doesn't match typeshed's
|
||||
// `OpenTextMode` type alias (<https://github.com/python/typeshed/blob/6937a9b193bfc2f0696452d58aad96d7627aa29a/stdlib/_typeshed/__init__.pyi#L220>).
|
||||
mode.into_string_literal().is_none_or(|mode| {
|
||||
mode.as_string_literal().is_none_or(|mode| {
|
||||
!matches!(
|
||||
mode.value(db),
|
||||
"r+" | "+r"
|
||||
|
@ -1557,7 +1557,7 @@ impl KnownFunction {
|
|||
return;
|
||||
}
|
||||
let mut diagnostic = if let Some(message) = message
|
||||
.and_then(Type::into_string_literal)
|
||||
.and_then(Type::as_string_literal)
|
||||
.map(|s| s.value(db))
|
||||
{
|
||||
builder.into_diagnostic(format_args!("Static assertion error: {message}"))
|
||||
|
|
|
@ -35,7 +35,7 @@ pub(crate) fn enclosing_generic_contexts<'db>(
|
|||
NodeWithScopeKind::Class(class) => {
|
||||
let definition = index.expect_single_definition(class);
|
||||
binding_type(db, definition)
|
||||
.into_class_literal()?
|
||||
.as_class_literal()?
|
||||
.generic_context(db)
|
||||
}
|
||||
NodeWithScopeKind::Function(function) => {
|
||||
|
@ -43,15 +43,15 @@ pub(crate) fn enclosing_generic_contexts<'db>(
|
|||
infer_definition_types(db, definition)
|
||||
.undecorated_type()
|
||||
.expect("function should have undecorated type")
|
||||
.into_function_literal()?
|
||||
.as_function_literal()?
|
||||
.last_definition_signature(db)
|
||||
.generic_context
|
||||
}
|
||||
NodeWithScopeKind::TypeAlias(type_alias) => {
|
||||
let definition = index.expect_single_definition(type_alias);
|
||||
binding_type(db, definition)
|
||||
.into_type_alias()?
|
||||
.into_pep_695_type_alias()?
|
||||
.as_type_alias()?
|
||||
.as_pep_695_type_alias()?
|
||||
.generic_context(db)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -1284,7 +1284,7 @@ impl<'db> SpecializationBuilder<'db> {
|
|||
let types_have_typevars = formal_union
|
||||
.elements(self.db)
|
||||
.iter()
|
||||
.filter(|ty| ty.has_type_var(self.db));
|
||||
.filter(|ty| ty.has_typevar(self.db));
|
||||
let Ok(Type::TypeVar(formal_bound_typevar)) = types_have_typevars.exactly_one()
|
||||
else {
|
||||
return Ok(());
|
||||
|
@ -1305,7 +1305,7 @@ impl<'db> SpecializationBuilder<'db> {
|
|||
// type. (Note that we've already handled above the case where the actual is
|
||||
// assignable to any _non-typevar_ union element.)
|
||||
let bound_typevars =
|
||||
(formal.elements(self.db).iter()).filter_map(|ty| ty.into_type_var());
|
||||
(formal.elements(self.db).iter()).filter_map(|ty| ty.as_typevar());
|
||||
if let Ok(bound_typevar) = bound_typevars.exactly_one() {
|
||||
self.add_type_mapping(bound_typevar, actual);
|
||||
}
|
||||
|
|
|
@ -777,7 +777,7 @@ pub fn definitions_for_keyword_argument<'db>(
|
|||
|
||||
let mut resolved_definitions = Vec::new();
|
||||
|
||||
if let Some(Type::Callable(callable_type)) = func_type.into_callable(db) {
|
||||
if let Some(Type::Callable(callable_type)) = func_type.try_upcast_to_callable(db) {
|
||||
let signatures = callable_type.signatures(db);
|
||||
|
||||
// For each signature, find the parameter with the matching name
|
||||
|
@ -872,7 +872,7 @@ pub fn call_signature_details<'db>(
|
|||
let func_type = call_expr.func.inferred_type(model);
|
||||
|
||||
// Use into_callable to handle all the complex type conversions
|
||||
if let Some(callable_type) = func_type.into_callable(db) {
|
||||
if let Some(callable_type) = func_type.try_upcast_to_callable(db) {
|
||||
let call_arguments =
|
||||
CallArguments::from_arguments(&call_expr.arguments, |_, splatted_value| {
|
||||
splatted_value.inferred_type(model)
|
||||
|
|
|
@ -490,7 +490,7 @@ pub(crate) fn nearest_enclosing_class<'db>(
|
|||
infer_definition_types(db, definition)
|
||||
.declaration_type(definition)
|
||||
.inner_type()
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -514,7 +514,7 @@ pub(crate) fn nearest_enclosing_function<'db>(
|
|||
inference
|
||||
.undecorated_type()
|
||||
.unwrap_or_else(|| inference.declaration_type(definition).inner_type())
|
||||
.into_function_literal()
|
||||
.as_function_literal()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -531,7 +531,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
// Filter out class literals that result from imports
|
||||
if let DefinitionKind::Class(class) = definition.kind(self.db()) {
|
||||
ty.inner_type()
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
.map(|class_literal| (class_literal, class.node(self.module())))
|
||||
} else {
|
||||
None
|
||||
|
@ -939,7 +939,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
if !matches!(definition.kind(self.db()), DefinitionKind::Function(_)) {
|
||||
return None;
|
||||
}
|
||||
let function = ty.inner_type().into_function_literal()?;
|
||||
let function = ty.inner_type().as_function_literal()?;
|
||||
if function.has_known_decorator(self.db(), FunctionDecorators::OVERLOAD) {
|
||||
Some(definition.place(self.db()))
|
||||
} else {
|
||||
|
@ -2200,12 +2200,10 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
{
|
||||
Ok(return_ty) => {
|
||||
let is_input_function_like = inferred_ty
|
||||
.into_callable(self.db())
|
||||
.and_then(Type::unwrap_as_callable_type)
|
||||
.try_upcast_to_callable(self.db())
|
||||
.and_then(Type::as_callable)
|
||||
.is_some_and(|callable| callable.is_function_like(self.db()));
|
||||
if is_input_function_like
|
||||
&& let Some(callable_type) = return_ty.unwrap_as_callable_type()
|
||||
{
|
||||
if is_input_function_like && let Some(callable_type) = return_ty.as_callable() {
|
||||
// When a method on a class is decorated with a function that returns a `Callable`, assume that
|
||||
// the returned callable is also function-like. See "Decorating a method with a `Callable`-typed
|
||||
// decorator" in `callables_as_descriptors.md` for the extended explanation.
|
||||
|
@ -2546,7 +2544,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
for decorator in decorator_list {
|
||||
let decorator_ty = self.infer_decorator(decorator);
|
||||
if decorator_ty
|
||||
.into_function_literal()
|
||||
.as_function_literal()
|
||||
.is_some_and(|function| function.is_known(self.db(), KnownFunction::Dataclass))
|
||||
{
|
||||
dataclass_params = Some(DataclassParams::default());
|
||||
|
@ -3342,8 +3340,8 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
let assigned_d = assigned_ty.display(db);
|
||||
let value_d = value_ty.display(db);
|
||||
|
||||
if let Some(typed_dict) = value_ty.into_typed_dict() {
|
||||
if let Some(key) = slice_ty.into_string_literal() {
|
||||
if let Some(typed_dict) = value_ty.as_typed_dict() {
|
||||
if let Some(key) = slice_ty.as_string_literal() {
|
||||
let key = key.value(self.db());
|
||||
validate_typed_dict_key_assignment(
|
||||
&self.context,
|
||||
|
@ -4056,7 +4054,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
);
|
||||
|
||||
let typevar_class = callable_type
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
.and_then(|cls| cls.known(self.db()))
|
||||
.filter(|cls| {
|
||||
matches!(cls, KnownClass::TypeVar | KnownClass::ExtensionsTypeVar)
|
||||
|
@ -4278,10 +4276,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
);
|
||||
};
|
||||
|
||||
let Some(name_param) = name_param_ty
|
||||
.into_string_literal()
|
||||
.map(|name| name.value(db))
|
||||
else {
|
||||
let Some(name_param) = name_param_ty.as_string_literal().map(|name| name.value(db)) else {
|
||||
return error(
|
||||
&self.context,
|
||||
"The first argument to `TypeVar` must be a string literal.",
|
||||
|
@ -5036,7 +5031,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
// Avoid looking up attributes on a module if a module imports from itself
|
||||
// (e.g. `from parent import submodule` inside the `parent` module).
|
||||
let import_is_self_referential = module_ty
|
||||
.into_module_literal()
|
||||
.as_module_literal()
|
||||
.is_some_and(|module| Some(self.file()) == module.module(self.db()).file(self.db()));
|
||||
|
||||
// First try loading the requested attribute from the module.
|
||||
|
@ -5871,7 +5866,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
} = dict;
|
||||
|
||||
// Validate `TypedDict` dictionary literal assignments.
|
||||
if let Some(typed_dict) = tcx.annotation.and_then(Type::into_typed_dict)
|
||||
if let Some(typed_dict) = tcx.annotation.and_then(Type::as_typed_dict)
|
||||
&& let Some(ty) = self.infer_typed_dict_expression(dict, typed_dict)
|
||||
{
|
||||
return ty;
|
||||
|
@ -6595,10 +6590,10 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
self.infer_all_argument_types(arguments, &mut call_arguments, &bindings);
|
||||
|
||||
// Validate `TypedDict` constructor calls after argument type inference
|
||||
if let Some(class_literal) = callable_type.into_class_literal() {
|
||||
if let Some(class_literal) = callable_type.as_class_literal() {
|
||||
if class_literal.is_typed_dict(self.db()) {
|
||||
let typed_dict_type = Type::typed_dict(ClassType::NonGeneric(class_literal));
|
||||
if let Some(typed_dict) = typed_dict_type.into_typed_dict() {
|
||||
if let Some(typed_dict) = typed_dict_type.as_typed_dict() {
|
||||
validate_typed_dict_constructor(
|
||||
&self.context,
|
||||
typed_dict,
|
||||
|
@ -9459,7 +9454,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
}
|
||||
}
|
||||
CallErrorKind::BindingError => {
|
||||
if let Some(typed_dict) = value_ty.into_typed_dict() {
|
||||
if let Some(typed_dict) = value_ty.as_typed_dict() {
|
||||
let slice_node = subscript.slice.as_ref();
|
||||
|
||||
report_invalid_key_on_typed_dict(
|
||||
|
@ -9566,7 +9561,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
|
||||
// TODO: properly handle old-style generics; get rid of this temporary hack
|
||||
if !value_ty
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
.is_some_and(|class| class.iter_mro(db, None).contains(&ClassBase::Generic))
|
||||
{
|
||||
report_non_subscriptable(context, value_node.into(), value_ty, "__class_getitem__");
|
||||
|
|
|
@ -1157,7 +1157,7 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
|
||||
let argument_type = self.infer_expression(&arguments[0], TypeContext::default());
|
||||
|
||||
let Some(callable_type) = argument_type.into_callable(db) else {
|
||||
let Some(callable_type) = argument_type.try_upcast_to_callable(db) else {
|
||||
if let Some(builder) = self
|
||||
.context
|
||||
.report_lint(&INVALID_TYPE_FORM, arguments_slice)
|
||||
|
|
|
@ -165,7 +165,7 @@ impl<'db> Type<'db> {
|
|||
// from a protocol `Q` to be a subtype of `Q` to be a subtype of `Q` if it overrides
|
||||
// `Q`'s members in a Liskov-incompatible way.
|
||||
let type_to_test = self
|
||||
.into_protocol_instance()
|
||||
.as_protocol_instance()
|
||||
.and_then(ProtocolInstanceType::as_nominal_type)
|
||||
.map(Type::NominalInstance)
|
||||
.unwrap_or(self);
|
||||
|
|
|
@ -634,7 +634,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
|||
// Add the narrowed values from the RHS first, to keep literals before broader types.
|
||||
builder = builder.add(rhs_values);
|
||||
|
||||
if let Some(lhs_union) = lhs_ty.into_union() {
|
||||
if let Some(lhs_union) = lhs_ty.as_union() {
|
||||
for element in lhs_union.elements(self.db) {
|
||||
// Keep only the non-single-valued portion of the original type.
|
||||
if !element.is_single_valued(self.db)
|
||||
|
@ -671,7 +671,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
|||
let mut single_builder = UnionBuilder::new(self.db);
|
||||
let mut rest_builder = UnionBuilder::new(self.db);
|
||||
|
||||
if let Some(lhs_union) = lhs_ty.into_union() {
|
||||
if let Some(lhs_union) = lhs_ty.as_union() {
|
||||
for element in lhs_union.elements(self.db) {
|
||||
if element.is_single_valued(self.db)
|
||||
|| element.is_literal_string()
|
||||
|
@ -840,7 +840,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
|||
let callable_type = inference.expression_type(&**callable);
|
||||
|
||||
if callable_type
|
||||
.into_class_literal()
|
||||
.as_class_literal()
|
||||
.is_some_and(|c| c.is_known(self.db, KnownClass::Type))
|
||||
{
|
||||
let place = self.expect_place(&target);
|
||||
|
@ -903,7 +903,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
|||
if function == KnownFunction::HasAttr {
|
||||
let attr = inference
|
||||
.expression_type(second_arg)
|
||||
.into_string_literal()?
|
||||
.as_string_literal()?
|
||||
.value(self.db);
|
||||
|
||||
if !is_identifier(attr) {
|
||||
|
|
|
@ -641,7 +641,7 @@ impl<'a, 'db> ProtocolMember<'a, 'db> {
|
|||
// unfortunately not sufficient to obtain the `Callable` supertypes of these types, due to the
|
||||
// complex interaction between `__new__`, `__init__` and metaclass `__call__`.
|
||||
let attribute_type = if self.name == "__call__" {
|
||||
let Some(attribute_type) = other.into_callable(db) else {
|
||||
let Some(attribute_type) = other.try_upcast_to_callable(db) else {
|
||||
return ConstraintSet::from(false);
|
||||
};
|
||||
attribute_type
|
||||
|
|
|
@ -55,7 +55,7 @@ fn infer_method_information<'db>(
|
|||
let method = infer_definition_types(db, definition)
|
||||
.declaration_type(definition)
|
||||
.inner_type()
|
||||
.into_function_literal()?;
|
||||
.as_function_literal()?;
|
||||
|
||||
let class_def = index.expect_single_definition(class_node);
|
||||
let (class_literal, class_is_generic) = match infer_definition_types(db, class_def)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue