in starlark/src/syntax/validate.rs [178:228]
fn check_parameters(parameters: &[AstParameter], codemap: &CodeMap) -> anyhow::Result<()> {
let err = |span, msg| Err(Diagnostic::new(msg, span, codemap));
// you can't repeat argument names
let mut argset = HashSet::new();
// You can't have more than one *args/*, **kwargs
// **kwargs must be last
// You can't have a required `x` after an optional `y=1`
let mut seen_args = false;
let mut seen_kwargs = false;
let mut seen_optional = false;
for arg in parameters.iter() {
match &arg.node {
Parameter::Normal(n, ..) => {
if seen_kwargs || seen_optional {
return err(arg.span, ArgumentUseOrderError::PositionalThenNonPositional);
}
test_param_name(&mut argset, n, arg, codemap)?;
}
Parameter::WithDefaultValue(n, ..) => {
if seen_kwargs {
return err(arg.span, ArgumentUseOrderError::DefaultParameterAfterStars);
}
seen_optional = true;
test_param_name(&mut argset, n, arg, codemap)?;
}
Parameter::NoArgs => {
if seen_args || seen_kwargs {
return err(arg.span, ArgumentUseOrderError::ArgsParameterAfterStars);
}
seen_args = true;
}
Parameter::Args(n, ..) => {
if seen_args || seen_kwargs {
return err(arg.span, ArgumentUseOrderError::ArgsParameterAfterStars);
}
seen_args = true;
test_param_name(&mut argset, n, arg, codemap)?;
}
Parameter::KwArgs(n, ..) => {
if seen_kwargs {
return err(arg.span, ArgumentUseOrderError::MultipleKwargs);
}
seen_kwargs = true;
test_param_name(&mut argset, n, arg, codemap)?;
}
}
}
Ok(())
}