@@ -4,7 +4,6 @@ use ruff_diagnostics::{Edit, Fix};
44use rustc_hash:: FxHashMap ;
55
66use std:: borrow:: Cow ;
7- use std:: cell:: RefCell ;
87use std:: time:: Duration ;
98
109use bitflags:: bitflags;
@@ -51,7 +50,7 @@ use crate::types::bound_super::BoundSuperType;
5150use crate :: types:: call:: { Binding , Bindings , CallArguments , CallableBinding } ;
5251pub ( crate ) use crate :: types:: callable:: { CallableType , CallableTypes } ;
5352pub ( crate ) use crate :: types:: class_base:: ClassBase ;
54- use crate :: types:: constraints:: ConstraintSetBuilder ;
53+ use crate :: types:: constraints:: { ConstraintSetBuilder , Solutions } ;
5554use crate :: types:: context:: { LintDiagnosticGuard , LintDiagnosticGuardBuilder } ;
5655use crate :: types:: diagnostic:: { INVALID_AWAIT , INVALID_TYPE_FORM } ;
5756pub use crate :: types:: display:: { DisplaySettings , TypeDetail , TypeDisplayDetails } ;
@@ -60,10 +59,10 @@ use crate::types::function::{
6059 DataclassTransformerFlags , DataclassTransformerParams , FunctionDecorators , FunctionSpans ,
6160 FunctionType , KnownFunction ,
6261} ;
62+ pub ( crate ) use crate :: types:: generics:: GenericContext ;
6363use crate :: types:: generics:: {
6464 ApplySpecialization , InferableTypeVars , Specialization , bind_typevar,
6565} ;
66- pub ( crate ) use crate :: types:: generics:: { GenericContext , SpecializationBuilder } ;
6766use crate :: types:: infer:: InferenceFlags ;
6867use crate :: types:: known_instance:: { InternedConstraintSet , InternedType , UnionTypeInstance } ;
6968pub use crate :: types:: method:: { BoundMethodType , KnownBoundMethodType , WrapperDescriptorKind } ;
@@ -1902,17 +1901,38 @@ impl<'db> Type<'db> {
19021901 let generic_context = specialization. generic_context ( db) ;
19031902
19041903 // Collect the type mappings used to narrow the type context.
1905- let tcx_mappings = {
1906- let mut builder =
1907- SpecializationBuilder :: new ( db, generic_context. inferable_typevars ( db) ) ;
1908-
1909- if let Some ( tcx) = tcx. annotation {
1904+ //
1905+ // We use a forward CSA check (`alias_instance ≤ tcx`) to infer what each typevar
1906+ // in the identity specialization maps to in the type context. For example, if
1907+ // `tcx = list[int]` and `alias_instance = list[T]`, the CSA produces `T = int`.
1908+ let tcx_mappings: FxHashMap < _ , _ > = tcx
1909+ . annotation
1910+ . and_then ( |tcx| {
19101911 let alias_instance = Type :: instance ( db, class_literal. identity_specialization ( db) ) ;
1911- let _ = builder. infer_reverse ( constraints, tcx, alias_instance) ;
1912- }
1913-
1914- builder. into_type_mappings ( )
1915- } ;
1912+ let set = alias_instance. when_constraint_set_assignable_to ( db, tcx, constraints) ;
1913+ match set. solutions ( db, constraints) {
1914+ Solutions :: Constrained ( solutions) => {
1915+ let mut mappings = FxHashMap :: default ( ) ;
1916+ for solution in solutions. iter ( ) {
1917+ for binding in solution {
1918+ mappings
1919+ . entry ( binding. bound_typevar . identity ( db) )
1920+ . and_modify ( |existing| {
1921+ * existing = UnionType :: from_two_elements (
1922+ db,
1923+ * existing,
1924+ binding. solution ,
1925+ ) ;
1926+ } )
1927+ . or_insert ( binding. solution ) ;
1928+ }
1929+ }
1930+ Some ( mappings)
1931+ }
1932+ _ => None ,
1933+ }
1934+ } )
1935+ . unwrap_or_default ( ) ;
19161936
19171937 for ( type_var, ty) in generic_context. variables ( db) . zip ( specialization. types ( db) ) {
19181938 let variance = type_var. variance_with_polarity ( db, polarity) ;
@@ -5501,12 +5521,6 @@ impl<'db> Type<'db> {
55015521 match type_mapping {
55025522 TypeMapping :: EagerExpansion => unreachable ! ( "handled above" ) ,
55035523
5504- // For UniqueSpecialization, get raw value type, apply specialization, then apply mapping.
5505- TypeMapping :: UniqueSpecialization { .. } => {
5506- let value_type = alias. raw_value_type ( db) ;
5507- alias. apply_function_specialization ( db, value_type) . apply_type_mapping_impl ( db, type_mapping, tcx, visitor)
5508- }
5509-
55105524 _ => {
55115525 let value_type = alias. raw_value_type ( db) . apply_type_mapping_impl ( db, type_mapping, tcx, visitor) ;
55125526 alias. apply_function_specialization ( db, value_type) . apply_type_mapping_impl ( db, type_mapping, tcx, visitor)
@@ -5531,7 +5545,6 @@ impl<'db> Type<'db> {
55315545 Type :: LiteralValue ( _) => match type_mapping {
55325546 TypeMapping :: ApplySpecialization ( _) |
55335547 TypeMapping :: ApplySpecializationWithMaterialization { .. } |
5534- TypeMapping :: UniqueSpecialization { .. } |
55355548 TypeMapping :: BindLegacyTypevars ( _) |
55365549 TypeMapping :: BindSelf { .. } |
55375550 TypeMapping :: ReplaceSelf { .. } |
@@ -5547,7 +5560,6 @@ impl<'db> Type<'db> {
55475560 Type :: Dynamic ( _) => match type_mapping {
55485561 TypeMapping :: ApplySpecialization ( _) |
55495562 TypeMapping :: ApplySpecializationWithMaterialization { .. } |
5550- TypeMapping :: UniqueSpecialization { .. } |
55515563 TypeMapping :: BindLegacyTypevars ( _) |
55525564 TypeMapping :: BindSelf ( ..) |
55535565 TypeMapping :: ReplaceSelf { .. } |
@@ -6328,11 +6340,6 @@ pub enum TypeMapping<'a, 'db> {
63286340 specialization : ApplySpecialization < ' a , ' db > ,
63296341 materialization_kind : MaterializationKind ,
63306342 } ,
6331- /// Resets any specializations to contain unique synthetic type variables.
6332- UniqueSpecialization {
6333- // A list of synthetic type variables, and the types they replaced.
6334- specialization : RefCell < Vec < ( BoundTypeVarInstance < ' db > , Type < ' db > ) > > ,
6335- } ,
63366343 /// Replaces any literal types with their corresponding promoted type form (e.g. `Literal["string"]`
63376344 /// to `str`, or `def _() -> int` to `Callable[[], int]`).
63386345 Promote ( PromotionMode , PromotionKind ) ,
@@ -6384,8 +6391,7 @@ impl<'db> TypeMapping<'_, 'db> {
63846391 } ) ,
63856392 )
63866393 }
6387- TypeMapping :: UniqueSpecialization { .. }
6388- | TypeMapping :: Promote ( ..)
6394+ TypeMapping :: Promote ( ..)
63896395 | TypeMapping :: BindLegacyTypevars ( _)
63906396 | TypeMapping :: Materialize ( _)
63916397 | TypeMapping :: ReplaceParameterDefaults
@@ -6430,7 +6436,6 @@ impl<'db> TypeMapping<'_, 'db> {
64306436 } ,
64316437 TypeMapping :: Promote ( mode, kind) => TypeMapping :: Promote ( mode. flip ( ) , * kind) ,
64326438 TypeMapping :: ApplySpecialization ( _)
6433- | TypeMapping :: UniqueSpecialization { .. }
64346439 | TypeMapping :: BindLegacyTypevars ( _)
64356440 | TypeMapping :: BindSelf ( ..)
64366441 | TypeMapping :: ReplaceSelf { .. }
0 commit comments