[ty] Coalesce allocations for parameter info in ArgumentMatcher (#20586)

<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

Follow up on #20495. The improvement suggested by @AlexWaygood cannot be
applied as-is since the `argument_matches` vector is indexed by argument
number, while the two boolean vectors are indexed by parameter number.
Still coalescing the latter two saves one allocation.
This commit is contained in:
Francesco Giacometti 2025-09-26 02:56:59 +02:00 committed by GitHub
parent 589a674a8d
commit e66a872c14
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2043,14 +2043,19 @@ impl ArgumentForms {
} }
} }
#[derive(Default, Clone, Copy)]
struct ParameterInfo {
matched: bool,
suppress_missing_error: bool,
}
struct ArgumentMatcher<'a, 'db> { struct ArgumentMatcher<'a, 'db> {
parameters: &'a Parameters<'db>, parameters: &'a Parameters<'db>,
argument_forms: &'a mut ArgumentForms, argument_forms: &'a mut ArgumentForms,
errors: &'a mut Vec<BindingError<'db>>, errors: &'a mut Vec<BindingError<'db>>,
argument_matches: Vec<MatchedArgument<'db>>, argument_matches: Vec<MatchedArgument<'db>>,
parameter_matched: Vec<bool>, parameter_info: Vec<ParameterInfo>,
suppress_missing_error: Vec<bool>,
next_positional: usize, next_positional: usize,
first_excess_positional: Option<usize>, first_excess_positional: Option<usize>,
num_synthetic_args: usize, num_synthetic_args: usize,
@ -2069,8 +2074,7 @@ impl<'a, 'db> ArgumentMatcher<'a, 'db> {
argument_forms, argument_forms,
errors, errors,
argument_matches: vec![MatchedArgument::default(); arguments.len()], argument_matches: vec![MatchedArgument::default(); arguments.len()],
parameter_matched: vec![false; parameters.len()], parameter_info: vec![ParameterInfo::default(); parameters.len()],
suppress_missing_error: vec![false; parameters.len()],
next_positional: 0, next_positional: 0,
first_excess_positional: None, first_excess_positional: None,
num_synthetic_args: 0, num_synthetic_args: 0,
@ -2112,7 +2116,7 @@ impl<'a, 'db> ArgumentMatcher<'a, 'db> {
} }
} }
} }
if self.parameter_matched[parameter_index] { if self.parameter_info[parameter_index].matched {
if !parameter.is_variadic() && !parameter.is_keyword_variadic() { if !parameter.is_variadic() && !parameter.is_keyword_variadic() {
self.errors.push(BindingError::ParameterAlreadyAssigned { self.errors.push(BindingError::ParameterAlreadyAssigned {
argument_index: self.get_argument_index(argument_index), argument_index: self.get_argument_index(argument_index),
@ -2133,7 +2137,7 @@ impl<'a, 'db> ArgumentMatcher<'a, 'db> {
matched_argument.parameters.push(parameter_index); matched_argument.parameters.push(parameter_index);
matched_argument.types.push(argument_type); matched_argument.types.push(argument_type);
matched_argument.matched = true; matched_argument.matched = true;
self.parameter_matched[parameter_index] = true; self.parameter_info[parameter_index].matched = true;
} }
fn match_positional( fn match_positional(
@ -2189,7 +2193,7 @@ impl<'a, 'db> ArgumentMatcher<'a, 'db> {
argument_index: self.get_argument_index(argument_index), argument_index: self.get_argument_index(argument_index),
parameter: ParameterContext::new(parameter, parameter_index, true), parameter: ParameterContext::new(parameter, parameter_index, true),
}); });
self.suppress_missing_error[parameter_index] = true; self.parameter_info[parameter_index].suppress_missing_error = true;
} else { } else {
self.errors.push(BindingError::UnknownArgument { self.errors.push(BindingError::UnknownArgument {
argument_name: ast::name::Name::new(name), argument_name: ast::name::Name::new(name),
@ -2316,7 +2320,8 @@ impl<'a, 'db> ArgumentMatcher<'a, 'db> {
}; };
for (parameter_index, parameter) in self.parameters.iter().enumerate() { for (parameter_index, parameter) in self.parameters.iter().enumerate() {
if self.parameter_matched[parameter_index] && !parameter.is_keyword_variadic() { if self.parameter_info[parameter_index].matched && !parameter.is_keyword_variadic()
{
continue; continue;
} }
if matches!( if matches!(
@ -2348,9 +2353,16 @@ impl<'a, 'db> ArgumentMatcher<'a, 'db> {
} }
let mut missing = vec![]; let mut missing = vec![];
for (index, matched) in self.parameter_matched.iter().copied().enumerate() { for (
index,
ParameterInfo {
matched,
suppress_missing_error,
},
) in self.parameter_info.iter().copied().enumerate()
{
if !matched { if !matched {
if self.suppress_missing_error[index] { if suppress_missing_error {
continue; continue;
} }
let param = &self.parameters[index]; let param = &self.parameters[index];