···44234423 ),
44244424 };
4425442544264426- // If there's an error reordering the fields, or there's labelled
44274427- // arguments with no field map, then we return an invalid expression.
44264426+ // If there's an error with the constructor being passed the wrong
44274427+ // number of arguments we keep track of it, but don't immediately return
44284428+ // an invalid node!
44294429+ // We still want to analyse the passed arguments.
44304430+ let mut labelled_arity_error = false;
44284431 if let Err(error) = result {
44324432+ if let Error::IncorrectArity { .. } = error {
44334433+ labelled_arity_error = true;
44344434+ }
44294435 self.problems.error(error);
44304430- return self.new_invalid_constant(location);
44314436 }
4432443744334433- let (mut arguments_types, return_type) =
44344434- match match_fun_type(constructor.type_.clone(), arguments.len(), self.environment) {
44354435- Ok((arguments_types, return_type)) => (arguments_types, return_type),
44364436- Err(error) => {
44374437- self.problems.error(convert_not_fun_error(
44384438- error,
44394439- module.map_or(location, |(_, module_location)| {
44404440- module_location.merge(&location)
44414441- }),
44424442- location,
44434443- CallKind::Function,
44444444- ));
44454445- return self.new_invalid_constant(location);
44464446- }
44474447- };
44384438+ let called_location = module.as_ref().map_or(location, |(_, module_location)| {
44394439+ module_location.merge(&location)
44404440+ });
44414441+44424442+ let FunctionTypeMatch {
44434443+ mut expected_arguments,
44444444+ expected_return,
44454445+ missing_arguments: _,
44464446+ ignored_labelled_arguments,
44474447+ } = self.fault_tolerant_match_function_type(
44484448+ labelled_arity_error,
44494449+ CallKind::Function,
44504450+ constructor.type_.clone(),
44514451+ called_location,
44524452+ location,
44534453+ &arguments,
44544454+ );
4448445544494449- let arguments = arguments_types
44564456+ let mut typed_arguments = expected_arguments
44504457 .iter_mut()
44514458 .zip(arguments)
44524459 .map(|(type_, argument): (&mut Arc<Type>, _)| {
···44734480 })
44744481 .collect_vec();
4475448244834483+ // Now if we had supplied less arguments than required and some of those
44844484+ // were labelled, in the previous step we would have got rid of those
44854485+ // _before_ typing.
44864486+ // That is because we can only reliably type positional arguments in
44874487+ // case of mismatched arity, as labelled arguments cannot be reordered.
44884488+ //
44894489+ // So now what we want to do is add back those labelled arguments to
44904490+ // make sure the LS can still see that those were explicitly supplied.
44914491+ for IgnoredLabelledArgument {
44924492+ label,
44934493+ location,
44944494+ implicit,
44954495+ } in ignored_labelled_arguments
44964496+ {
44974497+ typed_arguments.push(CallArg {
44984498+ label,
44994499+ value: TypedConstant::Invalid {
45004500+ location,
45014501+ type_: self.new_unbound_var(),
45024502+ extra_information: None,
45034503+ },
45044504+ implicit,
45054505+ location,
45064506+ })
45074507+ }
45084508+44764509 Constant::Record {
44774510 module,
44784511 location,
44794512 name,
44804480- arguments,
44814481- type_: return_type,
45134513+ arguments: typed_arguments,
45144514+ type_: expected_return,
44824515 field_map: match field_map {
44834516 Some(field_map) => Inferred::Known(field_map),
44844517 None => Inferred::Unknown,
···55165549 }
55175550}
5518555155525552+#[derive(Debug)]
55195553struct FunctionTypeMatch {
55205554 /// The types the arguments of the function are expected to have.
55215555 expected_arguments: Vec<Arc<Type>>,
···55275561 ignored_labelled_arguments: Vec<IgnoredLabelledArgument>,
55285562}
5529556355645564+#[derive(Debug)]
55305565struct IgnoredLabelledArgument {
55315566 label: Option<EcoString>,
55325567 location: SrcSpan,