Skip to content

Commit 6c7beb8

Browse files
giacomocavalierilpil
authored andcommitted
generate valid code when matching on the rhs of another let
1 parent 0899b25 commit 6c7beb8

4 files changed

Lines changed: 64 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
or git dependency on Hex when running `gleam update`.
5353
([Giacomo Cavalieri](https://github.com/giacomocavalieri))
5454

55+
- Fixed a bug where the "pattern match on value" code action would generate
56+
invalid code when used on a `let` assignment on the right hand side of another
57+
`let` assignment.
58+
([Giacomo Cavalieri](https://github.com/giacomocavalieri))
59+
5560
- Fixed a bug where the compiler wouldn't track the minimum required version
5661
when using list prepending in constants.
5762
([Giacomo Cavalieri](https://github.com/giacomocavalieri))

language-server/src/code_action.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6007,7 +6007,18 @@ impl<'ast, IO> ast::visit::Visit<'ast> for PatternMatchOnValue<'ast, IO> {
60076007
}
60086008

60096009
ast::visit::visit_typed_assignment(self, assignment);
6010-
if let Some((name, _, ref type_)) = self.pattern_variable_under_cursor {
6010+
if let Some((name, _, ref type_)) = self.pattern_variable_under_cursor
6011+
// We must make sure that no other value was selected while visiting
6012+
// this. If it were `Some` that means that we have found _another_
6013+
// variable to match on inside the assignmemt itself. For example:
6014+
// ```gleam
6015+
// let a = {
6016+
// let b = todo
6017+
// // ^ We're matching on this, not the outer one!
6018+
// }
6019+
// ```
6020+
&& self.selected_value.is_none()
6021+
{
60116022
self.selected_value = Some(PatternMatchedValue::LetVariable {
60126023
variable_name: name,
60136024
variable_type: type_.clone(),

language-server/src/tests/action.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7860,6 +7860,24 @@ fn maybe_wibble() { Ok(Wobble) }
78607860
);
78617861
}
78627862

7863+
#[test]
7864+
// https://github.com/gleam-lang/gleam/issues/5648
7865+
fn pattern_match_on_variable_defined_inside_anonymous_function() {
7866+
assert_code_action!(
7867+
PATTERN_MATCH_ON_VARIABLE,
7868+
"
7869+
pub fn main() {
7870+
let outcome = apply(#(Ok(1), Nil), fn(pair) {
7871+
let #(result, nil) = pair
7872+
})
7873+
}
7874+
7875+
fn apply(a, f) { f(a) }
7876+
",
7877+
find_position_of("result").to_selection()
7878+
);
7879+
}
7880+
78637881
#[test]
78647882
fn pattern_match_on_clause_variable_with_label() {
78657883
assert_code_action!(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
source: language-server/src/tests/action.rs
3+
expression: "\npub fn main() {\n let outcome = apply(#(Ok(1), Nil), fn(pair) {\n let #(result, nil) = pair\n })\n}\n\nfn apply(a, f) { f(a) }\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
pub fn main() {
8+
let outcome = apply(#(Ok(1), Nil), fn(pair) {
9+
let #(result, nil) = pair
10+
11+
})
12+
}
13+
14+
fn apply(a, f) { f(a) }
15+
16+
17+
----- AFTER ACTION
18+
19+
pub fn main() {
20+
let outcome = apply(#(Ok(1), Nil), fn(pair) {
21+
let #(result, nil) = pair
22+
case result {
23+
Ok(value) -> todo
24+
Error(value) -> todo
25+
}
26+
})
27+
}
28+
29+
fn apply(a, f) { f(a) }

0 commit comments

Comments
 (0)