mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 10:02:38 +03:00
Merge branch 'trunk' into singleton-to-single
This commit is contained in:
commit
1f29fc4358
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2895,6 +2895,7 @@ dependencies = [
|
||||
"roc_solve",
|
||||
"roc_types",
|
||||
"roc_unify",
|
||||
"serde_json",
|
||||
"target-lexicon",
|
||||
"tempfile",
|
||||
]
|
||||
|
@ -80,6 +80,7 @@ libloading = "0.6"
|
||||
# This way, GitHub Actions works and nobody's builds get broken.
|
||||
inkwell = { git = "https://github.com/rtfeldman/inkwell", tag = "llvm10-0.release3" }
|
||||
target-lexicon = "0.10"
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.5.1"
|
||||
|
@ -7,10 +7,11 @@ use roc_can::builtins::builtin_defs_map;
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_gen::llvm::build::OptLevel;
|
||||
use roc_load::file::LoadingProblem;
|
||||
use std::fs;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use target_lexicon::Triple;
|
||||
use tempfile::Builder;
|
||||
|
||||
fn report_timing(buf: &mut String, label: &str, duration: Duration) {
|
||||
buf.push_str(&format!(
|
||||
@ -52,8 +53,14 @@ pub fn build_file<'a>(
|
||||
)?;
|
||||
|
||||
let path_to_platform = loaded.platform_path.clone();
|
||||
|
||||
let app_o_file = roc_file_path.with_file_name("roc_app.o");
|
||||
let app_o_file = Builder::new()
|
||||
.prefix("roc_app")
|
||||
.suffix(".o")
|
||||
.tempfile()
|
||||
.map_err(|err| {
|
||||
todo!("TODO Gracefully handle tempfile creation error {:?}", err);
|
||||
})?;
|
||||
let app_o_file = app_o_file.path();
|
||||
let buf = &mut String::with_capacity(1024);
|
||||
|
||||
let mut it = loaded.timings.iter().peekable();
|
||||
@ -96,13 +103,12 @@ pub fn build_file<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
let cwd = app_o_file.parent().unwrap();
|
||||
let cwd = roc_file_path.parent().unwrap();
|
||||
let binary_path = cwd.join(&*loaded.output_path); // TODO should join ".exe" on Windows
|
||||
|
||||
let code_gen_timing = program::gen_from_mono_module(
|
||||
&arena,
|
||||
loaded,
|
||||
roc_file_path,
|
||||
&roc_file_path,
|
||||
Triple::host(),
|
||||
&app_o_file,
|
||||
opt_level,
|
||||
@ -119,16 +125,21 @@ pub fn build_file<'a>(
|
||||
|
||||
let compilation_end = compilation_start.elapsed().unwrap();
|
||||
|
||||
let size = std::fs::metadata(&app_o_file).unwrap().len();
|
||||
let size = std::fs::metadata(&app_o_file)
|
||||
.unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Could not open {:?} - which was supposed to have been generated. Error: {:?}",
|
||||
app_o_file, err
|
||||
);
|
||||
})
|
||||
.len();
|
||||
|
||||
if emit_debug_info {
|
||||
println!(
|
||||
"\n\nCompilation finished! Here's how long each module took to compile:\n\n{}",
|
||||
"\n\nCompilation finished!\n\nHere's how long each module took to compile:\n\n{}",
|
||||
buf
|
||||
);
|
||||
|
||||
println!("\nSuccess! 🎉\n\n\t➡ {}\n", app_o_file.display());
|
||||
|
||||
println!(
|
||||
"Finished compilation and code gen in {} ms\n\nProduced a app.o file of size {:?}\n",
|
||||
compilation_end.as_millis(),
|
||||
@ -138,6 +149,7 @@ pub fn build_file<'a>(
|
||||
|
||||
// Step 2: link the precompiled host and compiled app
|
||||
let mut host_input_path = PathBuf::from(cwd);
|
||||
|
||||
host_input_path.push(&*path_to_platform);
|
||||
host_input_path.push("host.o");
|
||||
|
||||
@ -161,7 +173,7 @@ pub fn build_file<'a>(
|
||||
link(
|
||||
target,
|
||||
binary_path,
|
||||
&[host_input_path.as_path().to_str().unwrap(), app_o_file.as_path().to_str().unwrap()],
|
||||
&[host_input_path.as_path().to_str().unwrap(), app_o_file.to_str().unwrap()],
|
||||
link_type
|
||||
)
|
||||
.map_err(|_| {
|
||||
@ -177,16 +189,21 @@ pub fn build_file<'a>(
|
||||
println!("Finished linking in {} ms\n", link_end.as_millis());
|
||||
}
|
||||
|
||||
// Clean up the leftover .o file from the Roc, if possible.
|
||||
// (If cleaning it up fails, that's fine. No need to take action.)
|
||||
// TODO compile the app_o_file to a tmpdir, as an extra precaution.
|
||||
let _ = fs::remove_file(app_o_file);
|
||||
|
||||
// If the cmd errored out, return the Err.
|
||||
cmd_result?;
|
||||
|
||||
// If possible, report the generated executable name relative to the current dir.
|
||||
let generated_filename = binary_path
|
||||
.strip_prefix(env::current_dir().unwrap())
|
||||
.unwrap_or(&binary_path);
|
||||
|
||||
let total_end = compilation_start.elapsed().unwrap();
|
||||
println!("Finished entire process in {} ms\n", total_end.as_millis());
|
||||
|
||||
println!(
|
||||
"🎉 Built {} in {} ms",
|
||||
generated_filename.to_str().unwrap(),
|
||||
total_end.as_millis()
|
||||
);
|
||||
|
||||
Ok(binary_path)
|
||||
}
|
||||
|
@ -18,6 +18,15 @@ mod cli_run {
|
||||
use serial_test::serial;
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const ALLOW_VALGRIND: bool = true;
|
||||
|
||||
// Disallow valgrind on macOS by default, because it reports a ton
|
||||
// of false positives. For local development on macOS, feel free to
|
||||
// change this to true!
|
||||
#[cfg(target_os = "macos")]
|
||||
const ALLOW_VALGRIND: bool = false;
|
||||
|
||||
fn check_output(
|
||||
file: &Path,
|
||||
executable_filename: &str,
|
||||
@ -49,7 +58,7 @@ mod cli_run {
|
||||
}
|
||||
assert!(compile_out.status.success());
|
||||
|
||||
let out = if use_valgrind {
|
||||
let out = if use_valgrind && ALLOW_VALGRIND {
|
||||
let (valgrind_out, raw_xml) = run_with_valgrind(
|
||||
stdin_str,
|
||||
&[file.with_file_name(executable_filename).to_str().unwrap()],
|
||||
|
@ -5,6 +5,21 @@ const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
|
||||
comptime {
|
||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||
// which is only necessary on macOS.
|
||||
//
|
||||
// Once that issue is fixed, we can undo the changes in
|
||||
// 177cf12e0555147faa4d436e52fc15175c2c4ff0 and go back to passing
|
||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||
// workaround is present in many host.zig files, so make sure to undo
|
||||
// it everywhere!
|
||||
|
||||
if (std.builtin.os.tag == .macos) {
|
||||
_ = @import("compiler_rt");
|
||||
}
|
||||
}
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
|
@ -5,6 +5,20 @@ const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
|
||||
comptime {
|
||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||
// which is only necessary on macOS.
|
||||
//
|
||||
// Once that issue is fixed, we can undo the changes in
|
||||
// 177cf12e0555147faa4d436e52fc15175c2c4ff0 and go back to passing
|
||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||
// workaround is present in many host.zig files, so make sure to undo
|
||||
// it everywhere!
|
||||
if (std.builtin.os.tag == .macos) {
|
||||
_ = @import("compiler_rt");
|
||||
}
|
||||
}
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
|
@ -27,6 +27,7 @@ bumpalo = { version = "3.2", features = ["collections"] }
|
||||
inlinable_string = "0.1.0"
|
||||
libloading = "0.6"
|
||||
tempfile = "3.1.0"
|
||||
serde_json = "1.0"
|
||||
# NOTE: rtfeldman/inkwell is a fork of TheDan64/inkwell which does not change anything.
|
||||
#
|
||||
# The reason for this fork is that the way Inkwell is designed, you have to use
|
||||
|
@ -55,6 +55,109 @@ fn find_zig_str_path() -> PathBuf {
|
||||
panic!("cannot find `str.zig`")
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn build_zig_host(
|
||||
env_path: &str,
|
||||
env_home: &str,
|
||||
emit_bin: &str,
|
||||
zig_host_src: &str,
|
||||
zig_str_path: &str,
|
||||
) -> Output {
|
||||
Command::new("zig")
|
||||
.env_clear()
|
||||
.env("PATH", env_path)
|
||||
.env("HOME", env_home)
|
||||
.args(&[
|
||||
"build-obj",
|
||||
zig_host_src,
|
||||
emit_bin,
|
||||
"--pkg-begin",
|
||||
"str",
|
||||
zig_str_path,
|
||||
"--pkg-end",
|
||||
// include the zig runtime
|
||||
"-fcompiler-rt",
|
||||
// include libc
|
||||
"--library",
|
||||
"c",
|
||||
])
|
||||
.output()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn build_zig_host(
|
||||
env_path: &str,
|
||||
env_home: &str,
|
||||
emit_bin: &str,
|
||||
zig_host_src: &str,
|
||||
zig_str_path: &str,
|
||||
) -> Output {
|
||||
use serde_json::Value;
|
||||
|
||||
// Run `zig env` to find the location of zig's std/ directory
|
||||
let zig_env_output = Command::new("zig").args(&["env"]).output().unwrap();
|
||||
|
||||
let zig_env_json = if zig_env_output.status.success() {
|
||||
std::str::from_utf8(&zig_env_output.stdout).unwrap_or_else(|utf8_err| {
|
||||
panic!(
|
||||
"`zig env` failed; its stderr output was invalid utf8 ({:?})",
|
||||
utf8_err
|
||||
);
|
||||
})
|
||||
} else {
|
||||
match std::str::from_utf8(&zig_env_output.stderr) {
|
||||
Ok(stderr) => panic!("`zig env` failed - stderr output was: {:?}", stderr),
|
||||
Err(utf8_err) => panic!(
|
||||
"`zig env` failed; its stderr output was invalid utf8 ({:?})",
|
||||
utf8_err
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
let mut zig_compiler_rt_path = match serde_json::from_str(zig_env_json) {
|
||||
Ok(Value::Object(map)) => match map.get("std_dir") {
|
||||
Some(Value::String(std_dir)) => PathBuf::from(Path::new(std_dir)),
|
||||
_ => {
|
||||
panic!("Expected JSON containing a `std_dir` String field from `zig env`, but got: {:?}", zig_env_json);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
panic!(
|
||||
"Expected JSON containing a `std_dir` field from `zig env`, but got: {:?}",
|
||||
zig_env_json
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
zig_compiler_rt_path.push("special");
|
||||
zig_compiler_rt_path.push("compiler_rt.zig");
|
||||
|
||||
Command::new("zig")
|
||||
.env_clear()
|
||||
.env("PATH", &env_path)
|
||||
.env("HOME", &env_home)
|
||||
.args(&[
|
||||
"build-obj",
|
||||
zig_host_src,
|
||||
&emit_bin,
|
||||
"--pkg-begin",
|
||||
"str",
|
||||
zig_str_path,
|
||||
"--pkg-end",
|
||||
// include the zig runtime
|
||||
"--pkg-begin",
|
||||
"compiler_rt",
|
||||
zig_compiler_rt_path.to_str().unwrap(),
|
||||
"--pkg-end",
|
||||
// include libc
|
||||
"--library",
|
||||
"c",
|
||||
])
|
||||
.output()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn rebuild_host(host_input_path: &Path) {
|
||||
let c_host_src = host_input_path.with_file_name("host.c");
|
||||
let c_host_dest = host_input_path.with_file_name("c_host.o");
|
||||
@ -79,28 +182,17 @@ pub fn rebuild_host(host_input_path: &Path) {
|
||||
&zig_str_path
|
||||
);
|
||||
|
||||
let output = Command::new("zig")
|
||||
.env_clear()
|
||||
.env("PATH", &env_path)
|
||||
.env("HOME", &env_home)
|
||||
.args(&[
|
||||
"build-obj",
|
||||
zig_host_src.to_str().unwrap(),
|
||||
validate_output(
|
||||
"host.zig",
|
||||
"zig",
|
||||
build_zig_host(
|
||||
&env_path,
|
||||
&env_home,
|
||||
&emit_bin,
|
||||
"--pkg-begin",
|
||||
"str",
|
||||
zig_host_src.to_str().unwrap(),
|
||||
zig_str_path.to_str().unwrap(),
|
||||
"--pkg-end",
|
||||
// include the zig runtime
|
||||
"-fcompiler-rt",
|
||||
// include libc
|
||||
"--library",
|
||||
"c",
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
validate_output("host.zig", "zig", output);
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Compile host.c
|
||||
let output = Command::new("clang")
|
||||
@ -351,7 +443,11 @@ fn link_macos(
|
||||
// Don't allow LD_ env vars to affect this
|
||||
.env_clear()
|
||||
.args(&[
|
||||
"--gc-sections",
|
||||
// NOTE: we don't do --gc-sections on macOS because the default
|
||||
// macOS linker doesn't support it, but it's a performance
|
||||
// optimization, so if we ever switch to a different linker,
|
||||
// we'd like to re-enable it on macOS!
|
||||
// "--gc-sections",
|
||||
link_type_arg,
|
||||
"-arch",
|
||||
target.architecture.to_string().as_str(),
|
||||
|
@ -23,7 +23,7 @@ pub struct CodeGenTiming {
|
||||
pub fn gen_from_mono_module(
|
||||
arena: &Bump,
|
||||
mut loaded: MonomorphizedModule,
|
||||
_file_path: PathBuf,
|
||||
roc_file_path: &Path,
|
||||
target: Triple,
|
||||
app_o_file: &Path,
|
||||
opt_level: OptLevel,
|
||||
@ -92,7 +92,7 @@ pub fn gen_from_mono_module(
|
||||
use inkwell::module::Linkage;
|
||||
|
||||
let app_ll_file = {
|
||||
let mut temp = std::path::PathBuf::from(app_o_file);
|
||||
let mut temp = PathBuf::from(roc_file_path);
|
||||
temp.set_extension("ll");
|
||||
|
||||
temp
|
||||
@ -215,10 +215,10 @@ pub fn gen_from_mono_module(
|
||||
if emit_debug_info {
|
||||
module.strip_debug_info();
|
||||
|
||||
let mut app_ll_dbg_file = std::path::PathBuf::from(app_o_file);
|
||||
let mut app_ll_dbg_file = PathBuf::from(roc_file_path);
|
||||
app_ll_dbg_file.set_extension("dbg.ll");
|
||||
|
||||
let mut app_bc_file = std::path::PathBuf::from(app_o_file);
|
||||
let mut app_bc_file = PathBuf::from(roc_file_path);
|
||||
app_bc_file.set_extension("bc");
|
||||
|
||||
use std::process::Command;
|
||||
|
@ -420,6 +420,9 @@ fn binop_to_function(binop: BinOp) -> (&'static str, &'static str) {
|
||||
And => (ModuleName::BOOL, "and"),
|
||||
Or => (ModuleName::BOOL, "or"),
|
||||
Pizza => unreachable!("Cannot desugar the |> operator"),
|
||||
Assignment => unreachable!("Cannot desugar the = operator"),
|
||||
HasType => unreachable!("Cannot desugar the : operator"),
|
||||
Backpassing => unreachable!("Cannot desugar the <- operator"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,6 +390,9 @@ fn fmt_bin_op<'a>(
|
||||
operator::BinOp::And => buf.push_str("&&"),
|
||||
operator::BinOp::Or => buf.push_str("||"),
|
||||
operator::BinOp::Pizza => buf.push_str("|>"),
|
||||
operator::BinOp::Assignment => unreachable!(),
|
||||
operator::BinOp::HasType => unreachable!(),
|
||||
operator::BinOp::Backpassing => unreachable!(),
|
||||
}
|
||||
|
||||
buf.push(' ');
|
||||
|
@ -42,6 +42,9 @@ pub enum BinOp {
|
||||
And,
|
||||
Or,
|
||||
Pizza, // lowest precedence
|
||||
Assignment,
|
||||
HasType,
|
||||
Backpassing,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@ -83,6 +86,7 @@ impl BinOp {
|
||||
Equals | NotEquals | LessThan | GreaterThan | LessThanOrEq | GreaterThanOrEq => {
|
||||
NonAssociative
|
||||
}
|
||||
Assignment | HasType | Backpassing => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +99,7 @@ impl BinOp {
|
||||
And => 3,
|
||||
Or => 2,
|
||||
Pizza => 1,
|
||||
Assignment | HasType | Backpassing => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,6 +136,9 @@ impl std::fmt::Display for BinOp {
|
||||
And => "&&",
|
||||
Or => "||",
|
||||
Pizza => "|>",
|
||||
Assignment => "=",
|
||||
HasType => ":",
|
||||
Backpassing => "<-",
|
||||
};
|
||||
|
||||
write!(f, "{}", as_str)
|
||||
|
@ -117,6 +117,22 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_indent<'a, E>(
|
||||
min_indent: u16,
|
||||
indent_problem: fn(Row, Col) -> E,
|
||||
) -> impl Parser<'a, (), E>
|
||||
where
|
||||
E: 'a,
|
||||
{
|
||||
move |_, state: State<'a>| {
|
||||
if state.column > min_indent {
|
||||
Ok((NoProgress, (), state))
|
||||
} else {
|
||||
Err((NoProgress, indent_problem(state.line, state.column), state))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn space0_e<'a, E>(
|
||||
min_indent: u16,
|
||||
space_problem: fn(BadInputError, Row, Col) -> E,
|
||||
@ -128,28 +144,6 @@ where
|
||||
spaces_help_help(min_indent, space_problem, indent_problem)
|
||||
}
|
||||
|
||||
pub fn space1_e<'a, E>(
|
||||
min_indent: u16,
|
||||
space_problem: fn(BadInputError, Row, Col) -> E,
|
||||
indent_problem: fn(Row, Col) -> E,
|
||||
no_parse_problem: fn(Row, Col) -> E,
|
||||
) -> impl Parser<'a, &'a [CommentOrNewline<'a>], E>
|
||||
where
|
||||
E: 'a,
|
||||
{
|
||||
move |arena, state| match space0_e(min_indent, space_problem, indent_problem)
|
||||
.parse(arena, state)
|
||||
{
|
||||
Ok((NoProgress, _, state)) => Err((
|
||||
NoProgress,
|
||||
no_parse_problem(state.line, state.column),
|
||||
state,
|
||||
)),
|
||||
Ok((MadeProgress, spaces, state)) => Ok((MadeProgress, spaces, state)),
|
||||
Err(bad) => Err(bad),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spaces_till_end_of_line<'a, E: 'a>(
|
||||
tab_problem: fn(Row, Col) -> E,
|
||||
) -> impl Parser<'a, Option<&'a str>, E> {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -254,7 +254,12 @@ fn end_of_file<'a>() -> impl Parser<'a, (), SyntaxError<'a>> {
|
||||
if state.has_reached_end() {
|
||||
Ok((NoProgress, (), state))
|
||||
} else {
|
||||
Err((NoProgress, SyntaxError::ConditionFailed, state))
|
||||
dbg!(state);
|
||||
Err((
|
||||
NoProgress,
|
||||
SyntaxError::NotEndOfFile(state.line, state.column),
|
||||
state,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,20 @@ pub enum NumLiteral<'a> {
|
||||
},
|
||||
}
|
||||
|
||||
pub fn positive_number_literal<'a>() -> impl Parser<'a, NumLiteral<'a>, Number> {
|
||||
move |_arena, state: State<'a>| {
|
||||
match state.bytes.get(0) {
|
||||
Some(first_byte) if (*first_byte as char).is_ascii_digit() => {
|
||||
parse_number_base(false, &state.bytes, state)
|
||||
}
|
||||
_ => {
|
||||
// this is not a number at all
|
||||
Err((Progress::NoProgress, Number::End, state))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn number_literal<'a>() -> impl Parser<'a, NumLiteral<'a>, Number> {
|
||||
move |_arena, state: State<'a>| {
|
||||
match state.bytes.get(0) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use bumpalo::collections::vec::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_region::all::{Located, Position, Region};
|
||||
use std::fmt;
|
||||
use Progress::*;
|
||||
|
||||
@ -37,7 +37,15 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
/// Returns whether the parser has reached the end of the input
|
||||
pub fn has_reached_end(&self) -> bool {
|
||||
pub const fn get_position(&self) -> Position {
|
||||
Position {
|
||||
row: self.line,
|
||||
col: self.column,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the parser has reached the end of the input
|
||||
pub const fn has_reached_end(&self) -> bool {
|
||||
self.bytes.is_empty()
|
||||
}
|
||||
|
||||
@ -183,6 +191,7 @@ pub enum SyntaxError<'a> {
|
||||
Expr(EExpr<'a>),
|
||||
Header(EHeader<'a>),
|
||||
Space(BadInputError),
|
||||
NotEndOfFile(Row, Col),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -640,6 +640,33 @@ mod test_parse {
|
||||
assert_eq!(Ok(expected), actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn newline_and_spaces_before_less_than() {
|
||||
let arena = Bump::new();
|
||||
let spaced_int = arena.alloc(Num("1")).after(&[Newline]);
|
||||
let tuple = arena.alloc((
|
||||
Located::new(0, 0, 4, 5, spaced_int),
|
||||
Located::new(1, 1, 4, 5, LessThan),
|
||||
Located::new(1, 1, 6, 7, Num("2")),
|
||||
));
|
||||
|
||||
let newlines = bumpalo::vec![in &arena; Newline, Newline];
|
||||
let def = Def::Body(
|
||||
arena.alloc(Located::new(0, 0, 0, 1, Identifier("x"))),
|
||||
arena.alloc(Located::new(0, 1, 4, 7, BinOp(tuple))),
|
||||
);
|
||||
let loc_def = &*arena.alloc(Located::new(0, 1, 0, 7, def));
|
||||
let defs = &[loc_def];
|
||||
let ret = Expr::SpaceBefore(arena.alloc(Num("42")), newlines.into_bump_slice());
|
||||
let loc_ret = Located::new(3, 3, 0, 2, ret);
|
||||
let expected = Defs(defs, arena.alloc(loc_ret));
|
||||
|
||||
// let expected = BinOp(tuple);
|
||||
let actual = parse_expr_with(&arena, "x = 1\n < 2\n\n42");
|
||||
|
||||
assert_eq!(Ok(expected), actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn comment_with_non_ascii() {
|
||||
let arena = Bump::new();
|
||||
@ -1314,21 +1341,18 @@ mod test_parse {
|
||||
},
|
||||
));
|
||||
let args = &[&*arg1, &*arg2];
|
||||
let apply_expr = Expr::Apply(
|
||||
arena.alloc(Located::new(
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
},
|
||||
)),
|
||||
args,
|
||||
CalledVia::Space,
|
||||
let function = Located::new(
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
},
|
||||
);
|
||||
let expected = UnaryOp(arena.alloc(Located::new(0, 0, 1, 13, apply_expr)), loc_op);
|
||||
let unary = Located::new(0, 0, 0, 5, UnaryOp(arena.alloc(function), loc_op));
|
||||
let expected = Expr::Apply(arena.alloc(unary), args, CalledVia::Space);
|
||||
let actual = parse_expr_with(&arena, "-whee 12 foo");
|
||||
|
||||
assert_eq!(Ok(expected), actual);
|
||||
@ -1350,21 +1374,19 @@ mod test_parse {
|
||||
},
|
||||
));
|
||||
let args = &[&*arg1, &*arg2];
|
||||
let apply_expr = Expr::Apply(
|
||||
arena.alloc(Located::new(
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
},
|
||||
)),
|
||||
args,
|
||||
CalledVia::Space,
|
||||
|
||||
let function = Located::new(
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
},
|
||||
);
|
||||
let expected = UnaryOp(arena.alloc(Located::new(0, 0, 1, 13, apply_expr)), loc_op);
|
||||
let unary = Located::new(0, 0, 0, 5, UnaryOp(arena.alloc(function), loc_op));
|
||||
let expected = Expr::Apply(arena.alloc(unary), args, CalledVia::Space);
|
||||
let actual = parse_expr_with(&arena, "!whee 12 foo");
|
||||
|
||||
assert_eq!(Ok(expected), actual);
|
||||
@ -1400,7 +1422,7 @@ mod test_parse {
|
||||
args,
|
||||
CalledVia::Space,
|
||||
)));
|
||||
let expected = UnaryOp(arena.alloc(Located::new(0, 0, 1, 15, apply_expr)), loc_op);
|
||||
let expected = UnaryOp(arena.alloc(Located::new(0, 0, 2, 14, apply_expr)), loc_op);
|
||||
let actual = parse_expr_with(&arena, "-(whee 12 foo)");
|
||||
|
||||
assert_eq!(Ok(expected), actual);
|
||||
@ -1436,7 +1458,7 @@ mod test_parse {
|
||||
args,
|
||||
CalledVia::Space,
|
||||
)));
|
||||
let expected = UnaryOp(arena.alloc(Located::new(0, 0, 1, 15, apply_expr)), loc_op);
|
||||
let expected = UnaryOp(arena.alloc(Located::new(0, 0, 2, 14, apply_expr)), loc_op);
|
||||
let actual = parse_expr_with(&arena, "!(whee 12 foo)");
|
||||
|
||||
assert_eq!(Ok(expected), actual);
|
||||
|
@ -3,7 +3,7 @@ use std::fmt;
|
||||
/// TODO replace Located with this
|
||||
pub type Loc<T> = Located<T>;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct Region {
|
||||
pub start_line: u32,
|
||||
pub end_line: u32,
|
||||
@ -107,6 +107,20 @@ impl Region {
|
||||
end_line,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn start(&self) -> Position {
|
||||
Position {
|
||||
row: self.start_line,
|
||||
col: self.start_col,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn end(&self) -> Position {
|
||||
Position {
|
||||
row: self.end_line,
|
||||
col: self.end_col,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -132,6 +146,12 @@ impl fmt::Debug for Region {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct Position {
|
||||
pub row: u32,
|
||||
pub col: u16,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub struct Located<T> {
|
||||
pub region: Region,
|
||||
|
@ -125,6 +125,22 @@ fn to_syntax_report<'a>(
|
||||
|
||||
report(doc)
|
||||
}
|
||||
NotEndOfFile(row, col) => {
|
||||
let surroundings = Region::from_rows_cols(start_row, start_col, *row, *col);
|
||||
let region = Region::from_row_col(*row, *col);
|
||||
|
||||
let doc = alloc.stack(vec![
|
||||
alloc.reflow(r"I expected to reach the end of the file, but got stuck here:"),
|
||||
alloc.region_with_subregion(surroundings, region),
|
||||
alloc.concat(vec![alloc.reflow("no hints")]),
|
||||
]);
|
||||
|
||||
Report {
|
||||
filename,
|
||||
doc,
|
||||
title: "NOT END OF FILE".to_string(),
|
||||
}
|
||||
}
|
||||
SyntaxError::Eof(region) => {
|
||||
let doc = alloc.stack(vec![alloc.reflow("End of Field"), alloc.region(*region)]);
|
||||
|
||||
@ -393,7 +409,7 @@ fn to_expr_report<'a>(
|
||||
alloc.vcat(vec![
|
||||
alloc.text("x = 4").indent(4),
|
||||
alloc.text("y = 2").indent(4),
|
||||
alloc.text("").indent(4),
|
||||
alloc.text(""),
|
||||
alloc.text("x + y").indent(4),
|
||||
]),
|
||||
]);
|
||||
@ -2702,7 +2718,7 @@ fn to_provides_report<'a>(
|
||||
.reflow(r"I am partway through parsing a provides list, but I got stuck here:"),
|
||||
alloc.region_with_subregion(surroundings, region),
|
||||
alloc.concat(vec![alloc.reflow(
|
||||
"I was expecting a type name, value name or function name next, like ",
|
||||
"I was expecting a type name, value name or function name next, like",
|
||||
)]),
|
||||
alloc
|
||||
.parser_suggestion("provides [ Animal, default, tame ]")
|
||||
@ -2764,7 +2780,7 @@ fn to_exposes_report<'a>(
|
||||
alloc.reflow(r"I am partway through parsing a exposes list, but I got stuck here:"),
|
||||
alloc.region_with_subregion(surroundings, region),
|
||||
alloc.concat(vec![alloc.reflow(
|
||||
"I was expecting a type name, value name or function name next, like ",
|
||||
"I was expecting a type name, value name or function name next, like",
|
||||
)]),
|
||||
alloc
|
||||
.parser_suggestion("exposes [ Animal, default, tame ]")
|
||||
|
@ -65,6 +65,7 @@ mod test_reporting {
|
||||
problems: can_problems,
|
||||
..
|
||||
} = can_expr(arena, expr_src)?;
|
||||
dbg!(&loc_expr);
|
||||
let mut subs = Subs::new(var_store.into());
|
||||
|
||||
for (var, name) in output.introduced_variables.name_by_var {
|
||||
@ -4124,12 +4125,12 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I trying to parse a record field access here:
|
||||
|
||||
|
||||
1│ foo.bar.
|
||||
^
|
||||
|
||||
|
||||
So I expect to see a lowercase letter next, like .name or .height.
|
||||
"#
|
||||
),
|
||||
@ -4147,12 +4148,12 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am very confused by this expression:
|
||||
|
||||
|
||||
1│ @Foo.Bar
|
||||
^^^^
|
||||
|
||||
|
||||
Looks like a private tag is treated like a module name. Maybe you
|
||||
wanted a qualified name, like Json.Decode.string?
|
||||
"#
|
||||
@ -4199,18 +4200,18 @@ mod test_reporting {
|
||||
x == 5
|
||||
Num.add 1 2
|
||||
|
||||
x y
|
||||
{ x, y }
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
||||
|
||||
The `add` function expects 2 arguments, but it got 4 instead:
|
||||
|
||||
4│ Num.add 1 2
|
||||
^^^^^^^
|
||||
|
||||
|
||||
This value is not a function, but it was given 3 arguments:
|
||||
|
||||
3│ x == 5
|
||||
^
|
||||
|
||||
Are there any missing commas? Or missing parentheses?
|
||||
"#
|
||||
),
|
||||
@ -4679,18 +4680,18 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── MISSING FINAL EXPRESSION ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a definition, but I got stuck here:
|
||||
|
||||
|
||||
1│ f : Foo.foo
|
||||
^
|
||||
|
||||
|
||||
This definition is missing a final expression. A nested definition
|
||||
must be followed by either another definition, or an expression
|
||||
|
||||
|
||||
x = 4
|
||||
y = 2
|
||||
|
||||
|
||||
x + y
|
||||
"#
|
||||
),
|
||||
@ -5055,13 +5056,13 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── UNFINISHED ARGUMENT LIST ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a function argument list, but I got stuck
|
||||
at this comma:
|
||||
|
||||
|
||||
1│ \a,,b -> 1
|
||||
^
|
||||
|
||||
|
||||
I was expecting an argument pattern before this, so try adding an
|
||||
argument before the comma and see if that helps?
|
||||
"#
|
||||
@ -5080,13 +5081,13 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── UNFINISHED ARGUMENT LIST ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a function argument list, but I got stuck
|
||||
at this comma:
|
||||
|
||||
|
||||
1│ \,b -> 1
|
||||
^
|
||||
|
||||
|
||||
I was expecting an argument pattern before this, so try adding an
|
||||
argument before the comma and see if that helps?
|
||||
"#
|
||||
@ -5488,12 +5489,12 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I trying to parse a record field access here:
|
||||
|
||||
|
||||
1│ Num.add . 23
|
||||
^
|
||||
|
||||
|
||||
So I expect to see a lowercase letter next, like .name or .height.
|
||||
"#
|
||||
),
|
||||
@ -5727,22 +5728,24 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
main =
|
||||
5 : I64
|
||||
(\x -> x) : I64
|
||||
|
||||
3
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
This looks like an operator, but it's not one I recognize!
|
||||
|
||||
|
||||
1│ main =
|
||||
2│ 5 : I64
|
||||
^
|
||||
|
||||
2│ (\x -> x) : I64
|
||||
^
|
||||
|
||||
The has-type operator : can only occur in a definition's type
|
||||
signature, like
|
||||
|
||||
|
||||
increment : I64 -> I64
|
||||
increment = \x -> x + 1
|
||||
"#
|
||||
@ -5789,15 +5792,15 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── WEIRD PROVIDES ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a provides list, but I got stuck here:
|
||||
|
||||
|
||||
3│ imports [base.Task, Base64 ]
|
||||
4│ provides [ main, @Foo ] to base
|
||||
^
|
||||
|
||||
I was expecting a type name, value name or function name next, like
|
||||
|
||||
|
||||
I was expecting a type name, value name or function name next, like
|
||||
|
||||
provides [ Animal, default, tame ]
|
||||
"#
|
||||
),
|
||||
@ -5809,7 +5812,7 @@ mod test_reporting {
|
||||
report_header_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
interface Foobar
|
||||
interface Foobar
|
||||
exposes [ main, @Foo ]
|
||||
imports [base.Task, Base64 ]
|
||||
"#
|
||||
@ -5817,15 +5820,15 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── WEIRD EXPOSES ───────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a exposes list, but I got stuck here:
|
||||
|
||||
1│ interface Foobar
|
||||
|
||||
1│ interface Foobar
|
||||
2│ exposes [ main, @Foo ]
|
||||
^
|
||||
|
||||
I was expecting a type name, value name or function name next, like
|
||||
|
||||
|
||||
I was expecting a type name, value name or function name next, like
|
||||
|
||||
exposes [ Animal, default, tame ]
|
||||
"#
|
||||
),
|
||||
@ -5837,7 +5840,7 @@ mod test_reporting {
|
||||
report_header_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
interface foobar
|
||||
interface foobar
|
||||
exposes [ main, @Foo ]
|
||||
imports [base.Task, Base64 ]
|
||||
"#
|
||||
@ -5845,12 +5848,12 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── WEIRD MODULE NAME ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a header, but got stuck here:
|
||||
|
||||
1│ interface foobar
|
||||
|
||||
1│ interface foobar
|
||||
^
|
||||
|
||||
|
||||
I am expecting a module name next, like BigNum or Main. Module names
|
||||
must start with an uppercase letter.
|
||||
"#
|
||||
@ -5863,7 +5866,7 @@ mod test_reporting {
|
||||
report_header_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
app foobar
|
||||
app foobar
|
||||
exposes [ main, @Foo ]
|
||||
imports [base.Task, Base64 ]
|
||||
"#
|
||||
@ -5871,16 +5874,66 @@ mod test_reporting {
|
||||
indoc!(
|
||||
r#"
|
||||
── WEIRD APP NAME ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
I am partway through parsing a header, but got stuck here:
|
||||
|
||||
1│ app foobar
|
||||
|
||||
1│ app foobar
|
||||
^
|
||||
|
||||
|
||||
I am expecting an application name next, like app "main" or
|
||||
app "editor". App names are surrounded by quotation marks.
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_unary_negative() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
foo = 3
|
||||
|
||||
-foo 1 2
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
||||
|
||||
This value is not a function, but it was given 2 arguments:
|
||||
|
||||
3│ -foo 1 2
|
||||
^^^^
|
||||
|
||||
Are there any missing commas? Or missing parentheses?
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_unary_not() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
foo = True
|
||||
|
||||
!foo 1 2
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
||||
|
||||
This value is not a function, but it was given 2 arguments:
|
||||
|
||||
3│ !foo 1 2
|
||||
^^^^
|
||||
|
||||
Are there any missing commas? Or missing parentheses?
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -738,7 +738,9 @@ fn list_repeat() {
|
||||
RocList<i64>
|
||||
);
|
||||
|
||||
assert_evals_to!("List.repeat 2 []", &[&[], &[]], &'static [&'static [i64]]);
|
||||
let empty_lists: &'static [&'static [i64]] = &[&[], &[]];
|
||||
|
||||
assert_evals_to!("List.repeat 2 []", empty_lists, &'static [&'static [i64]]);
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
@ -749,7 +751,7 @@ fn list_repeat() {
|
||||
List.repeat 2 noStrs
|
||||
"#
|
||||
),
|
||||
&[&[], &[]],
|
||||
empty_lists,
|
||||
&'static [&'static [i64]]
|
||||
);
|
||||
|
||||
|
@ -196,6 +196,8 @@ fn contains() {
|
||||
|
||||
#[test]
|
||||
fn from_list() {
|
||||
let empty_list: &'static [i64] = &[];
|
||||
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
@ -216,7 +218,7 @@ fn from_list() {
|
||||
|> Set.toList
|
||||
"#
|
||||
),
|
||||
&[],
|
||||
empty_list,
|
||||
&[i64]
|
||||
);
|
||||
|
||||
@ -231,7 +233,7 @@ fn from_list() {
|
||||
|> Set.toList
|
||||
"#
|
||||
),
|
||||
&[],
|
||||
empty_list,
|
||||
&[i64]
|
||||
);
|
||||
}
|
||||
|
4
examples/.gitignore
vendored
4
examples/.gitignore
vendored
@ -8,4 +8,8 @@ benchmarks/nqueens
|
||||
benchmarks/deriv
|
||||
benchmarks/cfold
|
||||
benchmarks/rbtree-insert
|
||||
benchmarks/rbtree-del
|
||||
benchmarks/closure
|
||||
benchmarks/test-astar
|
||||
benchmarks/test-base64
|
||||
effect-example
|
||||
|
Binary file not shown.
@ -6,6 +6,20 @@ const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
const maxInt = std.math.maxInt;
|
||||
|
||||
comptime {
|
||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||
// which is only necessary on macOS.
|
||||
//
|
||||
// Once that issue is fixed, we can undo the changes in
|
||||
// 177cf12e0555147faa4d436e52fc15175c2c4ff0 and go back to passing
|
||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||
// workaround is present in many host.zig files, so make sure to undo
|
||||
// it everywhere!
|
||||
if (std.builtin.os.tag == .macos) {
|
||||
_ = @import("compiler_rt");
|
||||
}
|
||||
}
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,6 +5,20 @@ const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
|
||||
comptime {
|
||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||
// which is only necessary on macOS.
|
||||
//
|
||||
// Once that issue is fixed, we can undo the changes in
|
||||
// 177cf12e0555147faa4d436e52fc15175c2c4ff0 and go back to passing
|
||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||
// workaround is present in many host.zig files, so make sure to undo
|
||||
// it everywhere!
|
||||
if (std.builtin.os.tag == .macos) {
|
||||
_ = @import("compiler_rt");
|
||||
}
|
||||
}
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
|
@ -3,6 +3,20 @@ const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
|
||||
comptime {
|
||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||
// which is only necessary on macOS.
|
||||
//
|
||||
// Once that issue is fixed, we can undo the changes in
|
||||
// 177cf12e0555147faa4d436e52fc15175c2c4ff0 and go back to passing
|
||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||
// workaround is present in many host.zig files, so make sure to undo
|
||||
// it everywhere!
|
||||
if (std.builtin.os.tag == .macos) {
|
||||
_ = @import("compiler_rt");
|
||||
}
|
||||
}
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
|
@ -5,6 +5,20 @@ const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
|
||||
comptime {
|
||||
// This is a workaround for https://github.com/ziglang/zig/issues/8218
|
||||
// which is only necessary on macOS.
|
||||
//
|
||||
// Once that issue is fixed, we can undo the changes in
|
||||
// 177cf12e0555147faa4d436e52fc15175c2c4ff0 and go back to passing
|
||||
// -fcompiler-rt in link.rs instead of doing this. Note that this
|
||||
// workaround is present in many host.zig files, so make sure to undo
|
||||
// it everywhere!
|
||||
if (std.builtin.os.tag == .macos) {
|
||||
_ = @import("compiler_rt");
|
||||
}
|
||||
}
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user