Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/ty_python_semantic/src/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
63 changes: 31 additions & 32 deletions crates/ty_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -982,51 +982,50 @@ 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,
}
}

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,
Expand All @@ -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")
}

Expand All @@ -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,
Expand All @@ -1058,15 +1057,15 @@ 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")
}

pub(crate) const fn is_typed_dict(&self) -> bool {
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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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")
}

Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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,
Expand Down Expand Up @@ -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),

Expand All @@ -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
}
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions crates/ty_python_semantic/src/types/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_>>();
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions crates/ty_python_semantic/src/types/call/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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__")
}) =>
{
Expand All @@ -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__") => {
Expand Down Expand Up @@ -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)),
));
}
Expand Down Expand Up @@ -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;
};

Expand Down
10 changes: 5 additions & 5 deletions crates/ty_python_semantic/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down Expand Up @@ -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))
}

Expand Down Expand Up @@ -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| {
Expand Down Expand Up @@ -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()),
)));
}

Expand All @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion crates/ty_python_semantic/src/types/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down
4 changes: 2 additions & 2 deletions crates/ty_python_semantic/src/types/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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}"))
Expand Down
Loading
Loading