Skip to content

Commit

Permalink
[red-knot] Reduce Name clones in call signature checking (#15335)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood authored Jan 8, 2025
1 parent 2ca31e4 commit 88d0720
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 25 deletions.
4 changes: 2 additions & 2 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,7 @@ impl<'db> Type<'db> {

/// Return the outcome of calling an object of this type.
#[must_use]
fn call(self, db: &'db dyn Db, arguments: &CallArguments<'db>) -> CallOutcome<'db> {
fn call(self, db: &'db dyn Db, arguments: &CallArguments<'_, 'db>) -> CallOutcome<'db> {
match self {
Type::FunctionLiteral(function_type) => {
let mut binding = bind_call(db, arguments, function_type.signature(db), Some(self));
Expand Down Expand Up @@ -1995,7 +1995,7 @@ impl<'db> Type<'db> {
self,
db: &'db dyn Db,
name: &str,
arguments: &CallArguments<'db>,
arguments: &CallArguments<'_, 'db>,
) -> CallDunderResult<'db> {
match self.to_meta_type(db).member(db, name) {
Symbol::Type(callable_ty, Boundness::Bound) => {
Expand Down
23 changes: 11 additions & 12 deletions crates/red_knot_python_semantic/src/types/call/arguments.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use super::Type;
use ruff_python_ast::name::Name;

/// Typed arguments for a single call, in source order.
#[derive(Clone, Debug, Default)]
pub(crate) struct CallArguments<'db>(Vec<Argument<'db>>);
pub(crate) struct CallArguments<'a, 'db>(Vec<Argument<'a, 'db>>);

impl<'db> CallArguments<'db> {
impl<'a, 'db> CallArguments<'a, 'db> {
/// Create a [`CallArguments`] from an iterator over non-variadic positional argument types.
pub(crate) fn positional(positional_tys: impl IntoIterator<Item = Type<'db>>) -> Self {
positional_tys
Expand All @@ -22,7 +21,7 @@ impl<'db> CallArguments<'db> {
Self(arguments)
}

pub(crate) fn iter(&self) -> impl Iterator<Item = &Argument<'db>> {
pub(crate) fn iter(&self) -> impl Iterator<Item = &Argument<'a, 'db>> {
self.0.iter()
}

Expand All @@ -32,34 +31,34 @@ impl<'db> CallArguments<'db> {
}
}

impl<'db, 'a> IntoIterator for &'a CallArguments<'db> {
type Item = &'a Argument<'db>;
type IntoIter = std::slice::Iter<'a, Argument<'db>>;
impl<'db, 'a, 'b> IntoIterator for &'b CallArguments<'a, 'db> {
type Item = &'b Argument<'a, 'db>;
type IntoIter = std::slice::Iter<'b, Argument<'a, 'db>>;

fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}

impl<'db> FromIterator<Argument<'db>> for CallArguments<'db> {
fn from_iter<T: IntoIterator<Item = Argument<'db>>>(iter: T) -> Self {
impl<'a, 'db> FromIterator<Argument<'a, 'db>> for CallArguments<'a, 'db> {
fn from_iter<T: IntoIterator<Item = Argument<'a, 'db>>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}

#[derive(Clone, Debug)]
pub(crate) enum Argument<'db> {
pub(crate) enum Argument<'a, 'db> {
/// A positional argument.
Positional(Type<'db>),
/// A starred positional argument (e.g. `*args`).
Variadic(Type<'db>),
/// A keyword argument (e.g. `a=1`).
Keyword { name: Name, ty: Type<'db> },
Keyword { name: &'a str, ty: Type<'db> },
/// The double-starred keywords argument (e.g. `**kwargs`).
Keywords(Type<'db>),
}

impl<'db> Argument<'db> {
impl<'db> Argument<'_, 'db> {
fn ty(&self) -> Type<'db> {
match self {
Self::Positional(ty) => *ty,
Expand Down
8 changes: 4 additions & 4 deletions crates/red_knot_python_semantic/src/types/call/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use ruff_python_ast as ast;
/// parameters, and any errors resulting from binding the call.
pub(crate) fn bind_call<'db>(
db: &'db dyn Db,
arguments: &CallArguments<'db>,
arguments: &CallArguments<'_, 'db>,
signature: &Signature<'db>,
callable_ty: Option<Type<'db>>,
) -> CallBinding<'db> {
Expand Down Expand Up @@ -45,7 +45,7 @@ pub(crate) fn bind_call<'db>(
.or_else(|| parameters.keyword_variadic())
else {
errors.push(CallBindingError::UnknownArgument {
argument_name: name.clone(),
argument_name: ast::name::Name::new(name),
argument_index,
});
continue;
Expand Down Expand Up @@ -168,7 +168,7 @@ impl<'db> CallBinding<'db> {
}
}

fn callable_name(&self, db: &'db dyn Db) -> Option<&ast::name::Name> {
fn callable_name(&self, db: &'db dyn Db) -> Option<&str> {
match self.callable_ty {
Some(Type::FunctionLiteral(function)) => Some(function.name(db)),
Some(Type::ClassLiteral(class_type)) => Some(class_type.class.name(db)),
Expand Down Expand Up @@ -272,7 +272,7 @@ impl<'db> CallBindingError<'db> {
&self,
context: &InferContext<'db>,
node: ast::AnyNodeRef,
callable_name: Option<&ast::name::Name>,
callable_name: Option<&str>,
) {
match self {
Self::InvalidArgumentType {
Expand Down
11 changes: 4 additions & 7 deletions crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2523,11 +2523,11 @@ impl<'db> TypeInferenceBuilder<'db> {
self.infer_expression(expression)
}

fn infer_arguments(
fn infer_arguments<'a>(
&mut self,
arguments: &ast::Arguments,
arguments: &'a ast::Arguments,
infer_as_type_expressions: bool,
) -> CallArguments<'db> {
) -> CallArguments<'a, 'db> {
let infer_argument_type = if infer_as_type_expressions {
Self::infer_type_expression
} else {
Expand Down Expand Up @@ -2558,10 +2558,7 @@ impl<'db> TypeInferenceBuilder<'db> {
}) => {
let ty = infer_argument_type(self, value);
if let Some(arg) = arg {
Argument::Keyword {
name: arg.id.clone(),
ty,
}
Argument::Keyword { name: &arg.id, ty }
} else {
// TODO diagnostic if not last
Argument::Keywords(ty)
Expand Down

0 comments on commit 88d0720

Please sign in to comment.