Skip to content

Commit 8bc71cb

Browse files
mxtthiaslpil
authored andcommitted
Move "Did you want a Bool" error to analysis step
Fixes #5052
1 parent b373611 commit 8bc71cb

File tree

9 files changed

+95
-44
lines changed

9 files changed

+95
-44
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929

3030
([Surya Rose](https://github.com/GearsDatapacks))
3131

32+
- The lowercase bool pattern error is no longer a syntax error, but instead a
33+
part of the analysis step. This allows the entire module to be analyzed, rather
34+
than stopping at the syntax error.
35+
([mxtthias](https://github.com/mxtthias))
36+
3237
### Build tool
3338

3439
- The help text displayed by `gleam dev --help`, `gleam test --help`, and

compiler-core/src/error.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4025,6 +4025,22 @@ with no constructors."
40254025
extra_labels: vec![],
40264026
}),
40274027
},
4028+
4029+
TypeError::LowercaseBoolPattern { location } => Diagnostic {
4030+
title: "Lowercase bool pattern".to_string(),
4031+
text: "See: https://tour.gleam.run/basics/bools/".into(),
4032+
hint: Some("In Gleam bool literals are `True` and `False`.".into()),
4033+
level: Level::Error,
4034+
location: Some(Location {
4035+
label: Label {
4036+
text: Some("This is not a bool".into()),
4037+
span: *location,
4038+
},
4039+
path: path.clone(),
4040+
src: src.clone(),
4041+
extra_labels: vec![],
4042+
}),
4043+
},
40284044
})
40294045
.collect_vec(),
40304046

compiler-core/src/parse.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,22 +1278,14 @@ where
12781278
}
12791279
}
12801280
} else {
1281-
match name.as_str() {
1282-
"true" | "false" => {
1283-
return parse_error(
1284-
ParseErrorType::LowcaseBooleanPattern,
1285-
SrcSpan { start, end },
1286-
);
1287-
}
1288-
_ => Pattern::Variable {
1289-
origin: VariableOrigin {
1290-
syntax: VariableSyntax::Variable(name.clone()),
1291-
declaration: position.to_declaration(),
1292-
},
1293-
location: SrcSpan { start, end },
1294-
name,
1295-
type_: (),
1281+
Pattern::Variable {
1282+
origin: VariableOrigin {
1283+
syntax: VariableSyntax::Variable(name.clone()),
1284+
declaration: position.to_declaration(),
12961285
},
1286+
location: SrcSpan { start, end },
1287+
name,
1288+
type_: (),
12971289
}
12981290
}
12991291
}

compiler-core/src/parse/error.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ pub enum ParseErrorType {
7777
ListSpreadWithAnotherSpread {
7878
first_spread_location: SrcSpan,
7979
}, // trying to use multiple spreads: `[..xs, ..ys]`
80-
LowcaseBooleanPattern, // most likely user meant True or False in patterns
8180
UnexpectedLabel, // argument labels were provided, but are not supported in this context
8281
UnexpectedEof,
8382
UnexpectedReservedWord, // reserved word used when a name was expected
@@ -420,13 +419,6 @@ utf16_codepoint, utf32_codepoint, signed, unsigned, big, little, native, size, u
420419
extra_labels: vec![],
421420
},
422421

423-
ParseErrorType::LowcaseBooleanPattern => ParseErrorDetails {
424-
text: "See: https://tour.gleam.run/basics/bools/".into(),
425-
hint: Some("In Gleam boolean literals are `True` and `False`.".into()),
426-
label_text: "Did you want a Bool instead of a variable?".into(),
427-
extra_labels: vec![],
428-
},
429-
430422
ParseErrorType::UnexpectedLabel => ParseErrorDetails {
431423
text: "Please remove the argument label.".into(),
432424
hint: None,

compiler-core/src/parse/tests.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -363,18 +363,6 @@ fn pointless_spread() {
363363
);
364364
}
365365

366-
// https://github.com/gleam-lang/gleam/issues/1358
367-
#[test]
368-
fn lowcase_bool_in_pattern() {
369-
assert_error!(
370-
"case 42 > 42 { true -> 1; false -> 2; }",
371-
ParseError {
372-
error: ParseErrorType::LowcaseBooleanPattern,
373-
location: SrcSpan { start: 15, end: 19 },
374-
}
375-
);
376-
}
377-
378366
// https://github.com/gleam-lang/gleam/issues/1613
379367
#[test]
380368
fn anonymous_function_labeled_arguments() {

compiler-core/src/type_/error.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@ pub enum Error {
672672
ExternalTypeWithConstructors {
673673
location: SrcSpan,
674674
},
675+
676+
LowercaseBoolPattern {
677+
location: SrcSpan,
678+
},
675679
}
676680

677681
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -1310,7 +1314,8 @@ impl Error {
13101314
| Error::NonUtf8StringAssignmentInBitArray { location }
13111315
| Error::PrivateOpaqueType { location }
13121316
| Error::SrcImportingDevDependency { location, .. }
1313-
| Error::ExternalTypeWithConstructors { location, .. } => location.start,
1317+
| Error::ExternalTypeWithConstructors { location, .. }
1318+
| Error::LowercaseBoolPattern { location } => location.start,
13141319
Error::UnknownLabels { unknown, .. } => {
13151320
unknown.iter().map(|(_, s)| s.start).min().unwrap_or(0)
13161321
}

compiler-core/src/type_/pattern.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -608,16 +608,22 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
608608
location,
609609
origin,
610610
..
611-
} => {
612-
self.insert_variable(&name, type_.clone(), location, origin.clone());
611+
} => match name.as_str() {
612+
"true" | "false" => {
613+
self.error(Error::LowercaseBoolPattern { location });
614+
Pattern::Invalid { location, type_ }
615+
}
616+
_ => {
617+
self.insert_variable(&name, type_.clone(), location, origin.clone());
613618

614-
Pattern::Variable {
615-
type_,
616-
name,
617-
location,
618-
origin,
619+
Pattern::Variable {
620+
type_,
621+
name,
622+
location,
623+
origin,
624+
}
619625
}
620-
}
626+
},
621627

622628
Pattern::BitArraySize(size) => {
623629
let location = size.location();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
source: compiler-core/src/type_/tests.rs
3+
expression: "\npub fn main() {\n case 42 > 42 {\n true -> 1\n false -> 2\n }\n}\n"
4+
---
5+
----- SOURCE CODE
6+
7+
pub fn main() {
8+
case 42 > 42 {
9+
true -> 1
10+
false -> 2
11+
}
12+
}
13+
14+
15+
----- ERROR
16+
error: Lowercase bool pattern
17+
┌─ /src/one/two.gleam:4:5
18+
19+
4true -> 1
20+
^^^^ This is not a bool
21+
22+
See: https://tour.gleam.run/basics/bools/
23+
Hint: In Gleam bool literals are `True` and `False`.
24+
25+
error: Lowercase bool pattern
26+
┌─ /src/one/two.gleam:5:5
27+
28+
5false -> 2
29+
^^^^^ This is not a bool
30+
31+
See: https://tour.gleam.run/basics/bools/
32+
Hint: In Gleam bool literals are `True` and `False`.

compiler-core/src/type_/tests.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,6 +2134,21 @@ pub fn main() {
21342134
);
21352135
}
21362136

2137+
// https://github.com/gleam-lang/gleam/issues/1358
2138+
#[test]
2139+
fn type_unification_does_not_allow_lowercase_bools_in_match_clause() {
2140+
assert_module_error!(
2141+
r#"
2142+
pub fn main() {
2143+
case 42 > 42 {
2144+
true -> 1
2145+
false -> 2
2146+
}
2147+
}
2148+
"#
2149+
);
2150+
}
2151+
21372152
#[test]
21382153
fn record_update_variant_inference_in_alternate_pattern_with_all_same_variants() {
21392154
assert_module_infer!(

0 commit comments

Comments
 (0)