Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Gleam 1.3 JS fixes to Nix #13

Merged
merged 4 commits into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion compiler-core/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,13 @@ impl<'a> Nix<'a> {
"builtins.import {}\n",
nix::syntax::path(self.prelude_location.as_str())
);
writer.write(&self.output_directory.join("gleam.nix"), &rexport)?;
let prelude_path = &self.output_directory.join("gleam.nix");

// This check skips unnecessary `gleam.nix` writes which confuse
// watchers
if !writer.exists(prelude_path) {
writer.write(prelude_path, &rexport)?;
}

Ok(())
}
Expand Down
31 changes: 28 additions & 3 deletions compiler-core/src/nix/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,20 @@ impl Generator<'_> {

// Sized ints
[BitArrayOption::Size { value: size, .. }] => {
let size_int = match *size.clone() {
TypedExpr::Int {
location: _,
typ: _,
value,
} => value.parse().unwrap_or(0),
_ => 0,
};
if size_int > 0 && size_int % 8 != 0 {
return Err(Error::Unsupported {
feature: "Non byte aligned array".into(),
location: segment.location,
});
}
self.tracker.sized_integer_segment_used = true;
let size = self.wrap_child_expression(size)?;
Ok(docvec![
Expand Down Expand Up @@ -1285,10 +1299,11 @@ pub(crate) fn constant_expression<'a>(
Constant::Record { typ, .. } if typ.is_nil() => Ok("null".to_doc()),

Constant::Record {
tag,
typ,
args,
module,
name,
tag,
typ,
..
} => {
if typ.is_result() {
Expand All @@ -1303,7 +1318,7 @@ pub(crate) fn constant_expression<'a>(
.map(|arg| wrap_child_constant_expression(tracker, &arg.value))
.try_collect()?;

Ok(construct_record(module.as_deref(), tag, field_values))
Ok(construct_record(module.as_deref(), name, field_values))
}

Constant::BitArray { segments, .. } => {
Expand Down Expand Up @@ -1579,6 +1594,16 @@ fn constant_bit_array<'a>(

// Sized ints
[BitArrayOption::Size { value: size, .. }] => {
let size_int = match *size.clone() {
Constant::Int { location: _, value } => value.parse().unwrap_or(0),
_ => 0,
};
if size_int > 0 && size_int % 8 != 0 {
return Err(Error::Unsupported {
feature: "Non byte aligned array".into(),
location: segment.location,
});
}
tracker.sized_integer_segment_used = true;
let size = wrap_child_constant_expr_fun(tracker, size)?;
Ok(docvec![
Expand Down
1 change: 1 addition & 0 deletions compiler-core/src/nix/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod blocks;
mod bools;
mod case;
mod case_clause_guards;
mod consts;
mod custom_types;
mod externals;
mod functions;
Expand Down
56 changes: 54 additions & 2 deletions compiler-core/src/nix/tests/bit_arrays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn sized() {
assert_nix!(
r#"
fn go() {
<<256:4>>
<<256:64>>
}
"#,
);
Expand All @@ -71,7 +71,7 @@ fn explicit_sized() {
assert_nix!(
r#"
fn go() {
<<256:size(4)>>
<<256:size(64)>>
}
"#,
);
Expand Down Expand Up @@ -245,3 +245,55 @@ fn as_module_const() {
"#
)
}

#[test]
fn negative_size() {
assert_nix!(
r#"
fn go() {
<<1:size(-1)>>
}
"#,
);
}

// https://github.com/gleam-lang/gleam/issues/1591
#[test]
fn not_byte_aligned() {
assert_nix!(
r#"
fn thing() {
4
}
fn go() {
<<256:4>>
}
"#,
);
}

#[test]
fn not_byte_aligned_explicit_sized() {
assert_nix!(
r#"
fn go() {
<<256:size(4)>>
}
"#,
);
}

// This test would ideally also result in go() being deleted like the previous tests
// but we can not know for sure what the value of a variable is going to be
// so right now go() is not deleted.
#[test]
fn not_byte_aligned_variable() {
assert_nix!(
r#"
fn go() {
let x = 4
<<256:size(x)>>
}
"#,
);
}
34 changes: 34 additions & 0 deletions compiler-core/src/nix/tests/case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,37 @@ pub fn main() {
"#
)
}

// https://github.com/gleam-lang/gleam/issues/3379
#[test]
fn single_clause_variables() {
assert_nix!(
r#"
pub fn main() {
let text = "first defined"
case "defined again" {
text -> Nil
}
let text = "a third time"
Nil
}
"#
)
}

// https://github.com/gleam-lang/gleam/issues/3379
#[test]
fn single_clause_variables_assigned() {
assert_nix!(
r#"
pub fn main() {
let text = "first defined"
let other = case "defined again" {
text -> Nil
}
let text = "a third time"
Nil
}
"#
)
}
35 changes: 35 additions & 0 deletions compiler-core/src/nix/tests/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::assert_nix;

#[test]
fn custom_type_constructor_imported_and_aliased() {
assert_nix!(
("package", "other_module", "pub type T { A }"),
r#"import other_module.{A as B}
pub const local = B
"#,
);
}

#[test]
fn imported_aliased_ok() {
assert_nix!(
r#"import gleam.{Ok as Y}
pub type X {
Ok
}
pub const y = Y
"#,
);
}

#[test]
fn imported_ok() {
assert_nix!(
r#"import gleam
pub type X {
Ok
}
pub const y = gleam.Ok
"#,
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
source: compiler-core/src/nix/tests/bit_arrays.rs
expression: "\nfn go() {\n <<256:size(4)>>\n}\n"
expression: "\nfn go() {\n <<256:size(64)>>\n}\n"
---
let
inherit (builtins.import ./../gleam.nix) toBitArray sizedInt;

go = { }: toBitArray [ (sizedInt 256 4) ];
go = { }: toBitArray [ (sizedInt 256 64) ];
in
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: compiler-core/src/nix/tests/bit_arrays.rs
expression: "\nfn go() {\n <<1:size(-1)>>\n}\n"
---
let
inherit (builtins.import ./../gleam.nix) toBitArray sizedInt;

go = { }: toBitArray [ (sizedInt 1 (-1)) ];
in
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: compiler-core/src/nix/tests/bit_arrays.rs
expression: "\nfn thing() {\n 4\n}\nfn go() {\n <<256:4>>\n}\n"
---
let inherit (builtins.import ./../gleam.nix) toBitArray; thing = { }: 4; in { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: compiler-core/src/nix/tests/bit_arrays.rs
expression: "\nfn go() {\n <<256:size(4)>>\n}\n"
---
let inherit (builtins.import ./../gleam.nix) toBitArray; in { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: compiler-core/src/nix/tests/bit_arrays.rs
expression: "\nfn go() {\n let x = 4\n <<256:size(x)>>\n}\n"
---
let
inherit (builtins.import ./../gleam.nix) toBitArray sizedInt;

go = { }: let x = 4; in toBitArray [ (sizedInt 256 x) ];
in
{ }
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
source: compiler-core/src/nix/tests/bit_arrays.rs
expression: "\nfn go() {\n <<256:4>>\n}\n"
expression: "\nfn go() {\n <<256:64>>\n}\n"
---
let
inherit (builtins.import ./../gleam.nix) toBitArray sizedInt;

go = { }: toBitArray [ (sizedInt 256 4) ];
go = { }: toBitArray [ (sizedInt 256 64) ];
in
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: compiler-core/src/nix/tests/case.rs
expression: "\npub fn main() {\n let text = \"first defined\"\n case \"defined again\" {\n text -> Nil\n }\n let text = \"a third time\"\n Nil\n}\n"
---
let
main =
{ }:
let
text = "first defined";
_' = let _pat' = "defined again"; in let text'1 = _pat'; in null;
text'1 = "a third time";
in
builtins.seq _' null;
in
{ inherit main; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: compiler-core/src/nix/tests/case.rs
expression: "\npub fn main() {\n let text = \"first defined\"\n let other = case \"defined again\" {\n text -> Nil\n }\n let text = \"a third time\"\n Nil\n}\n"
---
let
main =
{ }:
let
text = "first defined";
other = let _pat' = "defined again"; in let text'1 = _pat'; in null;
text'1 = "a third time";
in
null;
in
{ inherit main; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: compiler-core/src/nix/tests/consts.rs
expression: "import other_module.{A as B}\npub const local = B\n"
---
let
other_module' = builtins.import ./../../package/other_module.nix;
B = (builtins.import ./../../package/other_module.nix).A;

local = B;
in
{ inherit local; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: compiler-core/src/nix/tests/consts.rs
expression: "import gleam.{Ok as Y}\npub type X {\n Ok\n}\npub const y = Y\n"
---
let
gleam' = builtins.import ./../gleam.nix;
Y = (builtins.import ./../gleam.nix).Ok;

Ok = { __gleamTag = "Ok"; };

y = Y;
in
{ inherit Ok y; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
source: compiler-core/src/nix/tests/consts.rs
expression: "import gleam\npub type X {\n Ok\n}\npub const y = gleam.Ok\n"
---
let
gleam' = builtins.import ./../gleam.nix;

Ok = { __gleamTag = "Ok"; };

y = gleam'.Ok;
in
{ inherit Ok y; }
Loading