diff --git a/compiler/constrain/src/module.rs b/compiler/constrain/src/module.rs index d116e1731a..15dc6d1c90 100644 --- a/compiler/constrain/src/module.rs +++ b/compiler/constrain/src/module.rs @@ -160,6 +160,53 @@ pub fn pre_constrain_imports( }); } None => { + if module_id == home { + continue; + } + + if module_id == ModuleId::RESULT { + let region = Region::zero(); // TODO this should be the region where this symbol was declared in its home module. Look that up! + let loc_symbol = Loc { + value: symbol, + region, + }; + + match exposed_types.get(&module_id) { + Some(ExposedModuleTypes::Valid(solved_types, new_aliases)) => { + // If the exposed value was invalid (e.g. it didn't have + // a corresponding definition), it won't have an entry + // in solved_types + if let Some(solved_type) = solved_types.get(&symbol) { + // TODO should this be a union? + for (k, v) in new_aliases.clone() { + imported_aliases.insert(k, v); + } + + imported_symbols.push(Import { + loc_symbol, + solved_type: solved_type.clone(), + }); + } + } + Some(ExposedModuleTypes::Invalid) => { + // If that module was invalid, use True constraints + // for everything imported from it. + imported_symbols.push(Import { + loc_symbol, + solved_type: SolvedType::Erroneous(Problem::InvalidModule), + }); + } + None => { + panic!( + "Could not find module {:?} in exposed_types {:?}", + module_id, exposed_types + ); + } + } + + continue; + } + let is_valid_alias = stdlib.applies.contains(&symbol) // This wasn't a builtin value or Apply; maybe it was a builtin alias. || roc_types::builtin_aliases::aliases().contains_key(&symbol); diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 5d5b2b7cba..a41e0ab502 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -74,6 +74,8 @@ macro_rules! log { ($($arg:tt)*) => (if SHOW_MESSAGE_LOG { println!($($arg)*); } else {}) } +const BUILTIN_MODULES: &[(ModuleId, &[ModuleId])] = &[(ModuleId::RESULT, &[])]; + /// Struct storing various intermediate stages by their ModuleId #[derive(Debug, Default)] struct ModuleCache<'a> { @@ -2259,8 +2261,105 @@ fn load_module<'a>( arc_shorthands: Arc>>>, ident_ids_by_module: Arc>>, ) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { + use PackageQualified::*; + let module_start_time = SystemTime::now(); + dbg!(&module_name); + + match module_name.as_inner().as_str() { + "Result" => { + let parse_start = SystemTime::now(); + let parse_header_duration = parse_start.elapsed().unwrap(); + + // Insert the first entries for this module's timings + let mut module_timing = ModuleTiming::new(module_start_time); + + module_timing.read_roc_file = Default::default(); + module_timing.parse_header = parse_header_duration; + + let filename = PathBuf::from("Result.roc"); + + const EXPOSES: &[Loc] = &[ + Loc::at_zero(ExposedName::new("Result")), + Loc::at_zero(ExposedName::new("isOk")), + Loc::at_zero(ExposedName::new("isErr")), + Loc::at_zero(ExposedName::new("map")), + Loc::at_zero(ExposedName::new("mapErr")), + Loc::at_zero(ExposedName::new("after")), + Loc::at_zero(ExposedName::new("withDefault")), + ]; + let imports = &[]; + + let info = HeaderInfo { + loc_name: Loc { + region: Region::zero(), + value: ModuleNameEnum::Interface(roc_parse::header::ModuleName::new("Result")), + }, + filename, + is_root_module: false, + opt_shorthand: None, + packages: &[], + exposes: &EXPOSES, + imports, + extra: HeaderFor::Interface, + }; + + let src_bytes = r#" + Result ok err : [ Ok ok, Err err ] + + isOk : Result ok err -> Bool + isOk = \result -> + when result is + Ok _ -> True + Err _ -> False + + isErr : Result ok err -> Bool + isErr = \result -> + when result is + Ok _ -> False + Err _ -> True + + withDefault : Result ok err, ok -> ok + withDefault = \result, default -> + when result is + Ok value -> value + Err _ -> default + + map : Result a err, (a -> b) -> Result b err + map = \result, transform -> + when result is + Ok v -> Ok (transform v) + Err e -> Err e + + mapErr : Result ok a, (a -> b) -> Result ok b + mapErr = \result, transform -> + when result is + Ok v -> Ok v + Err e -> Err (transform e) + + after : Result a err, (a -> Result b err) -> Result b err + after = \result, transform -> + when result is + Ok v -> transform v + Err e -> Err e + "#; + + let parse_state = roc_parse::state::State::new(src_bytes.as_bytes()); + + return Ok(send_header( + info, + parse_state, + module_ids, + ident_ids_by_module, + module_timing, + )); + } + _ => { + // fall through + } + } + let (filename, opt_shorthand) = module_name_to_path(src_dir, module_name, arc_shorthands); load_filename( diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 82778fa6d0..d2a39ba9d2 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -1143,7 +1143,7 @@ define_builtins! { 57 LIST_SORT_DESC_COMPARE: "#sortDescCompare" } 5 RESULT: "Result" => { - 0 RESULT_RESULT: "Result" imported // the Result.Result type alias + 0 RESULT_RESULT: "Result" // the Result.Result type alias 1 RESULT_OK: "Ok" imported // Result.Result a e = [ Ok a, Err e ] // NB: not strictly needed; used for finding global tag names in error suggestions 2 RESULT_ERR: "Err" imported // Result.Result a e = [ Ok a, Err e ] diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 300c4272ef..af8c66b7ac 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -1108,7 +1108,8 @@ impl<'a, 'i> Env<'a, 'i> { } pub fn is_imported_symbol(&self, symbol: Symbol) -> bool { - symbol.module_id() != self.home && !symbol.is_builtin() + // symbol.module_id() != self.home && !symbol.is_builtin() + symbol.module_id() != self.home } } diff --git a/compiler/parse/src/header.rs b/compiler/parse/src/header.rs index 1a1b301f9f..6a36590965 100644 --- a/compiler/parse/src/header.rs +++ b/compiler/parse/src/header.rs @@ -88,7 +88,7 @@ impl<'a> From> for &'a str { } impl<'a> ExposedName<'a> { - pub fn new(name: &'a str) -> Self { + pub const fn new(name: &'a str) -> Self { ExposedName(name) } diff --git a/compiler/region/src/all.rs b/compiler/region/src/all.rs index a22e325f60..e273cb2a10 100644 --- a/compiler/region/src/all.rs +++ b/compiler/region/src/all.rs @@ -279,16 +279,16 @@ pub struct Loc { } impl Loc { - pub fn new(start: u32, end: u32, value: T) -> Loc { + pub const fn new(start: u32, end: u32, value: T) -> Loc { let region = Region::new(Position::new(start), Position::new(end)); Loc { region, value } } - pub fn at(region: Region, value: T) -> Loc { + pub const fn at(region: Region, value: T) -> Loc { Loc { region, value } } - pub fn at_zero(value: T) -> Loc { + pub const fn at_zero(value: T) -> Loc { let region = Region::zero(); Loc { region, value } } diff --git a/compiler/types/src/builtin_aliases.rs b/compiler/types/src/builtin_aliases.rs index f8df53a256..fc09ae90ee 100644 --- a/compiler/types/src/builtin_aliases.rs +++ b/compiler/types/src/builtin_aliases.rs @@ -319,6 +319,7 @@ pub fn aliases() -> MutMap { }, ); + /* // Result ok err : [ Ok ok, Err err ] add_alias( Symbol::RESULT_RESULT, @@ -331,6 +332,7 @@ pub fn aliases() -> MutMap { typ: result_alias_content(flex(TVAR1), flex(TVAR2)), }, ); + */ // Utf8ByteProblem : [ InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf ] add_alias(