Skip to content

Commit

Permalink
check for needs_begin_end_wrapping instead of only checking for pipel…
Browse files Browse the repository at this point in the history
…ines when emiting single-statement blocks fix gleam-lang#4154
  • Loading branch information
joshi-monster committed Jan 8, 2025
1 parent 48e210e commit 59af3e0
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@
- Fixed a bug where build tool could fail to add new dependencies when
dependencies with optional dependencies are present in the manifest.
([Louis Pilfold](https://github.com/lpil))

- Fixed a bug where a block expression containing a singular record update would
produce invalid erlang.
([yoshi](https://github.com/joshi-monster))

7 changes: 0 additions & 7 deletions compiler-core/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2377,13 +2377,6 @@ impl TypedStatement {
}
}

pub fn is_non_pipe_expression(&self) -> bool {
match self {
Statement::Expression(expression) => !expression.is_pipeline(),
_ => false,
}
}

pub fn location(&self) -> SrcSpan {
match self {
Statement::Expression(expression) => expression.location(),
Expand Down
8 changes: 6 additions & 2 deletions compiler-core/src/erlang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,8 +944,12 @@ where
}

fn block<'a>(statements: &'a Vec1<TypedStatement>, env: &mut Env<'a>) -> Document<'a> {
if statements.len() == 1 && statements.first().is_non_pipe_expression() {
return docvec!['(', statement(statements.first(), env), ')'];
if statements.len() == 1 {
if let Statement::Expression(expression) = statements.first() {
if !needs_begin_end_wrapping(expression) {
return docvec!['(', expr(expression, env), ')'];
}
}
}

let vars = env.current_scope_vars.clone();
Expand Down
17 changes: 17 additions & 0 deletions compiler-core/src/erlang/tests/records.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,20 @@ pub fn main() {
}"
);
}

#[test]
fn nested_record_update_with_blocks() {
assert_erl!(
"pub type A { A(b: B) }
pub type B { B(c: C) }
pub type C { C(val: Int) }
pub fn main(a: A) {
A(..a, b: {
B(..a.b, c: {
C(..a.b.c, val: 0)
})
})
}"
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
source: compiler-core/src/erlang/tests/records.rs
expression: "pub type A { A(b: B) }\npub type B { B(c: C) }\npub type C { C(val: Int) }\n\npub fn main(a: A) {\n A(..a, b: {\n B(..a.b, c: {\n C(..a.b.c, val: 0)\n })\n })\n}"
---
----- SOURCE CODE
pub type A { A(b: B) }
pub type B { B(c: C) }
pub type C { C(val: Int) }

pub fn main(a: A) {
A(..a, b: {
B(..a.b, c: {
C(..a.b.c, val: 0)
})
})
}

----- COMPILED ERLANG
-module(my@mod).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).

-export([main/1]).
-export_type([a/0, b/0, c/0]).

-type a() :: {a, b()}.

-type b() :: {b, c()}.

-type c() :: {c, integer()}.

-file("/root/project/test/my/mod.gleam", 5).
-spec main(a()) -> a().
main(A) ->
_record = A,
{a,
begin
_record@1 = erlang:element(2, A),
{b,
begin
_record@2 = erlang:element(2, erlang:element(2, A)),
{c, 0}
end}
end}.

0 comments on commit 59af3e0

Please sign in to comment.