From ff0ed4e75208ef62cce08feb79c98a8f77bbaad9 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 12 Dec 2025 14:06:35 +0000 Subject: [PATCH] [ty] Add `KnownUnion::to_type()` (#21948) --- crates/ty_python_semantic/src/types.rs | 43 +++++++++++-------- .../src/types/ide_support.rs | 22 +++------- .../ty_python_semantic/src/types/newtype.rs | 21 ++------- 3 files changed, 32 insertions(+), 54 deletions(-) diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index ca06e8ca79..1bbcc038cc 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -7281,29 +7281,12 @@ impl<'db> Type<'db> { // https://typing.python.org/en/latest/spec/special-types.html#special-cases-for-float-and-complex Type::ClassLiteral(class) => { let ty = match class.known(db) { - Some(KnownClass::Complex) => UnionType::from_elements( - db, - [ - KnownClass::Int.to_instance(db), - KnownClass::Float.to_instance(db), - KnownClass::Complex.to_instance(db), - ], - ), - Some(KnownClass::Float) => UnionType::from_elements( - db, - [ - KnownClass::Int.to_instance(db), - KnownClass::Float.to_instance(db), - ], - ), - _ if class.is_typed_dict(db) => { - Type::typed_dict(class.default_specialization(db)) - } + Some(KnownClass::Complex) => KnownUnion::Complex.to_type(db), + Some(KnownClass::Float) => KnownUnion::Float.to_type(db), _ => Type::instance(db, class.default_specialization(db)), }; Ok(ty) } - Type::GenericAlias(alias) if alias.is_typed_dict(db) => Ok(Type::typed_dict(*alias)), Type::GenericAlias(alias) => Ok(Type::instance(db, ClassType::from(*alias))), Type::SubclassOf(_) @@ -14008,6 +13991,28 @@ pub(crate) enum KnownUnion { Complex, // `int | float | complex` } +impl KnownUnion { + pub(crate) fn to_type(self, db: &dyn Db) -> Type<'_> { + match self { + KnownUnion::Float => UnionType::from_elements( + db, + [ + KnownClass::Int.to_instance(db), + KnownClass::Float.to_instance(db), + ], + ), + KnownUnion::Complex => UnionType::from_elements( + db, + [ + KnownClass::Int.to_instance(db), + KnownClass::Float.to_instance(db), + KnownClass::Complex.to_instance(db), + ], + ), + } + } +} + #[salsa::interned(debug, heap_size=IntersectionType::heap_size)] pub struct IntersectionType<'db> { /// The intersection type includes only values in all of these types. diff --git a/crates/ty_python_semantic/src/types/ide_support.rs b/crates/ty_python_semantic/src/types/ide_support.rs index 4087d125c6..8de1d00d28 100644 --- a/crates/ty_python_semantic/src/types/ide_support.rs +++ b/crates/ty_python_semantic/src/types/ide_support.rs @@ -7,8 +7,9 @@ use crate::semantic_index::definition::DefinitionKind; use crate::semantic_index::{attribute_scopes, global_scope, semantic_index, use_def_map}; use crate::types::call::{CallArguments, MatchedArgument}; use crate::types::signatures::{ParameterKind, Signature}; -use crate::types::{CallDunderError, UnionType}; -use crate::types::{CallableTypes, ClassBase, KnownClass, Type, TypeContext}; +use crate::types::{ + CallDunderError, CallableTypes, ClassBase, KnownUnion, Type, TypeContext, UnionType, +}; use crate::{Db, DisplaySettings, HasType, SemanticModel}; use ruff_db::files::FileRange; use ruff_db::parsed::parsed_module; @@ -193,21 +194,8 @@ pub fn definitions_for_name<'db>( fn is_float_or_complex_annotation(db: &dyn Db, ty: UnionType, name: &str) -> bool { let float_or_complex_ty = match name { - "float" => UnionType::from_elements( - db, - [ - KnownClass::Int.to_instance(db), - KnownClass::Float.to_instance(db), - ], - ), - "complex" => UnionType::from_elements( - db, - [ - KnownClass::Int.to_instance(db), - KnownClass::Float.to_instance(db), - KnownClass::Complex.to_instance(db), - ], - ), + "float" => KnownUnion::Float.to_type(db), + "complex" => KnownUnion::Complex.to_type(db), _ => return false, } .expect_union(); diff --git a/crates/ty_python_semantic/src/types/newtype.rs b/crates/ty_python_semantic/src/types/newtype.rs index cc6f2cff69..906999a9f2 100644 --- a/crates/ty_python_semantic/src/types/newtype.rs +++ b/crates/ty_python_semantic/src/types/newtype.rs @@ -3,9 +3,7 @@ use std::collections::BTreeSet; use crate::Db; use crate::semantic_index::definition::{Definition, DefinitionKind}; use crate::types::constraints::ConstraintSet; -use crate::types::{ - ClassType, KnownClass, KnownUnion, Type, UnionType, definition_expression_type, visitor, -}; +use crate::types::{ClassType, KnownUnion, Type, definition_expression_type, visitor}; use ruff_db::parsed::parsed_module; use ruff_python_ast as ast; @@ -236,21 +234,8 @@ impl<'db> NewTypeBase<'db> { match self { NewTypeBase::ClassType(class_type) => Type::instance(db, class_type), NewTypeBase::NewType(newtype) => Type::NewTypeInstance(newtype), - NewTypeBase::Float => UnionType::from_elements( - db, - [ - KnownClass::Int.to_instance(db), - KnownClass::Float.to_instance(db), - ], - ), - NewTypeBase::Complex => UnionType::from_elements( - db, - [ - KnownClass::Int.to_instance(db), - KnownClass::Float.to_instance(db), - KnownClass::Complex.to_instance(db), - ], - ), + NewTypeBase::Float => KnownUnion::Float.to_type(db), + NewTypeBase::Complex => KnownUnion::Complex.to_type(db), } } }