@@ -2590,71 +2590,6 @@ impl<'db> CallableBinding<'db> {
25902590 }
25912591 }
25922592
2593- let mut union_argument_type_builders = std:: iter:: repeat_with ( || UnionBuilder :: new ( db) )
2594- . take ( max_parameter_count)
2595- . collect :: < Vec < _ > > ( ) ;
2596-
2597- // The following loop is trying to construct a tuple of argument types that correspond to
2598- // the participating parameter indexes. Considering the following example:
2599- //
2600- // ```python
2601- // @overload
2602- // def f(x: Literal[1], y: Literal[2]) -> tuple[int, int]: ...
2603- // @overload
2604- // def f(*args: Any) -> tuple[Any, ...]: ...
2605- //
2606- // f(1, 2)
2607- // ```
2608- //
2609- // Here, only the first parameter participates in the filtering process because only one
2610- // overload has the second parameter. So, while going through the argument types, the
2611- // second argument needs to be skipped but for the second overload both arguments map to
2612- // the first parameter and that parameter is considered for the filtering process. This
2613- // flag is to handle that special case of many-to-one mapping from arguments to parameters.
2614- let mut variadic_parameter_handled = false ;
2615-
2616- for ( argument_index, argument_types) in arguments. types ( ) . iter ( ) . enumerate ( ) {
2617- if variadic_parameter_handled {
2618- continue ;
2619- }
2620- for overload_index in matching_overload_indexes {
2621- let overload = & self . overloads [ * overload_index] ;
2622- for ( parameter_index, variadic_argument_type) in
2623- overload. argument_matches [ argument_index] . iter ( )
2624- {
2625- let parameter = & overload. signature . parameters ( ) [ parameter_index] ;
2626- if parameter. is_variadic ( ) {
2627- variadic_parameter_handled = true ;
2628- }
2629- if !participating_parameter_indexes. contains ( & parameter_index) {
2630- continue ;
2631- }
2632- let argument_type =
2633- argument_types. get_for_declared_type ( parameter. annotated_type ( ) ) ;
2634- union_argument_type_builders[ parameter_index] . add_in_place (
2635- variadic_argument_type
2636- . unwrap_or ( argument_type)
2637- . top_materialization ( db) ,
2638- ) ;
2639- }
2640- }
2641- }
2642-
2643- // These only contain the top materialized argument types for the corresponding
2644- // participating parameter indexes.
2645- let top_materialized_argument_type = Type :: heterogeneous_tuple (
2646- db,
2647- union_argument_type_builders
2648- . into_iter ( )
2649- . filter_map ( |builder| {
2650- if builder. is_empty ( ) {
2651- None
2652- } else {
2653- Some ( builder. build ( ) )
2654- }
2655- } ) ,
2656- ) ;
2657-
26582593 // A flag to indicate whether we've found the overload that makes the remaining overloads
26592594 // unmatched for the given argument types.
26602595 let mut filter_remaining_overloads = false ;
@@ -2665,6 +2600,73 @@ impl<'db> CallableBinding<'db> {
26652600 continue ;
26662601 }
26672602
2603+ let mut union_argument_type_builders = std:: iter:: repeat_with ( || UnionBuilder :: new ( db) )
2604+ . take ( max_parameter_count)
2605+ . collect :: < Vec < _ > > ( ) ;
2606+
2607+ // The following loop is trying to construct a tuple of argument types that correspond to
2608+ // the participating parameter indexes. Considering the following example:
2609+ //
2610+ // ```python
2611+ // @overload
2612+ // def f(x: Literal[1], y: Literal[2]) -> tuple[int, int]: ...
2613+ // @overload
2614+ // def f(*args: Any) -> tuple[Any, ...]: ...
2615+ //
2616+ // f(1, 2)
2617+ // ```
2618+ //
2619+ // Here, only the first parameter participates in the filtering process because only one
2620+ // overload has the second parameter. So, while going through the argument types, the
2621+ // second argument needs to be skipped but for the second overload both arguments map to
2622+ // the first parameter and that parameter is considered for the filtering process. This
2623+ // flag is to handle that special case of many-to-one mapping from arguments to parameters.
2624+ let mut variadic_parameter_handled = false ;
2625+
2626+ for ( argument_index, argument_types) in arguments. types ( ) . iter ( ) . enumerate ( ) {
2627+ if variadic_parameter_handled {
2628+ continue ;
2629+ }
2630+ for overload_index in matching_overload_indexes {
2631+ let overload = & self . overloads [ * overload_index] ;
2632+ for ( parameter_index, variadic_argument_type) in
2633+ overload. argument_matches [ argument_index] . iter ( )
2634+ {
2635+ let parameter = & overload. signature . parameters ( ) [ parameter_index] ;
2636+ if parameter. is_variadic ( ) {
2637+ variadic_parameter_handled = true ;
2638+ }
2639+ if !participating_parameter_indexes. contains ( & parameter_index) {
2640+ continue ;
2641+ }
2642+ let current_parameter =
2643+ & self . overloads [ * current_index] . signature . parameters ( ) [ parameter_index] ;
2644+ let argument_type = argument_types
2645+ . get_for_declared_type ( current_parameter. annotated_type ( ) ) ;
2646+ union_argument_type_builders[ parameter_index] . add_in_place (
2647+ variadic_argument_type
2648+ . unwrap_or ( argument_type)
2649+ . top_materialization ( db) ,
2650+ ) ;
2651+ }
2652+ }
2653+ }
2654+
2655+ // These only contain the top materialized argument types for the corresponding
2656+ // participating parameter indexes.
2657+ let top_materialized_argument_type = Type :: heterogeneous_tuple (
2658+ db,
2659+ union_argument_type_builders
2660+ . into_iter ( )
2661+ . filter_map ( |builder| {
2662+ if builder. is_empty ( ) {
2663+ None
2664+ } else {
2665+ Some ( builder. build ( ) )
2666+ }
2667+ } ) ,
2668+ ) ;
2669+
26682670 let mut union_parameter_types = std:: iter:: repeat_with ( || UnionBuilder :: new ( db) )
26692671 . take ( max_parameter_count)
26702672 . collect :: < Vec < _ > > ( ) ;
0 commit comments