Skip to content

Commit 361b7f2

Browse files
committed
They are called clauses, not branches
1 parent 9000668 commit 361b7f2

File tree

5 files changed

+65
-37
lines changed

5 files changed

+65
-37
lines changed

CHANGELOG.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959
([Giacomo Cavalieri](https://github.com/giacomocavalieri))
6060

61-
- The compiler now raises a warning for unreachable branches that are matching
61+
- The compiler now raises a warning for unreachable clauses that are matching
6262
on bit array segments that could never match. Consider this example:
6363

6464
```gleam
@@ -71,7 +71,7 @@
7171
}
7272
```
7373

74-
There's a subtle bug here. The second branch can never match since it's
74+
There's a subtle bug here. The second clause can never match since it's
7575
impossible for the first byte of the bit array to have the value `404`.
7676
The new error explains this nicely:
7777

@@ -383,23 +383,23 @@
383383
### Language server
384384

385385
- The language server now offers a code action to remove all the unreachable
386-
branches in a case expression. For example:
386+
clauses in a case expression. For example:
387387

388388
```gleam
389389
pub fn main() {
390390
case find_user() {
391391
Ok(user) -> todo
392392
Ok(Admin) -> todo
393-
// ^^^^^^^^^ This branch is unreachable
393+
// ^^^^^^^^^ This clause is unreachable
394394
Ok(User) -> todo
395-
// ^^^^^^^^ This branch is unreachable
395+
// ^^^^^^^^ This clause is unreachable
396396
Error(_) -> todo
397397
}
398398
}
399399
```
400400

401-
Hovering over one of the unreachable branches and triggering the code action
402-
would remove all the unreachable branches:
401+
Hovering over one of the unreachable clauses and triggering the code action
402+
would remove all the unreachable clauses:
403403

404404
```gleam
405405
pub fn main() {

compiler-core/src/language_server/code_action.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,14 +3706,14 @@ impl<'a> GenerateDynamicDecoder<'a> {
37063706
eco_format!("use variant <- {module}.field(\"type\", {module}.string)")
37073707
};
37083708

3709-
let mut branches = Vec::with_capacity(constructors_size);
3709+
let mut clauses = Vec::with_capacity(constructors_size);
37103710
for constructor in iter::once(first).chain(rest) {
37113711
let body = self.constructor_decoder(mode, custom_type, constructor, 4)?;
37123712
let name = to_snake_case(&constructor.name);
3713-
branches.push(eco_format!(r#" "{name}" -> {body}"#));
3713+
clauses.push(eco_format!(r#" "{name}" -> {body}"#));
37143714
}
37153715

3716-
let cases = branches.join("\n");
3716+
let cases = clauses.join("\n");
37173717
let type_name = &custom_type.name;
37183718
Some(eco_format!(
37193719
r#"{{
@@ -4116,7 +4116,7 @@ impl<'a> GenerateJsonEncoder<'a> {
41164116
// Otherwise we generate an encoder for a type with multiple constructors:
41174117
// it will need to pattern match on the various constructors and encode each
41184118
// one separately.
4119-
let mut branches = Vec::with_capacity(constructors_size);
4119+
let mut clauses = Vec::with_capacity(constructors_size);
41204120
for constructor in iter::once(first).chain(rest) {
41214121
let RecordConstructor { name, .. } = constructor;
41224122
let encoder =
@@ -4135,13 +4135,13 @@ impl<'a> GenerateJsonEncoder<'a> {
41354135
.join(":, ")
41364136
)
41374137
};
4138-
branches.push(eco_format!(" {name}{unpacking} -> {encoder}"));
4138+
clauses.push(eco_format!(" {name}{unpacking} -> {encoder}"));
41394139
}
41404140

4141-
let branches = branches.join("\n");
4141+
let clauses = clauses.join("\n");
41424142
Some(eco_format!(
41434143
"case {record_name} {{
4144-
{branches}
4144+
{clauses}
41454145
}}",
41464146
))
41474147
}
@@ -4720,7 +4720,7 @@ impl<'a, IO> PatternMatchOnValue<'a, IO> {
47204720
Type::Var { type_ } => self.type_var_to_destructure_patterns(&type_.borrow()),
47214721

47224722
// We special case lists, they don't have "regular" constructors
4723-
// like other types. Instead we always add the two branches covering
4723+
// like other types. Instead we always add the two clauses covering
47244724
// the empty and non empty list.
47254725
Type::Named { .. } if type_.is_list() => {
47264726
Some(vec1!["[]".into(), "[first, ..rest]".into()])
@@ -8230,53 +8230,53 @@ fn single_expression(expression: &TypedExpr) -> Option<&TypedExpr> {
82308230
}
82318231
}
82328232

8233-
/// Code action to remove `opaque` from a private type.
8233+
/// Code action to remove unreachable clauses from a case expression.
82348234
///
8235-
pub struct RemoveUnreachableBranches<'a> {
8235+
pub struct RemoveUnreachableCaseClauses<'a> {
82368236
module: &'a Module,
82378237
params: &'a CodeActionParams,
82388238
edits: TextEdits<'a>,
8239-
/// The source location of the patterns of all the unreachable branches in
8239+
/// The source location of the patterns of all the unreachable clauses in
82408240
/// the current module.
82418241
///
8242-
unreachable_branches: HashSet<SrcSpan>,
8243-
branches_to_delete: Vec<SrcSpan>,
8242+
unreachable_clauses: HashSet<SrcSpan>,
8243+
clauses_to_delete: Vec<SrcSpan>,
82448244
}
82458245

8246-
impl<'a> RemoveUnreachableBranches<'a> {
8246+
impl<'a> RemoveUnreachableCaseClauses<'a> {
82478247
pub fn new(
82488248
module: &'a Module,
82498249
line_numbers: &'a LineNumbers,
82508250
params: &'a CodeActionParams,
82518251
) -> Self {
8252-
let unreachable_branches = (module.ast.type_info.warnings.iter())
8252+
let unreachable_clauses = (module.ast.type_info.warnings.iter())
82538253
.filter_map(|warning| match warning {
82548254
type_::Warning::UnreachableCasePattern { location, .. } => Some(*location),
82558255
_ => None,
82568256
})
82578257
.collect();
82588258

82598259
Self {
8260-
unreachable_branches,
8260+
unreachable_clauses,
82618261
module,
82628262
params,
82638263
edits: TextEdits::new(line_numbers),
8264-
branches_to_delete: vec![],
8264+
clauses_to_delete: vec![],
82658265
}
82668266
}
82678267

82688268
pub fn code_actions(mut self) -> Vec<CodeAction> {
82698269
self.visit_typed_module(&self.module.ast);
8270-
if self.branches_to_delete.is_empty() {
8270+
if self.clauses_to_delete.is_empty() {
82718271
return vec![];
82728272
}
82738273

8274-
for branch in self.branches_to_delete {
8274+
for branch in self.clauses_to_delete {
82758275
self.edits.delete(branch);
82768276
}
82778277

82788278
let mut action = Vec::with_capacity(1);
8279-
CodeActionBuilder::new("Remove unreachable branches")
8279+
CodeActionBuilder::new("Remove unreachable clauses")
82808280
.kind(CodeActionKind::QUICKFIX)
82818281
.changes(self.params.text_document.uri.clone(), self.edits.edits)
82828282
.preferred(true)
@@ -8285,7 +8285,7 @@ impl<'a> RemoveUnreachableBranches<'a> {
82858285
}
82868286
}
82878287

8288-
impl<'ast> ast::visit::Visit<'ast> for RemoveUnreachableBranches<'ast> {
8288+
impl<'ast> ast::visit::Visit<'ast> for RemoveUnreachableCaseClauses<'ast> {
82898289
fn visit_typed_expr_case(
82908290
&mut self,
82918291
location: &'ast SrcSpan,
@@ -8302,18 +8302,18 @@ impl<'ast> ast::visit::Visit<'ast> for RemoveUnreachableBranches<'ast> {
83028302
within(self.params.range, pattern_range)
83038303
});
83048304
if is_hovering_clause {
8305-
self.branches_to_delete = clauses
8305+
self.clauses_to_delete = clauses
83068306
.iter()
83078307
.filter(|clause| {
8308-
self.unreachable_branches
8308+
self.unreachable_clauses
83098309
.contains(&clause.pattern_location())
83108310
})
83118311
.map(|clause| clause.location())
83128312
.collect_vec();
83138313
return;
83148314
}
83158315

8316-
// If we're not hovering any of the branches clauses then we want to
8316+
// If we're not hovering any of the clauses then we want to
83178317
// keep visiting the case expression as the unreachable branch might be
83188318
// in one of the nested cases.
83198319
ast::visit::visit_typed_expr_case(self, location, type_, subjects, clauses, compiled_case);

compiler-core/src/language_server/engine.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
language_server::{
1515
code_action::{
1616
AddOmittedLabels, CollapseNestedCase, ExtractFunction, RemoveBlock,
17-
RemovePrivateOpaque, RemoveUnreachableBranches,
17+
RemovePrivateOpaque, RemoveUnreachableCaseClauses,
1818
},
1919
compiler::LspProjectCompiler,
2020
files::FileSystemProxy,
@@ -408,7 +408,8 @@ where
408408
code_action_fix_names(&lines, &params, &this.error, &mut actions);
409409
code_action_import_module(module, &lines, &params, &this.error, &mut actions);
410410
code_action_add_missing_patterns(module, &lines, &params, &this.error, &mut actions);
411-
actions.extend(RemoveUnreachableBranches::new(module, &lines, &params).code_actions());
411+
actions
412+
.extend(RemoveUnreachableCaseClauses::new(module, &lines, &params).code_actions());
412413
actions.extend(CollapseNestedCase::new(module, &lines, &params).code_actions());
413414
code_action_inexhaustive_let_to_case(
414415
module,

compiler-core/src/language_server/tests/action.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ const GENERATE_VARIANT: &str = "Generate variant";
133133
const REMOVE_BLOCK: &str = "Remove block";
134134
const REMOVE_OPAQUE_FROM_PRIVATE_TYPE: &str = "Remove opaque from private type";
135135
const COLLAPSE_NESTED_CASE: &str = "Collapse nested case";
136-
const REMOVE_UNREACHABLE_BRANCHES: &str = "Remove unreachable branches";
136+
const REMOVE_UNREACHABLE_CLAUSES: &str = "Remove unreachable clauses";
137137
const ADD_OMITTED_LABELS: &str = "Add omitted labels";
138138
const EXTRACT_FUNCTION: &str = "Extract function";
139139

@@ -10003,9 +10003,9 @@ pub fn main() {
1000310003
}
1000410004

1000510005
#[test]
10006-
fn remove_unreachable_branches() {
10006+
fn remove_unreachable_clauses() {
1000710007
assert_code_action!(
10008-
REMOVE_UNREACHABLE_BRANCHES,
10008+
REMOVE_UNREACHABLE_CLAUSES,
1000910009
"pub fn main(x) {
1001010010
case x {
1001110011
Ok(n) -> 1
@@ -10022,7 +10022,7 @@ fn remove_unreachable_branches() {
1002210022
#[test]
1002310023
fn remove_unreachable_branches_does_not_pop_up_if_all_branches_are_reachable() {
1002410024
assert_no_code_actions!(
10025-
REMOVE_UNREACHABLE_BRANCHES,
10025+
REMOVE_UNREACHABLE_CLAUSES,
1002610026
"pub fn main(x) {
1002710027
case x {
1002810028
Ok(n) -> 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
assertion_line: 10007
4+
expression: "pub fn main(x) {\n case x {\n Ok(n) -> 1\n Ok(_) -> 2\n Error(_) -> todo\n Ok(1) -> 3\n }\n}\n"
5+
snapshot_kind: text
6+
---
7+
----- BEFORE ACTION
8+
pub fn main(x) {
9+
case x {
10+
Ok(n) -> 1
11+
Ok(_) -> 2
12+
Error(_) -> todo
13+
Ok(1) -> 3
14+
15+
}
16+
}
17+
18+
19+
----- AFTER ACTION
20+
pub fn main(x) {
21+
case x {
22+
Ok(n) -> 1
23+
24+
Error(_) -> todo
25+
26+
}
27+
}

0 commit comments

Comments
 (0)