Skip to content

Commit 12f8d70

Browse files
giacomocavalierilpil
authored andcommitted
allow matching on list arguments
fixes #4806
1 parent 3056ba4 commit 12f8d70

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

compiler-core/src/language_server/code_action.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4664,6 +4664,14 @@ where
46644664
match type_ {
46654665
Type::Fn { .. } => None,
46664666
Type::Var { type_ } => self.type_var_to_destructure_patterns(&type_.borrow()),
4667+
4668+
// We special case lists, they don't have "regular" constructors
4669+
// like other types. Instead we always add the two branches covering
4670+
// the empty and non empty list.
4671+
Type::Named { .. } if type_.is_list() => {
4672+
Some(vec1!["[]".into(), "[first, ..rest]".into()])
4673+
}
4674+
46674675
Type::Named {
46684676
module: type_module,
46694677
name: type_name,

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9162,3 +9162,14 @@ fn remove_opaque_from_private_type() {
91629162
find_position_of("Wibble").to_selection()
91639163
);
91649164
}
9165+
9166+
#[test]
9167+
fn pattern_match_on_list_variable() {
9168+
assert_code_action!(
9169+
PATTERN_MATCH_ON_ARGUMENT,
9170+
"pub fn main(a_list: List(a)) {
9171+
todo
9172+
}",
9173+
find_position_of("a_list").to_selection()
9174+
);
9175+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "pub fn main(a_list: List(a)) {\n todo\n}"
4+
---
5+
----- BEFORE ACTION
6+
pub fn main(a_list: List(a)) {
7+
8+
todo
9+
}
10+
11+
12+
----- AFTER ACTION
13+
pub fn main(a_list: List(a)) {
14+
case a_list {
15+
[] -> todo
16+
[first, ..rest] -> todo
17+
}
18+
todo
19+
}

compiler-core/src/type_.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,14 @@ impl Type {
320320
}
321321
}
322322

323+
pub fn is_list(&self) -> bool {
324+
match self {
325+
Self::Named { module, name, .. } if "List" == name && is_prelude_module(module) => true,
326+
Self::Var { type_ } => type_.borrow().is_list(),
327+
_ => false,
328+
}
329+
}
330+
323331
pub fn named_type_name(&self) -> Option<(EcoString, EcoString)> {
324332
match self {
325333
Self::Named { module, name, .. } => Some((module.clone(), name.clone())),
@@ -1239,6 +1247,13 @@ impl TypeVar {
12391247
}
12401248
}
12411249

1250+
pub fn is_list(&self) -> bool {
1251+
match self {
1252+
TypeVar::Link { type_ } => type_.is_list(),
1253+
TypeVar::Unbound { .. } | TypeVar::Generic { .. } => false,
1254+
}
1255+
}
1256+
12421257
pub fn result_ok_type(&self) -> Option<Arc<Type>> {
12431258
match self {
12441259
TypeVar::Link { type_ } => type_.result_ok_type(),

0 commit comments

Comments
 (0)