mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Reuse symbol when opaque type wraps a known symbol
Opaques decay immediately into their argument during codegen, so we need to handle something that's effectively variable aliasing correctly. This bug popped up while migrating all current private tags to opaques.
This commit is contained in:
parent
b417cc6c18
commit
5d1dd81e93
4 changed files with 70 additions and 9 deletions
|
@ -3499,7 +3499,15 @@ pub fn with_hole<'a>(
|
||||||
|
|
||||||
OpaqueRef { argument, .. } => {
|
OpaqueRef { argument, .. } => {
|
||||||
let (arg_var, loc_arg_expr) = *argument;
|
let (arg_var, loc_arg_expr) = *argument;
|
||||||
with_hole(
|
|
||||||
|
match can_reuse_symbol(env, procs, &loc_arg_expr.value) {
|
||||||
|
// Opaques decay to their argument.
|
||||||
|
ReuseSymbol::Value(real_name) => {
|
||||||
|
let mut result = hole.clone();
|
||||||
|
substitute_in_exprs(arena, &mut result, assigned, real_name);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
_ => with_hole(
|
||||||
env,
|
env,
|
||||||
loc_arg_expr.value,
|
loc_arg_expr.value,
|
||||||
arg_var,
|
arg_var,
|
||||||
|
@ -3507,7 +3515,8 @@ pub fn with_hole<'a>(
|
||||||
layout_cache,
|
layout_cache,
|
||||||
assigned,
|
assigned,
|
||||||
hole,
|
hole,
|
||||||
)
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Record {
|
Record {
|
||||||
|
|
|
@ -1580,3 +1580,28 @@ fn issue_2725_alias_polymorphic_lambda() {
|
||||||
i64
|
i64
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn opaque_assign_to_symbol() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [ out ] to "./platform"
|
||||||
|
|
||||||
|
Variable := U8
|
||||||
|
|
||||||
|
fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ]
|
||||||
|
fromUtf8 = \char ->
|
||||||
|
Ok ($Variable char)
|
||||||
|
|
||||||
|
out =
|
||||||
|
when fromUtf8 98 is
|
||||||
|
Ok ($Variable n) -> n
|
||||||
|
_ -> 1
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
98,
|
||||||
|
u8
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
10
compiler/test_mono/generated/opaque_assign_to_symbol.txt
Normal file
10
compiler/test_mono/generated/opaque_assign_to_symbol.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
procedure : `#UserApp.fromUtf8` [C {}, C U8]
|
||||||
|
procedure = `#UserApp.fromUtf8` (`#UserApp.char`):
|
||||||
|
let `#UserApp.3` : [C {}, C U8] = Ok `#UserApp.4`;
|
||||||
|
ret `#UserApp.3`;
|
||||||
|
|
||||||
|
procedure : `#UserApp.out` [C {}, C U8]
|
||||||
|
procedure = `#UserApp.out` ():
|
||||||
|
let `#UserApp.2` : U8 = 98i64;
|
||||||
|
let `#UserApp.1` : [C {}, C U8] = CallByName `#UserApp.fromUtf8` `#UserApp.2`;
|
||||||
|
ret `#UserApp.1`;
|
|
@ -1330,6 +1330,23 @@ fn specialize_ability_call() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[mono_test]
|
||||||
|
fn opaque_assign_to_symbol() {
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [ out ] to "./platform"
|
||||||
|
|
||||||
|
Variable := U8
|
||||||
|
|
||||||
|
fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ]
|
||||||
|
fromUtf8 = \char ->
|
||||||
|
Ok ($Variable char)
|
||||||
|
|
||||||
|
out = fromUtf8 98
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// #[ignore]
|
// #[ignore]
|
||||||
// #[mono_test]
|
// #[mono_test]
|
||||||
// fn static_str_closure() {
|
// fn static_str_closure() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue