Wrap opaque types in the repl with the appropriate opaque wrapper

Closes #3504
This commit is contained in:
Ayaz Hafiz 2022-07-13 17:45:13 -04:00
parent cb25bf0f48
commit 9b7950f765
No known key found for this signature in database
GPG Key ID: 0E2A37416A25EF58
6 changed files with 30 additions and 8 deletions

View File

@ -249,7 +249,7 @@ lazy_static! {
std::sync::Mutex::new(roc_collections::SmallStringInterner::with_capacity(10)); std::sync::Mutex::new(roc_collections::SmallStringInterner::with_capacity(10));
} }
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
pub struct Interns { pub struct Interns {
pub module_ids: ModuleIds, pub module_ids: ModuleIds,
pub all_ident_ids: IdentIdsByModule, pub all_ident_ids: IdentIdsByModule,
@ -663,7 +663,7 @@ impl IdentIds {
} }
} }
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
pub struct IdentIdsByModule(VecMap<ModuleId, IdentIds>); pub struct IdentIdsByModule(VecMap<ModuleId, IdentIds>);
impl IdentIdsByModule { impl IdentIdsByModule {

View File

@ -395,6 +395,8 @@ fn gen_and_eval_llvm<'a>(
} }
}; };
let interns = loaded.interns.clone();
let (lib, main_fn_name, subs) = let (lib, main_fn_name, subs) =
mono_module_to_dylib(&arena, target, loaded, opt_level).expect("we produce a valid Dylib"); mono_module_to_dylib(&arena, target, loaded, opt_level).expect("we produce a valid Dylib");
@ -407,6 +409,7 @@ fn gen_and_eval_llvm<'a>(
main_fn_layout, main_fn_layout,
&content, &content,
&subs, &subs,
&interns,
target_info, target_info,
); );

View File

@ -1,12 +1,13 @@
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
use roc_types::types::AliasKind;
use std::cmp::{max_by_key, min_by_key}; use std::cmp::{max_by_key, min_by_key};
use roc_builtins::bitcode::{FloatWidth, IntWidth}; use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
use roc_module::called_via::CalledVia; use roc_module::called_via::CalledVia;
use roc_module::ident::TagName; use roc_module::ident::TagName;
use roc_module::symbol::Symbol; use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::ir::ProcLayout; use roc_mono::ir::ProcLayout;
use roc_mono::layout::{ use roc_mono::layout::{
union_sorted_tags_help, Builtin, Layout, LayoutCache, UnionLayout, UnionVariant, WrappedVariant, union_sorted_tags_help, Builtin, Layout, LayoutCache, UnionLayout, UnionVariant, WrappedVariant,
@ -23,6 +24,7 @@ struct Env<'a, 'env> {
arena: &'a Bump, arena: &'a Bump,
subs: &'env Subs, subs: &'env Subs,
target_info: TargetInfo, target_info: TargetInfo,
interns: &'a Interns,
} }
pub enum ToAstProblem { pub enum ToAstProblem {
@ -45,12 +47,14 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
layout: ProcLayout<'a>, layout: ProcLayout<'a>,
content: &'a Content, content: &'a Content,
subs: &'a Subs, subs: &'a Subs,
interns: &'a Interns,
target_info: TargetInfo, target_info: TargetInfo,
) -> Result<Expr<'a>, ToAstProblem> { ) -> Result<Expr<'a>, ToAstProblem> {
let env = Env { let env = Env {
arena, arena,
subs, subs,
target_info, target_info,
interns,
}; };
match layout { match layout {
@ -70,6 +74,7 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
enum NewtypeKind<'a> { enum NewtypeKind<'a> {
Tag(&'a TagName), Tag(&'a TagName),
RecordField(&'a str), RecordField(&'a str),
Opaque(Symbol),
} }
/// Unrolls types that are newtypes. These include /// Unrolls types that are newtypes. These include
@ -115,7 +120,7 @@ fn unroll_newtypes_and_aliases<'a>(
)); ));
content = env.subs.get_content_without_compacting(field.into_inner()); content = env.subs.get_content_without_compacting(field.into_inner());
} }
Content::Alias(_, _, real_var, _) => { Content::Alias(name, _, real_var, kind) => {
// We need to pass through aliases too, because their underlying types may have // We need to pass through aliases too, because their underlying types may have
// unrolled newtypes. For example, // unrolled newtypes. For example,
// T : { a : Str } // T : { a : Str }
@ -126,6 +131,9 @@ fn unroll_newtypes_and_aliases<'a>(
// //
// At the end of the day what we should show to the user is the alias content, not // At the end of the day what we should show to the user is the alias content, not
// what's inside, so keep that around too. // what's inside, so keep that around too.
if *kind == AliasKind::Opaque && name.module_id() != ModuleId::NUM {
newtype_containers.push(NewtypeKind::Opaque(*name));
}
alias_content = Some(content); alias_content = Some(content);
content = env.subs.get_content_without_compacting(*real_var); content = env.subs.get_content_without_compacting(*real_var);
} }
@ -157,6 +165,13 @@ fn apply_newtypes<'a>(
let field = Loc::at_zero(AssignedField::RequiredValue(label, &[], field_val)); let field = Loc::at_zero(AssignedField::RequiredValue(label, &[], field_val));
expr = Expr::Record(Collection::with_items(&*arena.alloc([field]))) expr = Expr::Record(Collection::with_items(&*arena.alloc([field])))
} }
NewtypeKind::Opaque(name) => {
let opaque_name = arena.alloc(format!("@{}", name.as_str(&env.interns)));
let opaque_ref = &*arena.alloc(Loc::at_zero(Expr::OpaqueRef(opaque_name)));
let loc_arg_expr = &*arena.alloc(Loc::at_zero(expr));
let loc_arg_exprs = arena.alloc_slice_copy(&[loc_arg_expr]);
expr = Expr::Apply(opaque_ref, loc_arg_exprs, CalledVia::Space);
}
} }
} }
expr expr

View File

@ -1,3 +1,4 @@
use roc_module::symbol::Interns;
use roc_mono::{ use roc_mono::{
ir::ProcLayout, ir::ProcLayout,
layout::{CapturesNiche, LayoutCache}, layout::{CapturesNiche, LayoutCache},
@ -16,6 +17,7 @@ pub fn get_values<'a>(
target_info: TargetInfo, target_info: TargetInfo,
arena: &'a bumpalo::Bump, arena: &'a bumpalo::Bump,
subs: &'a Subs, subs: &'a Subs,
interns: &'a Interns,
start: *const u8, start: *const u8,
mut start_offset: usize, mut start_offset: usize,
variables: &[Variable], variables: &[Variable],
@ -52,6 +54,7 @@ pub fn get_values<'a>(
proc_layout, proc_layout,
content, content,
subs, subs,
interns,
target_info, target_info,
) )
}?; }?;

View File

@ -1024,7 +1024,7 @@ fn opaque_apply() {
@Age 23 @Age 23
"# "#
), ),
"23 : Age", "@Age 23 : Age",
) )
} }
@ -1038,7 +1038,7 @@ fn opaque_apply_polymorphic() {
@F (Package "" { a: "" }) @F (Package "" { a: "" })
"# "#
), ),
r#"Package "" { a: "" } : F Str { a : Str }"#, r#"@F (Package "" { a: "" }) : F Str { a : Str }"#,
) )
} }
@ -1054,7 +1054,7 @@ fn opaque_pattern_and_call() {
f (@F (Package A {})) f (@F (Package A {}))
"# "#
), ),
r#"Package {} A : F {} [A]*"#, r#"@F (Package {} A) : F {} [A]*"#,
) )
} }
@ -1189,6 +1189,6 @@ fn opaque_wrap_function() {
List.map [1u8, 2u8, 3u8] @A List.map [1u8, 2u8, 3u8] @A
"# "#
), ),
"[1, 2, 3] : List (A U8)", "[@A 1, @A 2, @A 3] : List (A U8)",
); );
} }

View File

@ -251,6 +251,7 @@ pub async fn entrypoint_from_js(src: String) -> Result<String, String> {
main_fn_layout, main_fn_layout,
content, content,
&subs, &subs,
&interns,
target_info, target_info,
); );