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

Configure Feed

Select the types of activity you want to include in your feed.

Add relevant suggestion when a type annotation uses angle brackets

authored by

Aaron Christiansen and committed by
Louis Pilfold
(Sep 8, 2025, 1:04 PM +0100) b23e00f9 4f5991c6

+94 -6
+7 -2
compiler-core/src/parse.rs
··· 2564 2564 Ok((start, upname, arguments2, par_e, end)) 2565 2565 } else if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) { 2566 2566 Err(ParseError { 2567 - error: ParseErrorType::TypeAngleGenerics, 2567 + error: ParseErrorType::TypeDefinitionAngleGenerics, 2568 2568 location: SrcSpan { 2569 2569 start: less_start, 2570 2570 end: less_end, ··· 2775 2775 arguments, 2776 2776 }))) 2777 2777 } else if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) { 2778 + let arguments = self.parse_types()?; 2778 2779 Err(ParseError { 2779 - error: ParseErrorType::TypeAngleGenerics, 2780 + error: ParseErrorType::TypeUsageAngleGenerics { 2781 + name, 2782 + module: module.map(|(module_name, _)| module_name), 2783 + arguments, 2784 + }, 2780 2785 location: SrcSpan { 2781 2786 start: less_start, 2782 2787 end: less_end,
+42 -2
compiler-core/src/parse/error.rs
··· 118 118 // When the use tries to define a constant inside a function 119 119 ConstantInsideFunction, 120 120 FunctionDefinitionAngleGenerics, // fn something<T>() { ... } 121 - TypeAngleGenerics, // let a: List<String> = [] 121 + // let a: List<String> = [] 122 + TypeUsageAngleGenerics { 123 + module: Option<EcoString>, 124 + name: EcoString, 125 + arguments: Vec<TypeAst>, 126 + }, 127 + // type Something<T> { 128 + TypeDefinitionAngleGenerics, 122 129 } 123 130 124 131 pub(crate) struct ParseErrorDetails { ··· 669 676 extra_labels: vec![], 670 677 }, 671 678 672 - ParseErrorType::TypeAngleGenerics => ParseErrorDetails { 679 + ParseErrorType::TypeUsageAngleGenerics { 680 + module, 681 + name, 682 + arguments, 683 + } => { 684 + let type_arguments = arguments 685 + .iter() 686 + .map(|argument| { 687 + let mut argument_string = EcoString::new(); 688 + argument.print(&mut argument_string); 689 + argument_string 690 + }) 691 + .join(", "); 692 + let replacement_type = match module { 693 + Some(module) => format!("{module}.{name}({type_arguments})"), 694 + None => format!("{name}({type_arguments})"), 695 + }; 696 + 697 + ParseErrorDetails { 698 + text: format!( 699 + "\ 700 + Type parameters use lowercase names and are surrounded by parentheses. 701 + 702 + {replacement_type} 703 + 704 + See: https://tour.gleam.run/data-types/generic-custom-types/" 705 + ), 706 + hint: None, 707 + label_text: "I was expecting `(` here.".into(), 708 + extra_labels: vec![], 709 + } 710 + } 711 + 712 + ParseErrorType::TypeDefinitionAngleGenerics => ParseErrorDetails { 673 713 text: "\ 674 714 Type parameters use lowercase names and are surrounded by parentheses. 675 715
+19
compiler-core/src/parse/snapshots/gleam_core__parse__tests__type_angle_generics_usage_with_module_error.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: "let set: set.Set<Int> = set.new()" 4 + --- 5 + ----- SOURCE CODE 6 + let set: set.Set<Int> = set.new() 7 + 8 + ----- ERROR 9 + error: Syntax error 10 + ┌─ /src/parse/error.gleam:1:17 11 + 12 + 1 │ let set: set.Set<Int> = set.new() 13 + │ ^ I was expecting `(` here. 14 + 15 + Type parameters use lowercase names and are surrounded by parentheses. 16 + 17 + set.Set(Int) 18 + 19 + See: https://tour.gleam.run/data-types/generic-custom-types/
+19
compiler-core/src/parse/snapshots/gleam_core__parse__tests__type_angle_generics_usage_without_module_error.snap
··· 1 + --- 2 + source: compiler-core/src/parse/tests.rs 3 + expression: "let list: List<Int, String> = []" 4 + --- 5 + ----- SOURCE CODE 6 + let list: List<Int, String> = [] 7 + 8 + ----- ERROR 9 + error: Syntax error 10 + ┌─ /src/parse/error.gleam:1:15 11 + 12 + 1 │ let list: List<Int, String> = [] 13 + │ ^ I was expecting `(` here. 14 + 15 + Type parameters use lowercase names and are surrounded by parentheses. 16 + 17 + List(Int, String) 18 + 19 + See: https://tour.gleam.run/data-types/generic-custom-types/
+7 -2
compiler-core/src/parse/tests.rs
··· 1949 1949 } 1950 1950 1951 1951 #[test] 1952 - fn type_angle_generics_usage_error() { 1953 - assert_error!("let list: List<Int> = []"); 1952 + fn type_angle_generics_usage_without_module_error() { 1953 + assert_error!("let list: List<Int, String> = []"); 1954 + } 1955 + 1956 + #[test] 1957 + fn type_angle_generics_usage_with_module_error() { 1958 + assert_error!("let set: set.Set<Int> = set.new()"); 1954 1959 } 1955 1960 1956 1961 #[test]