mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-10-05 15:57:08 +03:00
Fix entry point reimports to give an error
This commit is contained in:
parent
4814742247
commit
53ca86848d
@ -6,7 +6,7 @@ use crate::{
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig},
|
||||
imports::PackageLoader,
|
||||
};
|
||||
use std::{fmt::Display, path::Path};
|
||||
use std::path::Path;
|
||||
|
||||
// TODO: Refactor so that we don't mix the two syntaxes here.
|
||||
|
||||
@ -17,11 +17,11 @@ pub fn load_file_to_book(
|
||||
diag: DiagnosticsConfig,
|
||||
) -> Result<Book, Diagnostics> {
|
||||
let code = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
|
||||
load_to_book(path.display(), &code, package_loader, diag)
|
||||
load_to_book(path, &code, package_loader, diag)
|
||||
}
|
||||
|
||||
pub fn load_to_book<T: Display>(
|
||||
origin: T,
|
||||
pub fn load_to_book(
|
||||
origin: &Path,
|
||||
code: &str,
|
||||
package_loader: impl PackageLoader,
|
||||
diag: DiagnosticsConfig,
|
||||
@ -31,11 +31,11 @@ pub fn load_to_book<T: Display>(
|
||||
book.load_imports(package_loader, diag)
|
||||
}
|
||||
|
||||
pub fn do_parse_book<T: Display>(code: &str, origin: T, mut book: ParseBook) -> Result<ParseBook, String> {
|
||||
book.source = Name::new(format!("{origin}"));
|
||||
TermParser::new(code).parse_book(book, false).map_err(|e| format!("In {} :\n{}", origin, e))
|
||||
pub fn do_parse_book(code: &str, origin: &Path, mut book: ParseBook) -> Result<ParseBook, String> {
|
||||
book.source = Name::new(origin.to_string_lossy());
|
||||
TermParser::new(code).parse_book(book, false).map_err(|e| format!("In {} :\n{}", origin.display(), e))
|
||||
}
|
||||
|
||||
pub fn do_parse_book_default<T: Display>(code: &str, origin: T) -> Result<Book, String> {
|
||||
pub fn do_parse_book_default(code: &str, origin: &Path) -> Result<Book, String> {
|
||||
do_parse_book(code, origin, ParseBook::builtins())?.to_fun()
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::fun::Name;
|
||||
use indexmap::IndexMap;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
path::{Path, PathBuf},
|
||||
path::{Component, Path, PathBuf},
|
||||
};
|
||||
|
||||
pub type Sources = IndexMap<Name, String>;
|
||||
@ -40,23 +40,33 @@ pub trait PackageLoader {
|
||||
pub struct DefaultLoader {
|
||||
local_path: PathBuf,
|
||||
loaded: HashSet<Name>,
|
||||
entrypoint: Name,
|
||||
}
|
||||
|
||||
impl DefaultLoader {
|
||||
pub fn new(local_path: &Path) -> Self {
|
||||
let entrypoint = Name::new(local_path.file_stem().unwrap().to_string_lossy());
|
||||
let local_path = local_path.parent().unwrap().to_path_buf();
|
||||
Self { local_path, loaded: HashSet::new() }
|
||||
Self { local_path, loaded: HashSet::new(), entrypoint }
|
||||
}
|
||||
|
||||
fn read_file(&mut self, path: &Path, file: Name, src: &mut Sources) -> Option<Name> {
|
||||
if !self.is_loaded(&file) {
|
||||
self.loaded.insert(file.clone());
|
||||
fn read_file(&mut self, path: &Path, file_path: &str, src: &mut Sources) -> Result<Option<Name>, String> {
|
||||
let normalized = normalize_path(&PathBuf::from(file_path));
|
||||
let file_path = Name::new(normalized.to_string_lossy());
|
||||
|
||||
if self.entrypoint == file_path {
|
||||
return Err("Can not import the entry point of the program.".to_string());
|
||||
};
|
||||
|
||||
if !self.is_loaded(&file_path) {
|
||||
self.loaded.insert(file_path.clone());
|
||||
|
||||
let path = path.with_extension("bend");
|
||||
let code = std::fs::read_to_string(path).ok()?;
|
||||
src.insert(file.clone(), code);
|
||||
let Some(code) = std::fs::read_to_string(path).ok() else { return Ok(None) };
|
||||
src.insert(file_path.clone(), code);
|
||||
}
|
||||
Some(file)
|
||||
|
||||
Ok(Some(file_path))
|
||||
}
|
||||
|
||||
fn read_file_in_folder(
|
||||
@ -65,11 +75,15 @@ impl DefaultLoader {
|
||||
folder: &str,
|
||||
file_name: &str,
|
||||
src: &mut Sources,
|
||||
) -> Option<Name> {
|
||||
let file_path = Name::new(format!("{}/{}", folder, file_name));
|
||||
) -> Result<Option<Name>, String> {
|
||||
let full_path = full_path.join(file_name);
|
||||
|
||||
self.read_file(&full_path, file_path, src)
|
||||
if folder.is_empty() {
|
||||
self.read_file(&full_path, file_name, src)
|
||||
} else {
|
||||
let file_name = &format!("{}/{}", folder, file_name);
|
||||
self.read_file(&full_path, file_name, src)
|
||||
}
|
||||
}
|
||||
|
||||
fn read_path(
|
||||
@ -77,12 +91,12 @@ impl DefaultLoader {
|
||||
base_path: &Path,
|
||||
path: &Name,
|
||||
imp_type: &ImportType,
|
||||
) -> Option<(BoundSource, Sources)> {
|
||||
) -> Result<Option<(BoundSource, Sources)>, String> {
|
||||
let full_path = base_path.join(path.as_ref());
|
||||
let mut src = IndexMap::new();
|
||||
|
||||
let file = if full_path.with_extension("bend").is_file() {
|
||||
self.read_file(&full_path, path.clone(), &mut src)
|
||||
self.read_file(&full_path, path.as_ref(), &mut src)?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -92,13 +106,13 @@ impl DefaultLoader {
|
||||
|
||||
match imp_type {
|
||||
ImportType::Single(file, _) => {
|
||||
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src) {
|
||||
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src)? {
|
||||
names.insert(file.clone(), name);
|
||||
}
|
||||
}
|
||||
ImportType::List(list) => {
|
||||
for (file, _) in list {
|
||||
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src) {
|
||||
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src)? {
|
||||
names.insert(file.clone(), name);
|
||||
}
|
||||
}
|
||||
@ -109,7 +123,7 @@ impl DefaultLoader {
|
||||
|
||||
if let Some("bend") = file.extension().and_then(|f| f.to_str()) {
|
||||
let file = file.file_stem().unwrap().to_string_lossy();
|
||||
if let Some(name) = self.read_file_in_folder(&full_path, path, &file, &mut src) {
|
||||
if let Some(name) = self.read_file_in_folder(&full_path, path, &file, &mut src)? {
|
||||
names.insert(Name::new(file), name);
|
||||
}
|
||||
}
|
||||
@ -126,12 +140,14 @@ impl DefaultLoader {
|
||||
None
|
||||
};
|
||||
|
||||
match (file, dir) {
|
||||
let src = match (file, dir) {
|
||||
(Some(f), None) => Some((BoundSource::File(f), src)),
|
||||
(None, Some(d)) => Some((BoundSource::Dir(d), src)),
|
||||
(Some(f), Some(d)) => Some((BoundSource::Either(f, d), src)),
|
||||
(None, None) => None,
|
||||
}
|
||||
};
|
||||
|
||||
Ok(src)
|
||||
}
|
||||
|
||||
fn is_loaded(&self, name: &Name) -> bool {
|
||||
@ -154,7 +170,7 @@ impl PackageLoader for DefaultLoader {
|
||||
};
|
||||
|
||||
for base in folders {
|
||||
let Some((names, new_pkgs)) = self.read_path(&base, path, imp_type) else { continue };
|
||||
let Some((names, new_pkgs)) = self.read_path(&base, path, imp_type)? else { continue };
|
||||
|
||||
*src = names;
|
||||
sources.extend(new_pkgs);
|
||||
@ -168,3 +184,31 @@ impl PackageLoader for DefaultLoader {
|
||||
Ok(sources)
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from 'cargo/util/paths.rs'
|
||||
pub fn normalize_path(path: &Path) -> PathBuf {
|
||||
let mut components = path.components().peekable();
|
||||
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
|
||||
components.next();
|
||||
PathBuf::from(c.as_os_str())
|
||||
} else {
|
||||
PathBuf::new()
|
||||
};
|
||||
|
||||
for component in components {
|
||||
match component {
|
||||
Component::Prefix(..) => unreachable!(),
|
||||
Component::RootDir => {
|
||||
ret.push(component.as_os_str());
|
||||
}
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
ret.pop();
|
||||
}
|
||||
Component::Normal(c) => {
|
||||
ret.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
use super::{loader::PackageLoader, BoundSource, ImportCtx, ImportType, ImportsMap};
|
||||
use super::{loader::PackageLoader, normalize_path, BoundSource, ImportCtx, ImportType, ImportsMap};
|
||||
use crate::{
|
||||
diagnostics::Diagnostics,
|
||||
fun::{load_book::do_parse_book, parser::ParseBook, Name},
|
||||
};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::VecDeque,
|
||||
path::{Component, Path, PathBuf},
|
||||
};
|
||||
use std::{cell::RefCell, collections::VecDeque, path::PathBuf};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Packages {
|
||||
@ -23,7 +19,7 @@ pub struct Packages {
|
||||
impl Packages {
|
||||
pub fn new(book: ParseBook) -> Self {
|
||||
Self {
|
||||
books: IndexMap::from([(Name::default(), book.into())]),
|
||||
books: IndexMap::from([(book.source.clone(), book.into())]),
|
||||
load_queue: VecDeque::new(),
|
||||
loaded_adts: IndexMap::new(),
|
||||
}
|
||||
@ -84,7 +80,7 @@ impl Packages {
|
||||
}
|
||||
|
||||
for (psrc, code) in sources {
|
||||
let module = do_parse_book(&code, &psrc, ParseBook::default())?;
|
||||
let module = do_parse_book(&code, &PathBuf::from(psrc.as_ref()), ParseBook::default())?;
|
||||
self.load_queue.push_back(self.books.len());
|
||||
self.books.insert(psrc, module.into());
|
||||
}
|
||||
@ -239,31 +235,3 @@ impl Packages {
|
||||
bound_book.top_level_names().cloned().collect()
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from 'cargo/util/paths.rs'
|
||||
fn normalize_path(path: &Path) -> PathBuf {
|
||||
let mut components = path.components().peekable();
|
||||
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
|
||||
components.next();
|
||||
PathBuf::from(c.as_os_str())
|
||||
} else {
|
||||
PathBuf::new()
|
||||
};
|
||||
|
||||
for component in components {
|
||||
match component {
|
||||
Component::Prefix(..) => unreachable!(),
|
||||
Component::RootDir => {
|
||||
ret.push(component.as_os_str());
|
||||
}
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
ret.pop();
|
||||
}
|
||||
Component::Normal(c) => {
|
||||
ret.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ pub fn run_book_simple(
|
||||
#[test]
|
||||
fn compile_file() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let compile_opts = CompileOpts::default();
|
||||
let diagnostics_cfg = DiagnosticsConfig { unused_definition: Severity::Allow, ..Default::default() };
|
||||
|
||||
@ -119,7 +119,7 @@ fn compile_file() {
|
||||
#[test]
|
||||
fn compile_file_o_all() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let opts = CompileOpts::default().set_all();
|
||||
let diagnostics_cfg = DiagnosticsConfig {
|
||||
recursion_cycle: Severity::Warning,
|
||||
@ -135,7 +135,7 @@ fn compile_file_o_all() {
|
||||
#[test]
|
||||
fn compile_file_o_no_all() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let compile_opts = CompileOpts::default().set_no_all();
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let res = compile_book(&mut book, compile_opts, diagnostics_cfg, None)?;
|
||||
@ -147,7 +147,7 @@ fn compile_file_o_no_all() {
|
||||
fn linear_readback() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let _guard = RUN_MUTEX.lock().unwrap();
|
||||
let book = do_parse_book_default(code, path.display())?;
|
||||
let book = do_parse_book_default(code, path)?;
|
||||
let compile_opts = CompileOpts::default().set_all();
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let (term, _, diags) = run_book_simple(
|
||||
@ -168,7 +168,7 @@ fn run_file() {
|
||||
function_name!(),
|
||||
&[(&|code, path| {
|
||||
let _guard = RUN_MUTEX.lock().unwrap();
|
||||
let book = do_parse_book_default(code, path.display())?;
|
||||
let book = do_parse_book_default(code, path)?;
|
||||
let diagnostics_cfg = DiagnosticsConfig {
|
||||
unused_definition: Severity::Allow,
|
||||
..DiagnosticsConfig::new(Severity::Error, true)
|
||||
@ -199,7 +199,7 @@ fn import_system() {
|
||||
..DiagnosticsConfig::new(Severity::Error, true)
|
||||
};
|
||||
|
||||
let book = load_to_book(path.display(), code, DefaultLoader::new(path), diagnostics_cfg)?;
|
||||
let book = load_to_book(path, code, DefaultLoader::new(path), diagnostics_cfg)?;
|
||||
let run_opts = RunOpts::default();
|
||||
|
||||
let mut res = String::new();
|
||||
@ -253,7 +253,7 @@ fn simplify_matches() {
|
||||
irrefutable_match: Severity::Allow,
|
||||
..DiagnosticsConfig::new(Severity::Error, true)
|
||||
};
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
||||
|
||||
ctx.check_shared_names();
|
||||
@ -286,7 +286,7 @@ fn simplify_matches() {
|
||||
#[test]
|
||||
fn parse_file() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let mut ctx = Ctx::new(&mut book, Default::default());
|
||||
ctx.set_entrypoint();
|
||||
ctx.book.encode_adts(AdtEncoding::NumScott);
|
||||
@ -304,7 +304,7 @@ fn encode_pattern_match() {
|
||||
let mut result = String::new();
|
||||
for adt_encoding in [AdtEncoding::Scott, AdtEncoding::NumScott] {
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
||||
ctx.check_shared_names();
|
||||
ctx.set_entrypoint();
|
||||
@ -345,7 +345,7 @@ fn desugar_file() {
|
||||
unused_definition: Severity::Allow,
|
||||
..DiagnosticsConfig::new(Severity::Error, true)
|
||||
};
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
desugar_book(&mut book, compile_opts, diagnostics_cfg, None)?;
|
||||
Ok(book.to_string())
|
||||
})
|
||||
@ -358,7 +358,7 @@ fn hangs() {
|
||||
|
||||
run_golden_test_dir(function_name!(), &move |code, path| {
|
||||
let _guard = RUN_MUTEX.lock().unwrap();
|
||||
let book = do_parse_book_default(code, path.display())?;
|
||||
let book = do_parse_book_default(code, path)?;
|
||||
let compile_opts = CompileOpts::default().set_all();
|
||||
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Allow, false);
|
||||
|
||||
@ -380,7 +380,7 @@ fn hangs() {
|
||||
#[test]
|
||||
fn compile_entrypoint() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
book.entrypoint = Some(Name::new("foo"));
|
||||
let diagnostics_cfg = DiagnosticsConfig { ..DiagnosticsConfig::new(Severity::Error, true) };
|
||||
let res = compile_book(&mut book, CompileOpts::default(), diagnostics_cfg, None)?;
|
||||
@ -393,7 +393,7 @@ fn compile_entrypoint() {
|
||||
fn run_entrypoint() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let _guard = RUN_MUTEX.lock().unwrap();
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
book.entrypoint = Some(Name::new("foo"));
|
||||
let compile_opts = CompileOpts::default().set_all();
|
||||
let diagnostics_cfg = DiagnosticsConfig { ..DiagnosticsConfig::new(Severity::Error, true) };
|
||||
@ -428,7 +428,7 @@ fn mutual_recursion() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let diagnostics_cfg =
|
||||
DiagnosticsConfig { recursion_cycle: Severity::Error, ..DiagnosticsConfig::new(Severity::Allow, true) };
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let opts = CompileOpts { merge: true, ..CompileOpts::default() };
|
||||
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
||||
Ok(format!("{}{}", res.diagnostics, hvm_book_show_pretty(&res.hvm_book)))
|
||||
@ -455,7 +455,7 @@ fn io() {
|
||||
}), */
|
||||
(&|code, path| {
|
||||
let _guard = RUN_MUTEX.lock().unwrap();
|
||||
let book = do_parse_book_default(code, path.display())?;
|
||||
let book = do_parse_book_default(code, path)?;
|
||||
let compile_opts = CompileOpts::default();
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let (term, _, diags) =
|
||||
@ -482,7 +482,7 @@ fn examples() -> Result<(), Diagnostics> {
|
||||
eprintln!("Testing {}", path.display());
|
||||
let code = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
|
||||
|
||||
let book = do_parse_book_default(&code, path.display()).unwrap();
|
||||
let book = do_parse_book_default(&code, path).unwrap();
|
||||
let compile_opts = CompileOpts::default();
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let (term, _, diags) = run_book_simple(book, RunOpts::default(), compile_opts, diagnostics_cfg, None)?;
|
||||
@ -504,7 +504,7 @@ fn examples() -> Result<(), Diagnostics> {
|
||||
#[test]
|
||||
fn scott_triggers_unused() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let opts = CompileOpts::default();
|
||||
let diagnostics_cfg =
|
||||
DiagnosticsConfig { unused_definition: Severity::Error, ..DiagnosticsConfig::default() };
|
||||
@ -517,7 +517,7 @@ fn scott_triggers_unused() {
|
||||
#[test]
|
||||
fn compile_long() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut book = do_parse_book_default(code, path.display())?;
|
||||
let mut book = do_parse_book_default(code, path)?;
|
||||
let opts = CompileOpts::default().set_all();
|
||||
let diagnostics_cfg = DiagnosticsConfig {
|
||||
recursion_cycle: Severity::Warning,
|
||||
|
4
tests/golden_tests/import_system/import_main.bend
Normal file
4
tests/golden_tests/import_system/import_main.bend
Normal file
@ -0,0 +1,4 @@
|
||||
import lib/import_entry
|
||||
|
||||
def main():
|
||||
return *
|
4
tests/golden_tests/import_system/import_main2.bend
Normal file
4
tests/golden_tests/import_system/import_main2.bend
Normal file
@ -0,0 +1,4 @@
|
||||
import lib/import_entry2
|
||||
|
||||
def main():
|
||||
return *
|
4
tests/golden_tests/import_system/import_main3.bend
Normal file
4
tests/golden_tests/import_system/import_main3.bend
Normal file
@ -0,0 +1,4 @@
|
||||
import lib/folder/import_entry3
|
||||
|
||||
def main():
|
||||
return *
|
@ -0,0 +1 @@
|
||||
import ../../../../import_main3 # multiples ../ have no effect past the main file folder
|
1
tests/golden_tests/import_system/lib/import_entry.bend
Normal file
1
tests/golden_tests/import_system/lib/import_entry.bend
Normal file
@ -0,0 +1 @@
|
||||
import import_main
|
1
tests/golden_tests/import_system/lib/import_entry2.bend
Normal file
1
tests/golden_tests/import_system/lib/import_entry2.bend
Normal file
@ -0,0 +1 @@
|
||||
import ../import_main2
|
6
tests/snapshots/import_system__import_main.bend.snap
Normal file
6
tests/snapshots/import_system__import_main.bend.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/import_system/import_main.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
Can not import the entry point of the program.
|
6
tests/snapshots/import_system__import_main2.bend.snap
Normal file
6
tests/snapshots/import_system__import_main2.bend.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/import_system/import_main2.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
Can not import the entry point of the program.
|
6
tests/snapshots/import_system__import_main3.bend.snap
Normal file
6
tests/snapshots/import_system__import_main3.bend.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/import_system/import_main3.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
Can not import the entry point of the program.
|
Loading…
Reference in New Issue
Block a user