⭐️ A friendly language for building type-safe, scalable systems!

Better context for incorrect arity message

Now it can tell the difference when a pattern has the wrong arity and
refer to it as a "pattern" instead of a "call".

authored by giacomocavalieri.me and committed by Louis Pilfold b41ca775 fc0a3dca

Changed files
+47 -9
compiler-core
+8 -3
compiler-core/src/error.rs
··· 5 5 use crate::strings::{to_snake_case, to_upper_camel_case}; 6 6 use crate::type_::collapse_links; 7 7 use crate::type_::error::{ 8 - InvalidImportKind, MissingAnnotation, ModuleValueUsageContext, Named, UnknownField, 9 - UnknownTypeHint, UnsafeRecordUpdateReason, 8 + IncorrectArityContext, InvalidImportKind, MissingAnnotation, ModuleValueUsageContext, Named, 9 + UnknownField, UnknownTypeHint, UnsafeRecordUpdateReason, 10 10 }; 11 11 use crate::type_::printer::{Names, Printer}; 12 12 use crate::type_::{FieldAccessUsage, error::PatternMatchKind}; ··· 2208 2208 TypeError::IncorrectArity { 2209 2209 labels, 2210 2210 location, 2211 + context, 2211 2212 expected, 2212 2213 given, 2213 2214 } => { 2214 2215 let text = if labels.is_empty() { 2215 2216 "".into() 2216 2217 } else { 2218 + let subject = match context { 2219 + IncorrectArityContext::Pattern => "pattern", 2220 + IncorrectArityContext::Function => "call", 2221 + }; 2217 2222 let labels = labels 2218 2223 .iter() 2219 2224 .map(|p| format!(" - {p}")) 2220 2225 .sorted() 2221 2226 .join("\n"); 2222 - format!("This call accepts these additional labelled arguments:\n\n{labels}",) 2227 + format!("This {subject} accepts these additional labelled arguments:\n\n{labels}",) 2223 2228 }; 2224 2229 let expected = match expected { 2225 2230 0 => "no arguments".into(),
+8
compiler-core/src/type_/error.rs
··· 224 224 IncorrectArity { 225 225 location: SrcSpan, 226 226 expected: usize, 227 + context: IncorrectArityContext, 227 228 given: usize, 228 229 labels: Vec<EcoString>, 229 230 }, ··· 671 672 List, 672 673 Tuple, 673 674 Record, 675 + } 676 + 677 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 678 + pub enum IncorrectArityContext { 679 + Pattern, 680 + Function, 674 681 } 675 682 676 683 #[derive(Debug, Clone, Copy, PartialEq, Eq)] ··· 1431 1438 ) => Error::IncorrectArity { 1432 1439 labels: vec![], 1433 1440 location: call_location, 1441 + context: IncorrectArityContext::Function, 1434 1442 expected, 1435 1443 given, 1436 1444 },
+8 -2
compiler-core/src/type_/expression.rs
··· 3659 3659 .map_err(|e| convert_get_value_constructor_error(e, location, None))? 3660 3660 { 3661 3661 // The fun has a field map so labelled arguments may be present and need to be reordered. 3662 - Some(field_map) => field_map.reorder(&mut args, location)?, 3662 + Some(field_map) => { 3663 + field_map.reorder(&mut args, location, IncorrectArityContext::Function)? 3664 + } 3663 3665 3664 3666 // The fun has no field map and so we error if arguments have been labelled 3665 3667 None => assert_no_labelled_arguments(&args)?, ··· 3975 3977 match field_map { 3976 3978 // The fun has a field map so labelled arguments may be 3977 3979 // present and need to be reordered. 3978 - Some(field_map) => field_map.reorder(&mut args, location), 3980 + Some(field_map) => { 3981 + field_map.reorder(&mut args, location, IncorrectArityContext::Function) 3982 + } 3979 3983 3980 3984 // The fun has no field map and so we error if arguments 3981 3985 // have been labelled. ··· 3995 3999 Error::IncorrectArity { 3996 4000 expected, 3997 4001 given, 4002 + context, 3998 4003 labels, 3999 4004 location, 4000 4005 } => { ··· 4002 4007 self.problems.error(Error::IncorrectArity { 4003 4008 expected, 4004 4009 given, 4010 + context, 4005 4011 labels, 4006 4012 location, 4007 4013 });
+11 -2
compiler-core/src/type_/fields.rs
··· 1 1 use super::Error; 2 - use crate::ast::{CallArg, SrcSpan}; 2 + use crate::{ 3 + ast::{CallArg, SrcSpan}, 4 + type_::error::IncorrectArityContext, 5 + }; 3 6 use ecow::EcoString; 4 7 use itertools::Itertools; 5 8 use std::collections::{HashMap, HashSet}; ··· 39 42 /// Reorder an argument list so that labelled fields supplied out-of-order are 40 43 /// in the correct order. 41 44 /// 42 - pub fn reorder<A>(&self, args: &mut Vec<CallArg<A>>, location: SrcSpan) -> Result<(), Error> { 45 + pub fn reorder<A>( 46 + &self, 47 + args: &mut Vec<CallArg<A>>, 48 + location: SrcSpan, 49 + context: IncorrectArityContext, 50 + ) -> Result<(), Error> { 43 51 let mut labelled_arguments_given = false; 44 52 let mut seen_labels = HashSet::new(); 45 53 let mut unknown_labels = Vec::new(); ··· 49 57 return Err(Error::IncorrectArity { 50 58 labels: self.incorrect_arity_labels(args), 51 59 location, 60 + context, 52 61 expected: self.arity as usize, 53 62 given: args.len(), 54 63 });
+8 -1
compiler-core/src/type_/pattern.rs
··· 838 838 self.error(Error::IncorrectArity { 839 839 labels: vec![], 840 840 location, 841 + context: IncorrectArityContext::Pattern, 841 842 expected: type_elements.len(), 842 843 given: elements.len(), 843 844 }); ··· 1014 1015 } 1015 1016 } 1016 1017 1017 - if let Err(error) = field_map.reorder(&mut pattern_args, location) { 1018 + if let Err(error) = field_map.reorder( 1019 + &mut pattern_args, 1020 + location, 1021 + IncorrectArityContext::Pattern, 1022 + ) { 1018 1023 { 1019 1024 self.problems.error(error); 1020 1025 self.error_encountered = true; ··· 1131 1136 self.error(Error::IncorrectArity { 1132 1137 labels: vec![], 1133 1138 location, 1139 + context: IncorrectArityContext::Pattern, 1134 1140 expected: args.len(), 1135 1141 given: pattern_args.len(), 1136 1142 }); ··· 1165 1171 self.error(Error::IncorrectArity { 1166 1172 labels: vec![], 1167 1173 location, 1174 + context: IncorrectArityContext::Pattern, 1168 1175 expected: 0, 1169 1176 given: pattern_args.len(), 1170 1177 });
+4 -1
compiler-core/src/type_/tests.rs
··· 619 619 fields: self.fields, 620 620 }; 621 621 let location = SrcSpan { start: 0, end: 0 }; 622 - assert_eq!(self.expected_result, fm.reorder(&mut args, location)); 622 + assert_eq!( 623 + self.expected_result, 624 + fm.reorder(&mut args, location, IncorrectArityContext::Function) 625 + ); 623 626 assert_eq!(self.expected_args, args); 624 627 } 625 628 }