Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/types/call/bind.rs (Rust)

Code before:
            {
                let parameter = &parameters[parameter_index];
                let Some(expected_type) = parameter.annotated_type() else {
                    continue;
                };

                if let Err(error) = builder.infer(
                    expected_type,
                    variadic_argument_type.unwrap_or(argument_type),
                ) {
                    self.errors.push(BindingError::SpecializationError {
                        error,
                        argument_index: adjusted_argument_index,
                    });
                }
            }
        }

        // Build the specialization first without inferring the type context.
        let isolated_specialization = builder.build(generic_context, *self.call_expression_tcx);
        let isolated_return_ty = self
            .return_ty
            .apply_specialization(self.db, isolated_specialization);

        let mut try_infer_tcx = || {
            // For generic constructors, we use the type context to infer the specialization of the class
            // instance instead of the method's return type.
            let (inference_context, generic_constructor) = if let Type::BoundMethod(method) =
                self.callable_type
                && let Type::NominalInstance(instance) = method.self_instance(self.db)
                && method.function(self.db).name(self.db) == "__init__"
            {
                let class_ty = instance
                    .class_literal(self.db)
                    .identity_specialization(self.db);

                (Type::instance(self.db, class_ty), true)
            } else {
                (self.signature.return_ty?, false)
            };

            let call_expression_tcx = self.call_expression_tcx.annotation?;

            // A type variable is not a useful type-context for expression inference, and applying it
            // to the return type can lead to confusing unions in nested generic calls.
            if call_expression_tcx.is_type_var() {
                return None;
            }

            // If the return type is already assignable to the annotated type, we can ignore the
            // type context and prefer the narrower inferred type.

Review comment (suggestion):
I was a bit confused here at first, because "generic constructor" sounded to me like the function itself was generic (which is probably illegal? or doesn't make sense because `__init__` always returns `None`, and so every generic parameter could be annotated with its upper bound). Maybe:
```suggestion
            // For constructors of generic classes, we use the type context to infer the specialization of the class
```

Code after:
                    db,
                    Name::new_static("__getitem__"),
                    MemberLookupPolicy::NO_INSTANCE_FALLBACK,
                )
                .place
            }) {
                Some(Place::Defined(keys_method, _, Definedness::AlwaysDefined)) => keys_method
                    .try_call(db, &CallArguments::positional([Type::unknown()]))
                    .ok()
                    .map_or_else(Type::unknown, |bindings| bindings.return_type(db)),
                _ => Type::unknown(),
            };

            for (parameter_index, parameter) in self.parameters.iter().enumerate() {
                if self.parameter_info[parameter_index].matched && !parameter.is_keyword_variadic()
                {
                    continue;
                }
                if matches!(
                    parameter.kind(),
                    ParameterKind::PositionalOnly { .. } | ParameterKind::Variadic { .. }
                ) {
                    continue;
                }
                self.assign_argument(
                    argument_index,
                    Argument::Keywords,
                    Some(value_type),
                    parameter_index,
                    parameter,
                    false,
                    true,
                );
            }
        }
    }

    fn finish(self) -> Box<[MatchedArgument<'db>]> {
        if let Some(first_excess_argument_index) = self.first_excess_positional {
            self.errors.push(BindingError::TooManyPositionalArguments {
                first_excess_argument_index: self.get_argument_index(first_excess_argument_index),
                expected_positional_count: self.parameters.positional().count(),
                provided_positional_count: self.next_positional,
            });
        }

        let mut missing = vec![];
        for (
            index,
            ParameterInfo {
                matched,