Skip to content

Commit 646e9bd

Browse files
Improve inlining tests
1 parent 739ab05 commit 646e9bd

9 files changed

+73
-47
lines changed

compiler-core/src/erlang/tests.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ mod type_params;
4141
mod use_;
4242
mod variables;
4343

44-
pub fn compile_test_project(src: &str, src_path: &str, dep: Option<(&str, &str, &str)>) -> String {
44+
pub fn compile_test_project(
45+
src: &str,
46+
src_path: &str,
47+
dependencies: Vec<(&str, &str, &str)>,
48+
) -> String {
4549
let mut modules = im::HashMap::new();
4650
let ids = UniqueIdGenerator::new();
4751
// DUPE: preludeinsertion
@@ -53,7 +57,7 @@ pub fn compile_test_project(src: &str, src_path: &str, dep: Option<(&str, &str,
5357
crate::type_::build_prelude(&ids),
5458
);
5559
let mut direct_dependencies = std::collections::HashMap::from_iter(vec![]);
56-
if let Some((dep_package, dep_name, dep_src)) = dep {
60+
for (dep_package, dep_name, dep_src) in dependencies {
5761
let mut dep_config = PackageConfig::default();
5862
dep_config.name = dep_package.into();
5963
let parsed = crate::parse::parse_module(
@@ -132,11 +136,11 @@ pub fn compile_test_project(src: &str, src_path: &str, dep: Option<(&str, &str,
132136

133137
#[macro_export]
134138
macro_rules! assert_erl {
135-
(($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{
139+
($(($dep_package:expr, $dep_name:expr, $dep_src:expr)),+, $src:literal $(,)?) => {{
136140
let compiled = $crate::erlang::tests::compile_test_project(
137141
$src,
138142
"/root/project/test/my/mod.gleam",
139-
Some(($dep_package, $dep_name, $dep_src)),
143+
vec![$(($dep_package, $dep_name, $dep_src)),*],
140144
);
141145
let output = format!(
142146
"----- SOURCE CODE\n{}\n\n----- COMPILED ERLANG\n{}",
@@ -149,7 +153,7 @@ macro_rules! assert_erl {
149153
let compiled = $crate::erlang::tests::compile_test_project(
150154
$src,
151155
"/root/project/test/my/mod.gleam",
152-
None,
156+
Vec::new(),
153157
);
154158
let output = format!(
155159
"----- SOURCE CODE\n{}\n\n----- COMPILED ERLANG\n{}",
@@ -988,7 +992,7 @@ pub fn main() {
988992
fn windows_file_escaping_bug() {
989993
let src = "pub fn main() { Nil }";
990994
let path = "C:\\root\\project\\test\\my\\mod.gleam";
991-
let output = compile_test_project(src, path, None);
995+
let output = compile_test_project(src, path, Vec::new());
992996
insta::assert_snapshot!(insta::internals::AutoName, output, src);
993997
}
994998

compiler-core/src/erlang/tests/inlining.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ pub fn try(result: Result(a, e), apply f: fn(a) -> Result(b, e)) -> Result(b, e)
3232
}
3333
}
3434
35-
pub fn then(result: Result(a, e), apply f: fn(a) -> Result(b, e)) -> Result(b, e) {
36-
try(result, f)
37-
}
38-
3935
pub fn map(over result: Result(a, e), with f: fn(a) -> b) -> Result(b, e) {
4036
case result {
4137
Ok(value) -> Ok(f(value))
@@ -99,15 +95,26 @@ pub fn main() {
9995

10096
#[test]
10197
fn inline_function_which_calls_other_function() {
102-
// `result.then` calls `result.try`, meaning this must be inlined twice to
98+
// This function calls `result.try`, meaning this must be inlined twice to
10399
// achieve the desired result.
104100
assert_erl!(
105101
("gleam_stdlib", "gleam/result", RESULT_MODULE),
102+
(
103+
"gleam_stdlib",
104+
"testing",
105+
"
106+
import gleam/result.{try}
107+
108+
pub fn always_inline(result, f) -> Result(b, e) {
109+
try(result, f)
110+
}
111+
"
112+
),
106113
"
107-
import gleam/result
114+
import testing
108115
109116
pub fn main() {
110-
result.then(Ok(10), Error)
117+
testing.always_inline(Ok(10), Error)
111118
}
112119
"
113120
);
@@ -161,13 +168,15 @@ pub fn count(from: Int, to: Int) -> Int {
161168

162169
#[test]
163170
fn do_not_inline_parameters_used_more_than_once() {
164-
// We just use `bool.guard` as the name here because it will be inlined
171+
// Since the `something` parameter is used more than once in the body of the
172+
// function, it should not be inlined, and should be assigned once at the
173+
// beginning of the function.
165174
assert_erl!(
166175
(
167176
"gleam_stdlib",
168-
"gleam/bool",
177+
"testing",
169178
"
170-
pub fn guard(something) {
179+
pub fn always_inline(something) {
171180
case something {
172181
True -> something
173182
False -> False
@@ -176,10 +185,10 @@ pub fn guard(something) {
176185
"
177186
),
178187
"
179-
import gleam/bool
188+
import testing
180189
181190
pub fn main() {
182-
bool.guard(True)
191+
testing.always_inline(True)
183192
}
184193
"
185194
);

compiler-core/src/erlang/tests/snapshots/gleam_core__erlang__tests__inlining__do_not_inline_parameters_used_more_than_once.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
source: compiler-core/src/erlang/tests/inlining.rs
3-
expression: "\nimport gleam/bool\n\npub fn main() {\n bool.guard(True)\n}\n"
3+
expression: "\nimport testing\n\npub fn main() {\n testing.always_inline(True)\n}\n"
44
---
55
----- SOURCE CODE
66

7-
import gleam/bool
7+
import testing
88

99
pub fn main() {
10-
bool.guard(True)
10+
testing.always_inline(True)
1111
}
1212

1313

compiler-core/src/erlang/tests/snapshots/gleam_core__erlang__tests__inlining__inline_function_which_calls_other_function.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
source: compiler-core/src/erlang/tests/inlining.rs
3-
expression: "\nimport gleam/result\n\npub fn main() {\n result.then(Ok(10), Error)\n}\n"
3+
expression: "\nimport testing\n\npub fn main() {\n testing.always_inline(Ok(10), Error)\n}\n"
44
---
55
----- SOURCE CODE
66

7-
import gleam/result
7+
import testing
88

99
pub fn main() {
10-
result.then(Ok(10), Error)
10+
testing.always_inline(Ok(10), Error)
1111
}
1212

1313

compiler-core/src/inline.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,8 +1159,12 @@ fn is_inlinable(package: &str, module: &str, name: &str) -> bool {
11591159
("gleam/bool", "guard") => true,
11601160
("gleam/bool", "lazy_guard") => true,
11611161
("gleam/result", "try") => true,
1162-
("gleam/result", "then") => true,
11631162
("gleam/result", "map") => true,
1163+
// For testing purposes it's useful to have a function which will always
1164+
// be inlined, which we can define however we want. We only inline this
1165+
// when we are in test mode though, because we wouldn't want this detail
1166+
// leaking out into real-world code and causing unexpected behaviour.
1167+
("testing", "always_inline") => cfg!(test),
11641168
_ => false,
11651169
}
11661170
}

compiler-core/src/javascript/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ macro_rules! assert_js {
5252
insta::assert_snapshot!(insta::internals::AutoName, output, $src);
5353
};
5454

55-
(($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{
55+
($(($dep_package:expr, $dep_name:expr, $dep_src:expr)),+, $src:literal $(,)?) => {{
5656
let compiled =
57-
$crate::javascript::tests::compile_js($src, vec![($dep_package, $dep_name, $dep_src)])
57+
$crate::javascript::tests::compile_js($src, vec![$(($dep_package, $dep_name, $dep_src)),*])
5858
.expect("compilation failed");
5959
let output = format!(
6060
"----- SOURCE CODE\n{}\n\n----- COMPILED JAVASCRIPT\n{}",

compiler-core/src/javascript/tests/inlining.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ pub fn try(result: Result(a, e), apply f: fn(a) -> Result(b, e)) -> Result(b, e)
3232
}
3333
}
3434
35-
pub fn then(result: Result(a, e), apply f: fn(a) -> Result(b, e)) -> Result(b, e) {
36-
try(result, f)
37-
}
38-
3935
pub fn map(over result: Result(a, e), with f: fn(a) -> b) -> Result(b, e) {
4036
case result {
4137
Ok(value) -> Ok(f(value))
@@ -99,15 +95,26 @@ pub fn main() {
9995

10096
#[test]
10197
fn inline_function_which_calls_other_function() {
102-
// `result.then` calls `result.try`, meaning this must be inlined twice to
98+
// This function calls `result.try`, meaning this must be inlined twice to
10399
// achieve the desired result.
104100
assert_js!(
105101
("gleam_stdlib", "gleam/result", RESULT_MODULE),
102+
(
103+
"gleam_stdlib",
104+
"testing",
105+
"
106+
import gleam/result.{try}
107+
108+
pub fn always_inline(result, f) -> Result(b, e) {
109+
try(result, f)
110+
}
111+
"
112+
),
106113
"
107-
import gleam/result
114+
import testing
108115
109116
pub fn main() {
110-
result.then(Ok(10), Error)
117+
testing.always_inline(Ok(10), Error)
111118
}
112119
"
113120
);
@@ -161,13 +168,15 @@ pub fn count(from: Int, to: Int) -> Int {
161168

162169
#[test]
163170
fn do_not_inline_parameters_used_more_than_once() {
164-
// We just use `bool.guard` as the name here because it will be inlined
171+
// Since the `something` parameter is used more than once in the body of the
172+
// function, it should not be inlined, and should be assigned once at the
173+
// beginning of the function.
165174
assert_js!(
166175
(
167176
"gleam_stdlib",
168-
"gleam/bool",
177+
"testing",
169178
"
170-
pub fn guard(something) {
179+
pub fn always_inline(something) {
171180
case something {
172181
True -> something
173182
False -> False
@@ -176,10 +185,10 @@ pub fn guard(something) {
176185
"
177186
),
178187
"
179-
import gleam/bool
188+
import testing
180189
181190
pub fn main() {
182-
bool.guard(True)
191+
testing.always_inline(True)
183192
}
184193
"
185194
);

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__inlining__do_not_inline_parameters_used_more_than_once.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
---
22
source: compiler-core/src/javascript/tests/inlining.rs
3-
expression: "\nimport gleam/bool\n\npub fn main() {\n bool.guard(True)\n}\n"
3+
expression: "\nimport testing\n\npub fn main() {\n testing.always_inline(True)\n}\n"
44
---
55
----- SOURCE CODE
66

7-
import gleam/bool
7+
import testing
88

99
pub fn main() {
10-
bool.guard(True)
10+
testing.always_inline(True)
1111
}
1212

1313

1414
----- COMPILED JAVASCRIPT
15-
import * as $bool from "../../gleam_stdlib/gleam/bool.mjs";
15+
import * as $testing from "../../gleam_stdlib/testing.mjs";
1616

1717
export function main() {
1818
{

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__inlining__inline_function_which_calls_other_function.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
---
22
source: compiler-core/src/javascript/tests/inlining.rs
3-
expression: "\nimport gleam/result\n\npub fn main() {\n result.then(Ok(10), Error)\n}\n"
3+
expression: "\nimport testing\n\npub fn main() {\n testing.always_inline(Ok(10), Error)\n}\n"
44
---
55
----- SOURCE CODE
66

7-
import gleam/result
7+
import testing
88

99
pub fn main() {
10-
result.then(Ok(10), Error)
10+
testing.always_inline(Ok(10), Error)
1111
}
1212

1313

1414
----- COMPILED JAVASCRIPT
15-
import * as $result from "../../gleam_stdlib/gleam/result.mjs";
15+
import * as $testing from "../../gleam_stdlib/testing.mjs";
1616
import { Ok, Error } from "../gleam.mjs";
1717

1818
export function main() {

0 commit comments

Comments
 (0)