Skip to content

Commit aaa625a

Browse files
AaronC81lpil
authored andcommitted
Add specific parser error for type usages with angle-bracket generics
1 parent ae459f8 commit aaa625a

File tree

4 files changed

+68
-22
lines changed

4 files changed

+68
-22
lines changed

compiler-core/src/parse.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,28 +2748,35 @@ where
27482748
name: EcoString,
27492749
end: u32,
27502750
) -> Result<Option<TypeAst>, ParseError> {
2751-
match self.maybe_one(&Token::LeftParen) {
2752-
Some((par_s, _)) => {
2753-
let arguments = self.parse_types()?;
2754-
let (_, par_e) = self.expect_one(&Token::RightParen)?;
2755-
if arguments.is_empty() {
2756-
return parse_error(
2757-
ParseErrorType::TypeConstructorNoArguments,
2758-
SrcSpan::new(par_s, par_e),
2759-
);
2760-
}
2761-
Ok(Some(TypeAst::Constructor(TypeAstConstructor {
2762-
location: SrcSpan { start, end: par_e },
2763-
name_location: SrcSpan {
2764-
start: name_start,
2765-
end,
2766-
},
2767-
module,
2768-
name,
2769-
arguments,
2770-
})))
2751+
if let Some((par_s, _)) = self.maybe_one(&Token::LeftParen) {
2752+
let arguments = self.parse_types()?;
2753+
let (_, par_e) = self.expect_one(&Token::RightParen)?;
2754+
if arguments.is_empty() {
2755+
return parse_error(
2756+
ParseErrorType::TypeConstructorNoArguments,
2757+
SrcSpan::new(par_s, par_e),
2758+
);
27712759
}
2772-
_ => Ok(Some(TypeAst::Constructor(TypeAstConstructor {
2760+
Ok(Some(TypeAst::Constructor(TypeAstConstructor {
2761+
location: SrcSpan { start, end: par_e },
2762+
name_location: SrcSpan {
2763+
start: name_start,
2764+
end,
2765+
},
2766+
module,
2767+
name,
2768+
arguments,
2769+
})))
2770+
} else if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) {
2771+
Err(ParseError {
2772+
error: ParseErrorType::TypeAngleGenerics,
2773+
location: SrcSpan {
2774+
start: less_start,
2775+
end: less_end,
2776+
},
2777+
})
2778+
} else {
2779+
Ok(Some(TypeAst::Constructor(TypeAstConstructor {
27732780
location: SrcSpan { start, end },
27742781
name_location: SrcSpan {
27752782
start: name_start,
@@ -2778,7 +2785,7 @@ where
27782785
module,
27792786
name,
27802787
arguments: vec![],
2781-
}))),
2788+
})))
27822789
}
27832790
}
27842791

compiler-core/src/parse/error.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ pub enum ParseErrorType {
118118
// When the use tries to define a constant inside a function
119119
ConstantInsideFunction,
120120
FunctionDefinitionAngleGenerics, // fn something<T>() { ... }
121+
TypeAngleGenerics, // let a: List<String> = []
121122
}
122123

123124
pub(crate) struct ParseErrorDetails {
@@ -667,6 +668,19 @@ See: https://tour.gleam.run/functions/generic-functions/"
667668
label_text: "I was expecting `(` here.".into(),
668669
extra_labels: vec![],
669670
},
671+
672+
ParseErrorType::TypeAngleGenerics => ParseErrorDetails {
673+
text: "\
674+
Type parameters use lowercase names and are surrounded by parentheses.
675+
676+
List(String)
677+
Result(Int, Error)
678+
679+
See: https://tour.gleam.run/data-types/generic-custom-types/".into(),
680+
hint: None,
681+
label_text: "I was expecting `(` here.".into(),
682+
extra_labels: vec![],
683+
},
670684
}
671685
}
672686
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: compiler-core/src/parse/tests.rs
3+
expression: "let list: List<Int> = []"
4+
---
5+
----- SOURCE CODE
6+
let list: List<Int> = []
7+
8+
----- ERROR
9+
error: Syntax error
10+
┌─ /src/parse/error.gleam:1:15
11+
12+
1let list: List<Int> = []
13+
^ I was expecting `(` here.
14+
15+
Type parameters use lowercase names and are surrounded by parentheses.
16+
17+
List(String)
18+
Result(Int, Error)
19+
20+
See: https://tour.gleam.run/data-types/generic-custom-types/

compiler-core/src/parse/tests.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,3 +1947,8 @@ pub fn main() {
19471947
fn function_definition_angle_generics_error() {
19481948
assert_module_error!("fn id<T>(x: T) { x }");
19491949
}
1950+
1951+
#[test]
1952+
fn type_angle_generics_error() {
1953+
assert_error!("let list: List<Int> = []");
1954+
}

0 commit comments

Comments
 (0)