From 88d07202c11677a667901f38f87759ac3af72b3f Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 8 Jan 2025 18:29:35 +0000 Subject: [PATCH] [red-knot] Reduce `Name` clones in call signature checking (#15335) --- crates/red_knot_python_semantic/src/types.rs | 4 ++-- .../src/types/call/arguments.rs | 23 +++++++++---------- .../src/types/call/bind.rs | 8 +++---- .../src/types/infer.rs | 11 ++++----- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types.rs b/crates/red_knot_python_semantic/src/types.rs index 84b1e2ef025cbd..7f01d24e7a9e73 100644 --- a/crates/red_knot_python_semantic/src/types.rs +++ b/crates/red_knot_python_semantic/src/types.rs @@ -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)); @@ -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) => { diff --git a/crates/red_knot_python_semantic/src/types/call/arguments.rs b/crates/red_knot_python_semantic/src/types/call/arguments.rs index 6a247a0b65e42f..b0067e41a0154f 100644 --- a/crates/red_knot_python_semantic/src/types/call/arguments.rs +++ b/crates/red_knot_python_semantic/src/types/call/arguments.rs @@ -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>); +pub(crate) struct CallArguments<'a, 'db>(Vec>); -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>) -> Self { positional_tys @@ -22,7 +21,7 @@ impl<'db> CallArguments<'db> { Self(arguments) } - pub(crate) fn iter(&self) -> impl Iterator> { + pub(crate) fn iter(&self) -> impl Iterator> { self.0.iter() } @@ -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> for CallArguments<'db> { - fn from_iter>>(iter: T) -> Self { +impl<'a, 'db> FromIterator> for CallArguments<'a, 'db> { + fn from_iter>>(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, diff --git a/crates/red_knot_python_semantic/src/types/call/bind.rs b/crates/red_knot_python_semantic/src/types/call/bind.rs index 7e699d1f5d094c..ebd15be09a42d7 100644 --- a/crates/red_knot_python_semantic/src/types/call/bind.rs +++ b/crates/red_knot_python_semantic/src/types/call/bind.rs @@ -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>, ) -> CallBinding<'db> { @@ -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; @@ -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)), @@ -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 { diff --git a/crates/red_knot_python_semantic/src/types/infer.rs b/crates/red_knot_python_semantic/src/types/infer.rs index e17041e84f3e9a..2338c0325cad3d 100644 --- a/crates/red_knot_python_semantic/src/types/infer.rs +++ b/crates/red_knot_python_semantic/src/types/infer.rs @@ -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 { @@ -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)