alpha
Login
or
Join now
nandi.uk
/
gleam
Star
2
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Fork of daniellemaywood.uk/gleam — Wasm codegen work
Star
2
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
parse blocks in case guards
author
Giacomo Cavalieri
committer
Louis Pilfold
date
11 months ago
(Aug 19, 2025, 8:15 PM +0100)
commit
d48babe0
d48babe0d9fda9f1e3b90b32b1c15f62a4eb88a8
parent
66d97b89
66d97b89a7b1ac5049a66e6568ea530c66fa70a3
+200
-29
6 changed files
Expand all
Collapse all
Unified
Split
compiler-core
src
format
tests.rs
parse
error.rs
snapshots
gleam_core__parse__tests__case_guard_with_empty_block.snap
gleam_core__parse__tests__case_guard_with_nested_blocks.snap
tests.rs
parse.rs
+5
-24
compiler-core/src/format/tests.rs
View file
Reviewed
···
4653
4653
}
4654
4654
4655
4655
#[test]
4656
4656
-
fn remove_braces_case_guard() {
4657
4657
-
assert_format_rewrite!(
4658
4658
-
"fn main() {
4659
4659
-
let is_enabled = False
4660
4660
-
let is_confirmed = False
4661
4661
-
let is_admin = True
4662
4662
-
case is_enabled, is_confirmed, is_admin {
4663
4663
-
is_enabled, is_confirmed, is_admin if { is_enabled && is_confirmed } || is_admin ->
4664
4664
-
Nil
4665
4665
-
_, _, _ -> Nil
4666
4666
-
}
4667
4667
-
}
4668
4668
-
",
4656
4656
+
fn do_not_remove_braces_from_case_guard() {
4657
4657
+
assert_format!(
4669
4658
"fn main() {
4670
4659
let is_enabled = False
4671
4660
let is_confirmed = False
4672
4661
let is_admin = True
4673
4662
case is_enabled, is_confirmed, is_admin {
4674
4663
is_enabled, is_confirmed, is_admin
4675
4675
-
if is_enabled && is_confirmed || is_admin
4664
4664
+
if { is_enabled && is_confirmed } || is_admin
4676
4665
-> Nil
4677
4666
_, _, _ -> Nil
4678
4667
}
···
4682
4671
}
4683
4672
4684
4673
#[test]
4685
4685
-
fn remove_braces_case_guard_2() {
4686
4686
-
assert_format_rewrite!(
4674
4674
+
fn do_not_remove_braces_from_case_guard_2() {
4675
4675
+
assert_format!(
4687
4676
"fn main() {
4688
4677
let wibble = #(10, [0])
4689
4678
case wibble {
4690
4679
wibble if True && { wibble.0 == 10 } -> Nil
4691
4691
-
_ -> Nil
4692
4692
-
}
4693
4693
-
}
4694
4694
-
",
4695
4695
-
"fn main() {
4696
4696
-
let wibble = #(10, [0])
4697
4697
-
case wibble {
4698
4698
-
wibble if True && wibble.0 == 10 -> Nil
4699
4680
_ -> Nil
4700
4681
}
4701
4682
}
+27
-5
compiler-core/src/parse.rs
View file
Reviewed
···
1809
1809
}
1810
1810
}
1811
1811
1812
1812
-
Some((_, Token::LeftBrace, _)) => {
1813
1813
-
// Nested guard expression
1812
1812
+
Some((start, Token::LeftBrace, _)) => {
1814
1813
self.advance();
1815
1815
-
let guard = self.parse_clause_guard_inner();
1816
1816
-
let _ = self.expect_one(&Token::RightBrace)?;
1817
1817
-
guard
1814
1814
+
Ok(Some(self.parse_case_clause_guard_block(start)?))
1818
1815
}
1819
1816
1820
1817
t0 => {
···
1828
1825
}
1829
1826
}
1830
1827
}
1828
1828
+
}
1829
1829
+
1830
1830
+
fn parse_case_clause_guard_block(
1831
1831
+
&mut self,
1832
1832
+
start: u32,
1833
1833
+
) -> Result<UntypedClauseGuard, ParseError> {
1834
1834
+
let body = self.parse_clause_guard_inner()?;
1835
1835
+
1836
1836
+
let Some(body) = body else {
1837
1837
+
let location = match self.next_tok() {
1838
1838
+
Some((_, Token::RightBrace, end)) => SrcSpan { start, end },
1839
1839
+
Some((_, _, _)) | None => SrcSpan {
1840
1840
+
start,
1841
1841
+
end: start + 1,
1842
1842
+
},
1843
1843
+
};
1844
1844
+
1845
1845
+
return parse_error(ParseErrorType::EmptyGuardBlock, location);
1846
1846
+
};
1847
1847
+
1848
1848
+
let (_, end) = self.expect_one(&Token::RightBrace)?;
1849
1849
+
Ok(ClauseGuard::Block {
1850
1850
+
location: SrcSpan { start, end },
1851
1851
+
value: Box::new(body),
1852
1852
+
})
1831
1853
}
1832
1854
1833
1855
fn parse_record_in_clause_guard(
+10
compiler-core/src/parse/error.rs
View file
Reviewed
···
112
112
module: EcoString,
113
113
item: EcoString,
114
114
},
115
115
+
/// This can happen when there's an empty block in a case clause guard.
116
116
+
/// For example: `_ if a == {}`
117
117
+
EmptyGuardBlock,
115
118
}
116
119
117
120
pub(crate) struct ParseErrorDetails {
···
625
628
.join("\n"),
626
629
hint: None,
627
630
label_text: "I was expecting either `/` or `.{` here.".into(),
631
631
+
extra_labels: vec![],
632
632
+
},
633
633
+
634
634
+
ParseErrorType::EmptyGuardBlock => ParseErrorDetails {
635
635
+
text: "".into(),
636
636
+
hint: None,
637
637
+
label_text: "A clause guard block cannot be empty".into(),
628
638
extra_labels: vec![],
629
639
},
630
640
}
+15
compiler-core/src/parse/snapshots/gleam_core__parse__tests__case_guard_with_empty_block.snap
View file
Reviewed
···
1
1
+
---
2
2
+
source: compiler-core/src/parse/tests.rs
3
3
+
expression: "case 1 {\n _ if a || {} -> 1\n}"
4
4
+
---
5
5
+
----- SOURCE CODE
6
6
+
case 1 {
7
7
+
_ if a || {} -> 1
8
8
+
}
9
9
+
10
10
+
----- ERROR
11
11
+
error: Syntax error
12
12
+
┌─ /src/parse/error.gleam:2:13
13
13
+
│
14
14
+
2 │ _ if a || {} -> 1
15
15
+
│ ^^ A clause guard block cannot be empty
+125
compiler-core/src/parse/snapshots/gleam_core__parse__tests__case_guard_with_nested_blocks.snap
View file
Reviewed
···
1
1
+
---
2
2
+
source: compiler-core/src/parse/tests.rs
3
3
+
expression: "case 1 {\n _ if { 1 || { 1 || 1 } } || 1 -> 1\n}"
4
4
+
---
5
5
+
[
6
6
+
Expression(
7
7
+
Case {
8
8
+
location: SrcSpan {
9
9
+
start: 0,
10
10
+
end: 48,
11
11
+
},
12
12
+
subjects: [
13
13
+
Int {
14
14
+
location: SrcSpan {
15
15
+
start: 5,
16
16
+
end: 6,
17
17
+
},
18
18
+
value: "1",
19
19
+
int_value: 1,
20
20
+
},
21
21
+
],
22
22
+
clauses: Some(
23
23
+
[
24
24
+
Clause {
25
25
+
location: SrcSpan {
26
26
+
start: 11,
27
27
+
end: 46,
28
28
+
},
29
29
+
pattern: [
30
30
+
Discard {
31
31
+
name: "_",
32
32
+
location: SrcSpan {
33
33
+
start: 11,
34
34
+
end: 12,
35
35
+
},
36
36
+
type_: (),
37
37
+
},
38
38
+
],
39
39
+
alternative_patterns: [],
40
40
+
guard: Some(
41
41
+
Or {
42
42
+
location: SrcSpan {
43
43
+
start: 16,
44
44
+
end: 40,
45
45
+
},
46
46
+
left: Block {
47
47
+
location: SrcSpan {
48
48
+
start: 16,
49
49
+
end: 35,
50
50
+
},
51
51
+
value: Or {
52
52
+
location: SrcSpan {
53
53
+
start: 18,
54
54
+
end: 33,
55
55
+
},
56
56
+
left: Constant(
57
57
+
Int {
58
58
+
location: SrcSpan {
59
59
+
start: 18,
60
60
+
end: 19,
61
61
+
},
62
62
+
value: "1",
63
63
+
int_value: 1,
64
64
+
},
65
65
+
),
66
66
+
right: Block {
67
67
+
location: SrcSpan {
68
68
+
start: 23,
69
69
+
end: 33,
70
70
+
},
71
71
+
value: Or {
72
72
+
location: SrcSpan {
73
73
+
start: 25,
74
74
+
end: 31,
75
75
+
},
76
76
+
left: Constant(
77
77
+
Int {
78
78
+
location: SrcSpan {
79
79
+
start: 25,
80
80
+
end: 26,
81
81
+
},
82
82
+
value: "1",
83
83
+
int_value: 1,
84
84
+
},
85
85
+
),
86
86
+
right: Constant(
87
87
+
Int {
88
88
+
location: SrcSpan {
89
89
+
start: 30,
90
90
+
end: 31,
91
91
+
},
92
92
+
value: "1",
93
93
+
int_value: 1,
94
94
+
},
95
95
+
),
96
96
+
},
97
97
+
},
98
98
+
},
99
99
+
},
100
100
+
right: Constant(
101
101
+
Int {
102
102
+
location: SrcSpan {
103
103
+
start: 39,
104
104
+
end: 40,
105
105
+
},
106
106
+
value: "1",
107
107
+
int_value: 1,
108
108
+
},
109
109
+
),
110
110
+
},
111
111
+
),
112
112
+
then: Int {
113
113
+
location: SrcSpan {
114
114
+
start: 45,
115
115
+
end: 46,
116
116
+
},
117
117
+
value: "1",
118
118
+
int_value: 1,
119
119
+
},
120
120
+
},
121
121
+
],
122
122
+
),
123
123
+
},
124
124
+
),
125
125
+
]
+18
compiler-core/src/parse/tests.rs
View file
Reviewed
···
1912
1912
fn private_opaque_type_is_parsed() {
1913
1913
assert_parse_module!("opaque type Wibble { Wobble }");
1914
1914
}
1915
1915
+
1916
1916
+
#[test]
1917
1917
+
fn case_guard_with_nested_blocks() {
1918
1918
+
assert_parse!(
1919
1919
+
"case 1 {
1920
1920
+
_ if { 1 || { 1 || 1 } } || 1 -> 1
1921
1921
+
}"
1922
1922
+
);
1923
1923
+
}
1924
1924
+
1925
1925
+
#[test]
1926
1926
+
fn case_guard_with_empty_block() {
1927
1927
+
assert_error!(
1928
1928
+
"case 1 {
1929
1929
+
_ if a || {} -> 1
1930
1930
+
}"
1931
1931
+
);
1932
1932
+
}