···48104810 self.problems.error(error);
48114811 }
4812481248134813- let mut missing_arguments = 0;
48144814- let mut ignored_labelled_arguments = vec![];
48154813 // Extract the type of the fun, ensuring it actually is a function
48164816- let (mut arguments_types, return_type) =
48174817- match match_fun_type(fun.type_(), arguments.len(), self.environment) {
48184818- Ok(function) => function,
48194819- Err(error) => {
48204820- let converted_error =
48214821- convert_not_fun_error(error.clone(), fun.location(), location, kind);
48224822- match error {
48234823- // If the function was valid but had the wrong number of arguments passed.
48244824- // Then we keep the error but still want to continue analysing the arguments that were passed.
48254825- MatchFunTypeError::IncorrectArity {
48264826- arguments: arg_types,
48274827- return_type,
48284828- expected,
48294829- given,
48304830- ..
48314831- } => {
48324832- missing_arguments = expected.saturating_sub(given);
48334833- // If the function has labels then arity issues will already
48344834- // be handled by the field map so we can ignore them here.
48354835- if !labelled_arity_error {
48364836- self.problems.error(converted_error);
48374837- (arg_types, return_type)
48384838- } else {
48394839- // Since arity errors with labels cause incorrect
48404840- // ordering, we can't type check the labelled arguments here.
48414841- let first_labelled_arg =
48424842- arguments.iter().position(|arg| arg.label.is_some());
48434843- ignored_labelled_arguments = arguments
48444844- .iter()
48454845- .skip_while(|argument| argument.label.is_none())
48464846- .map(|argument| {
48474847- (
48484848- argument.label.clone(),
48494849- argument.location,
48504850- argument.implicit,
48514851- )
48524852- })
48534853- .collect_vec();
48544854- let arguments_to_keep =
48554855- first_labelled_arg.unwrap_or(arguments.len());
48564856- (
48574857- arg_types.iter().take(arguments_to_keep).cloned().collect(),
48584858- return_type,
48594859- )
48604860- }
48614861- }
48624862- MatchFunTypeError::NotFn { .. } => {
48634863- self.problems.error(converted_error);
48644864- (vec![], self.new_unbound_var())
48654865- }
48664866- }
48674867- }
48684868- };
48144814+ let FunctionTypeMatch {
48154815+ expected_arguments: mut arguments_types,
48164816+ expected_return: return_type,
48174817+ missing_arguments,
48184818+ ignored_labelled_arguments,
48194819+ } = self.fault_tolerant_match_function_type(
48204820+ labelled_arity_error,
48214821+ kind,
48224822+ fun.type_(),
48234823+ fun.location(),
48244824+ location,
48254825+ &arguments,
48264826+ );
4869482748704828 // When typing the function's arguments we don't care if the previous
48714829 // expression panics or not because we want to provide a specialised
···49714929 //
49724930 // So now what we want to do is add back those labelled arguments to
49734931 // make sure the LS can still see that those were explicitly supplied.
49744974- for (label, location, implicit) in ignored_labelled_arguments {
49324932+ for IgnoredLabelledArgument {
49334933+ label,
49344934+ location,
49354935+ implicit,
49364936+ } in ignored_labelled_arguments
49374937+ {
49754938 typed_arguments.push(CallArg {
49764939 label,
49774940 value: TypedExpr::Invalid {
···54545417 | Constant::Invalid { .. } => (),
54555418 }
54565419 }
54205420+54215421+ fn fault_tolerant_match_function_type<A>(
54225422+ &mut self,
54235423+ has_labelled_arity_error: bool,
54245424+ call_kind: CallKind,
54255425+ constructor_type: Arc<Type>,
54265426+ // The span of the called element
54275427+ called_location: SrcSpan,
54285428+ // The full span of the function call
54295429+ full_location: SrcSpan,
54305430+ arguments: &[CallArg<A>],
54315431+ ) -> FunctionTypeMatch {
54325432+ // We start by matching the function type. If there's no error we're good
54335433+ // to go, we can immediately return the inferred types.
54345434+ let result = match_fun_type(constructor_type, arguments.len(), self.environment);
54355435+ let error = match result {
54365436+ Err(error) => error,
54375437+ Ok((expected_arguments, expected_return)) => {
54385438+ return FunctionTypeMatch {
54395439+ expected_arguments,
54405440+ expected_return,
54415441+ missing_arguments: 0,
54425442+ ignored_labelled_arguments: vec![],
54435443+ };
54445444+ }
54455445+ };
54465446+54475447+ let converted_error =
54485448+ convert_not_fun_error(error.clone(), called_location, full_location, call_kind);
54495449+54505450+ match error {
54515451+ // If the error is caused by the called thing not being a function
54525452+ // then there isn't much to do, there's no further expectation on
54535453+ // the function types.
54545454+ MatchFunTypeError::NotFn { .. } => {
54555455+ self.problems.error(converted_error);
54565456+ FunctionTypeMatch {
54575457+ expected_arguments: vec![],
54585458+ expected_return: self.new_unbound_var(),
54595459+ missing_arguments: 0,
54605460+ ignored_labelled_arguments: vec![],
54615461+ }
54625462+ }
54635463+54645464+ // If the function was valid but had the wrong number of arguments
54655465+ // passed that's when we want to try and recover!
54665466+ // We will have to continue analysing the arguments that were
54675467+ // passed.
54685468+ MatchFunTypeError::IncorrectArity {
54695469+ arguments: arguments_types,
54705470+ return_type,
54715471+ expected,
54725472+ given,
54735473+ ..
54745474+ } => {
54755475+ let missing_arguments = expected.saturating_sub(given);
54765476+54775477+ // If the function has labels then arity issues will already
54785478+ // be handled by the field map so we can ignore them here.
54795479+ if !has_labelled_arity_error {
54805480+ self.problems.error(converted_error);
54815481+ return FunctionTypeMatch {
54825482+ expected_arguments: arguments_types,
54835483+ expected_return: return_type,
54845484+ missing_arguments,
54855485+ ignored_labelled_arguments: vec![],
54865486+ };
54875487+ }
54885488+54895489+ // Since arity errors with labels cause incorrect ordering, we
54905490+ // can't type check the labelled arguments here.
54915491+ let first_labelled_arg = arguments.iter().position(|arg| arg.label.is_some());
54925492+ let arguments_to_keep = first_labelled_arg.unwrap_or(arguments.len());
54935493+ let kept_arguments = arguments_types
54945494+ .iter()
54955495+ .take(arguments_to_keep)
54965496+ .cloned()
54975497+ .collect();
54985498+ let ignored_labelled_arguments = arguments
54995499+ .iter()
55005500+ .skip_while(|argument| argument.label.is_none())
55015501+ .map(|argument| IgnoredLabelledArgument {
55025502+ label: argument.label.clone(),
55035503+ location: argument.location(),
55045504+ implicit: argument.implicit,
55055505+ })
55065506+ .collect_vec();
55075507+55085508+ FunctionTypeMatch {
55095509+ expected_arguments: kept_arguments,
55105510+ expected_return: return_type,
55115511+ missing_arguments,
55125512+ ignored_labelled_arguments,
55135513+ }
55145514+ }
55155515+ }
55165516+ }
55175517+}
55185518+55195519+struct FunctionTypeMatch {
55205520+ /// The types the arguments of the function are expected to have.
55215521+ expected_arguments: Vec<Arc<Type>>,
55225522+ /// The return type the function is expected to have.
55235523+ expected_return: Arc<Type>,
55245524+ /// How many arguments are missing from the function call.
55255525+ missing_arguments: usize,
55265526+ /// A list of the labelled arguments that were not provided to the function call.
55275527+ ignored_labelled_arguments: Vec<IgnoredLabelledArgument>,
55285528+}
55295529+55305530+struct IgnoredLabelledArgument {
55315531+ label: Option<EcoString>,
55325532+ location: SrcSpan,
55335533+ implicit: Option<ImplicitCallArgOrigin>,
54575534}
5458553554595536/// Given a constants, this will change its type into the given one, turning