Merge branch 'main' into roc-dev-report-status

This commit is contained in:
Anton-4 2023-10-10 20:04:57 +02:00 committed by GitHub
commit ac13ce57c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
845 changed files with 59689 additions and 51567 deletions

View file

@ -93,18 +93,18 @@ pub fn format(files: std::vec::Vec<PathBuf>, mode: FormatMode) -> Result<(), Str
// the PartialEq implementation is returning `false` even when the Debug-formatted impl is exactly the same.
// I don't have the patience to debug this right now, so let's leave it for another day...
// TODO: fix PartialEq impl on ast types
if format!("{:?}", ast_normalized) != format!("{:?}", reparsed_ast_normalized) {
if format!("{ast_normalized:?}") != format!("{reparsed_ast_normalized:?}") {
let mut fail_file = file.clone();
fail_file.set_extension("roc-format-failed");
std::fs::write(&fail_file, buf.as_str()).unwrap();
let mut before_file = file.clone();
before_file.set_extension("roc-format-failed-ast-before");
std::fs::write(&before_file, format!("{:#?}\n", ast_normalized)).unwrap();
std::fs::write(&before_file, format!("{ast_normalized:#?}\n")).unwrap();
let mut after_file = file.clone();
after_file.set_extension("roc-format-failed-ast-after");
std::fs::write(&after_file, format!("{:#?}\n", reparsed_ast_normalized)).unwrap();
std::fs::write(&after_file, format!("{reparsed_ast_normalized:#?}\n")).unwrap();
internal_error!(
"Formatting bug; formatting didn't reparse as the same tree\n\n\

View file

@ -20,6 +20,7 @@ use roc_load::{ExpectMetadata, Threading};
use roc_mono::ir::OptLevel;
use roc_packaging::cache::RocCacheDir;
use roc_packaging::tarball::Compression;
use roc_target::Target;
use std::env;
use std::ffi::{CString, OsStr, OsString};
use std::io;
@ -28,11 +29,8 @@ use std::os::raw::{c_char, c_int};
use std::path::{Path, PathBuf};
use std::process;
use std::time::Instant;
use strum::{EnumIter, IntoEnumIterator, IntoStaticStr};
use target_lexicon::BinaryFormat;
use target_lexicon::{
Architecture, Environment, OperatingSystem, Triple, Vendor, X86_32Architecture,
};
use strum::IntoEnumIterator;
use target_lexicon::{Architecture, Triple};
#[cfg(not(target_os = "linux"))]
use tempfile::TempDir;
@ -43,7 +41,6 @@ pub const CMD_BUILD: &str = "build";
pub const CMD_RUN: &str = "run";
pub const CMD_DEV: &str = "dev";
pub const CMD_REPL: &str = "repl";
pub const CMD_EDIT: &str = "edit";
pub const CMD_DOCS: &str = "docs";
pub const CMD_CHECK: &str = "check";
pub const CMD_VERSION: &str = "version";
@ -144,7 +141,8 @@ pub fn build_app() -> Command {
let build_target_values_parser =
PossibleValuesParser::new(Target::iter().map(Into::<&'static str>::into));
let app = Command::new("roc")
Command::new("roc")
.version(concatcp!(VERSION, "\n"))
.about("Run the given .roc file, if there are no compilation errors.\nYou can use one of the SUBCOMMANDS below to do something else!")
.args_conflicts_with_subcommands(true)
@ -334,23 +332,7 @@ pub fn build_app() -> Command {
.arg(flag_linker)
.arg(flag_prebuilt)
.arg(roc_file_to_run)
.arg(args_for_app.trailing_var_arg(true));
if cfg!(feature = "editor") {
app.subcommand(
Command::new(CMD_EDIT)
.about("Launch the Roc editor (Work In Progress)")
.arg(
Arg::new(DIRECTORY_OR_FILES)
.num_args(0..)
.required(false)
.value_parser(value_parser!(OsString))
.help("(optional) The directory or files to open on launch"),
),
)
} else {
app
}
.arg(args_for_app.trailing_var_arg(true))
}
#[derive(Debug, PartialEq, Eq)]
@ -387,7 +369,7 @@ pub fn test(_matches: &ArgMatches, _triple: Triple) -> io::Result<i32> {
#[cfg(not(windows))]
pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
use roc_build::program::report_problems_monomorphized;
use roc_load::{ExecutionMode, LoadConfig, LoadMonomorphizedError};
use roc_load::{ExecutionMode, FunctionKind, LoadConfig, LoadMonomorphizedError};
use roc_packaging::cache;
use roc_target::TargetInfo;
@ -416,12 +398,10 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
match matches.value_source(ROC_FILE) {
Some(ValueSource::DefaultValue) => {
eprintln!(
"\nThe current directory ({}) does not contain a {} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n",
current_dir_string,
DEFAULT_ROC_FILENAME
"\nThe current directory ({current_dir_string}) does not contain a {DEFAULT_ROC_FILENAME} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n"
)
}
_ => eprintln!("\nThis file was not found: {}\n\nYou can run `roc help` for more information on how to provide a .roc file.\n", expected_file_path_string),
_ => eprintln!("\nThis file was not found: {expected_file_path_string}\n\nYou can run `roc help` for more information on how to provide a .roc file.\n"),
}
process::exit(1);
@ -431,10 +411,13 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
let target = &triple;
let opt_level = opt_level;
let target_info = TargetInfo::from(target);
// TODO may need to determine this dynamically based on dev builds.
let function_kind = FunctionKind::LambdaSet;
// Step 1: compile the app and generate the .o file
let load_config = LoadConfig {
target_info,
function_kind,
// TODO: expose this from CLI?
render: roc_reporting::report::RenderTarget::ColorTerminal,
palette: roc_reporting::report::DEFAULT_PALETTE,
@ -565,16 +548,13 @@ pub fn build(
match matches.value_source(ROC_FILE) {
Some(ValueSource::DefaultValue) => {
eprintln!(
"\nThe current directory ({}) does not contain a {} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n",
current_dir_string,
DEFAULT_ROC_FILENAME
"\nThe current directory ({current_dir_string}) does not contain a {DEFAULT_ROC_FILENAME} file to use as a default.\n\nYou can run `roc help` for more information on how to provide a .roc file.\n"
)
}
_ => {
let mut error_lines = Vec::new();
error_lines.push(format!(
"This file was not found: {}",
expected_file_path_string
"This file was not found: {expected_file_path_string}"
));
// Add some additional hints if run as `roc [FILENAME]`.
if matches.subcommand().is_none() {
@ -584,8 +564,7 @@ pub fn build(
nearest_match(possible_typo, subcommands)
{
error_lines.push(format!(
"Did you mean to use the {} subcommand?",
nearest_command
"Did you mean to use the {nearest_command} subcommand?"
));
}
}
@ -1150,7 +1129,7 @@ fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<Executab
);
}
let path = PathBuf::from(format!("/proc/self/fd/{}", fd));
let path = PathBuf::from(format!("/proc/self/fd/{fd}"));
std::fs::write(&path, binary_bytes)?;
@ -1183,7 +1162,7 @@ fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<Executab
Ok(ExecutableFile::OnDisk(temp_dir, app_path_buf))
}
#[cfg(all(target_family = "windows"))]
#[cfg(target_family = "windows")]
fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<ExecutableFile> {
use std::fs::OpenOptions;
use std::io::Write;
@ -1281,83 +1260,3 @@ fn run_wasm<I: Iterator<Item = S>, S: AsRef<[u8]>>(wasm_path: &std::path::Path,
fn run_wasm<I: Iterator<Item = S>, S: AsRef<[u8]>>(_wasm_path: &std::path::Path, _args: I) {
println!("Running wasm files is not supported on this target.");
}
#[derive(Debug, Copy, Clone, EnumIter, IntoStaticStr, PartialEq, Eq, Default)]
pub enum Target {
#[strum(serialize = "system")]
#[default]
System,
#[strum(serialize = "linux32")]
Linux32,
#[strum(serialize = "linux64")]
Linux64,
#[strum(serialize = "windows64")]
Windows64,
#[strum(serialize = "wasm32")]
Wasm32,
}
impl Target {
pub fn to_triple(self) -> Triple {
use Target::*;
match self {
System => Triple::host(),
Linux32 => Triple {
architecture: Architecture::X86_32(X86_32Architecture::I386),
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Linux,
environment: Environment::Musl,
binary_format: BinaryFormat::Elf,
},
Linux64 => Triple {
architecture: Architecture::X86_64,
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Linux,
environment: Environment::Musl,
binary_format: BinaryFormat::Elf,
},
Windows64 => Triple {
architecture: Architecture::X86_64,
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Windows,
environment: Environment::Gnu,
binary_format: BinaryFormat::Coff,
},
Wasm32 => Triple {
architecture: Architecture::Wasm32,
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Wasi,
environment: Environment::Unknown,
binary_format: BinaryFormat::Wasm,
},
}
}
}
impl From<&Target> for Triple {
fn from(target: &Target) -> Self {
target.to_triple()
}
}
impl std::fmt::Display for Target {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", Into::<&'static str>::into(self))
}
}
impl std::str::FromStr for Target {
type Err = String;
fn from_str(string: &str) -> Result<Self, Self::Err> {
match string {
"system" => Ok(Target::System),
"linux32" => Ok(Target::Linux32),
"linux64" => Ok(Target::Linux64),
"windows64" => Ok(Target::Windows64),
"wasm32" => Ok(Target::Wasm32),
_ => Err(format!("Roc does not know how to compile to {}", string)),
}
}
}

View file

@ -2,17 +2,18 @@
use roc_build::link::LinkType;
use roc_build::program::{check_file, CodeGenBackend};
use roc_cli::{
build_app, format, test, BuildConfig, FormatMode, Target, CMD_BUILD, CMD_CHECK, CMD_DEV,
CMD_DOCS, CMD_EDIT, CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_REPL, CMD_RUN, CMD_TEST,
CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_NO_LINK, FLAG_TARGET,
FLAG_TIME, GLUE_DIR, GLUE_SPEC, ROC_FILE,
build_app, format, test, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK, CMD_DEV, CMD_DOCS,
CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_REPL, CMD_RUN, CMD_TEST, CMD_VERSION,
DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_NO_LINK, FLAG_TARGET, FLAG_TIME,
GLUE_DIR, GLUE_SPEC, ROC_FILE,
};
use roc_docs::generate_docs_html;
use roc_error_macros::user_error;
use roc_gen_dev::AssemblyBackendMode;
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_load::{LoadingProblem, Threading};
use roc_load::{FunctionKind, LoadingProblem, Threading};
use roc_packaging::cache::{self, RocCacheDir};
use roc_target::Target;
use std::fs::{self, FileType};
use std::io;
use std::path::{Path, PathBuf};
@ -51,9 +52,7 @@ fn main() -> io::Result<()> {
LinkType::Executable,
)
} else {
launch_editor(None)?;
Ok(0)
Ok(1)
}
}
Some((CMD_RUN, matches)) => {
@ -122,10 +121,12 @@ fn main() -> io::Result<()> {
.get_one::<String>(FLAG_TARGET)
.and_then(|s| Target::from_str(s).ok())
.unwrap_or_default();
let function_kind = FunctionKind::LambdaSet;
roc_linker::generate_stub_lib(
input_path,
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
&target.to_triple(),
function_kind,
)
}
Some((CMD_BUILD, matches)) => {
@ -200,32 +201,16 @@ fn main() -> io::Result<()> {
}
Err(LoadingProblem::FormattedReport(report)) => {
print!("{}", report);
print!("{report}");
Ok(1)
}
Err(other) => {
panic!("build_file failed with error:\n{:?}", other);
panic!("build_file failed with error:\n{other:?}");
}
}
}
Some((CMD_REPL, _)) => Ok(roc_repl_cli::main()),
Some((CMD_EDIT, matches)) => {
match matches
.get_many::<OsString>(DIRECTORY_OR_FILES)
.map(|mut values| values.next())
{
Some(Some(os_string)) => {
launch_editor(Some(Path::new(os_string)))?;
}
_ => {
launch_editor(None)?;
}
}
// Exit 0 if the editor exited normally
Ok(0)
}
Some((CMD_DOCS, matches)) => {
let root_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
@ -272,7 +257,7 @@ fn main() -> io::Result<()> {
let format_exit_code = match format(roc_files, format_mode) {
Ok(_) => 0,
Err(message) => {
eprintln!("{}", message);
eprintln!("{message}");
1
}
};
@ -330,13 +315,3 @@ fn roc_files_recursive<P: AsRef<Path>>(
Ok(())
}
#[cfg(feature = "editor")]
fn launch_editor(project_dir_path: Option<&Path>) -> io::Result<()> {
roc_editor::launch(project_dir_path)
}
#[cfg(not(feature = "editor"))]
fn launch_editor(_project_dir_path: Option<&Path>) -> io::Result<()> {
panic!("Cannot launch the editor because this build of roc did not include `feature = \"editor\"`!");
}