diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index c7cc9d0a5e..3bb3a7d19d 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -2586,7 +2586,6 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>( condition: cond_symbol, region, lookups, - layouts: _, remainder, } => { let bd = env.builder; @@ -2655,7 +2654,6 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>( condition: cond_symbol, region, lookups, - layouts: _, remainder, } => { let bd = env.builder; diff --git a/crates/compiler/mono/src/debug/checker.rs b/crates/compiler/mono/src/debug/checker.rs index 01e169f43e..edb9d7644a 100644 --- a/crates/compiler/mono/src/debug/checker.rs +++ b/crates/compiler/mono/src/debug/checker.rs @@ -309,14 +309,12 @@ impl<'a, 'r> Ctx<'a, 'r> { condition, region: _, lookups, - layouts, remainder, } | &Stmt::ExpectFx { condition, region: _, lookups, - layouts, remainder, } => { self.check_sym_layout( @@ -324,8 +322,8 @@ impl<'a, 'r> Ctx<'a, 'r> { Layout::Builtin(Builtin::Bool), UseKind::ExpectCond, ); - for (sym, lay) in lookups.iter().zip(layouts) { - self.check_sym_layout(*sym, *lay, UseKind::ExpectLookup); + for sym in lookups.iter() { + self.check_sym_exists(*sym); } self.check_stmt(remainder); } diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index 8e277e5b91..533990427a 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -1199,7 +1199,6 @@ impl<'a, 'i> Context<'a, 'i> { condition, region, lookups, - layouts, } => { let (b, mut b_live_vars) = self.visit_stmt(codegen, remainder); @@ -1207,7 +1206,6 @@ impl<'a, 'i> Context<'a, 'i> { condition: *condition, region: *region, lookups, - layouts, remainder: b, }); @@ -1223,7 +1221,6 @@ impl<'a, 'i> Context<'a, 'i> { condition, region, lookups, - layouts, } => { let (b, mut b_live_vars) = self.visit_stmt(codegen, remainder); @@ -1231,7 +1228,6 @@ impl<'a, 'i> Context<'a, 'i> { condition: *condition, region: *region, lookups, - layouts, remainder: b, }); diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index b75296a994..4d3f1918a6 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -1622,7 +1622,6 @@ pub enum Stmt<'a> { condition: Symbol, region: Region, lookups: &'a [Symbol], - layouts: &'a [Layout<'a>], /// what happens after the expect remainder: &'a Stmt<'a>, }, @@ -1630,7 +1629,6 @@ pub enum Stmt<'a> { condition: Symbol, region: Region, lookups: &'a [Symbol], - layouts: &'a [Layout<'a>], /// what happens after the expect remainder: &'a Stmt<'a>, }, @@ -6570,7 +6568,6 @@ pub fn from_can<'a>( let cond_symbol = env.unique_symbol(); let mut lookups = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); - let mut layouts = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); for ExpectLookup { symbol, @@ -6587,12 +6584,9 @@ pub fn from_can<'a>( ), None => symbol, }; - let res_layout = layout_cache.from_var(env.arena, var, env.subs); - let layout = return_on_layout_error!(env, res_layout, "Expect"); - if !matches!(layout, Layout::LambdaSet(..)) { + if !env.subs.is_function(var) { // Exclude functions from lookups lookups.push(symbol); - layouts.push(layout); } } @@ -6600,7 +6594,6 @@ pub fn from_can<'a>( condition: cond_symbol, region: loc_condition.region, lookups: lookups.into_bump_slice(), - layouts: layouts.into_bump_slice(), remainder: env.arena.alloc(rest), }; @@ -6626,7 +6619,6 @@ pub fn from_can<'a>( let cond_symbol = env.unique_symbol(); let mut lookups = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); - let mut layouts = Vec::with_capacity_in(lookups_in_cond.len(), env.arena); for ExpectLookup { symbol, @@ -6643,12 +6635,9 @@ pub fn from_can<'a>( ), None => symbol, }; - let res_layout = layout_cache.from_var(env.arena, var, env.subs); - let layout = return_on_layout_error!(env, res_layout, "Expect"); - if !matches!(layout, Layout::LambdaSet(..)) { + if !env.subs.is_function(var) { // Exclude functions from lookups lookups.push(symbol); - layouts.push(layout); } } @@ -6656,7 +6645,6 @@ pub fn from_can<'a>( condition: cond_symbol, region: loc_condition.region, lookups: lookups.into_bump_slice(), - layouts: layouts.into_bump_slice(), remainder: env.arena.alloc(rest), }; @@ -7082,7 +7070,6 @@ fn substitute_in_stmt_help<'a>( condition, region, lookups, - layouts, remainder, } => { let new_remainder = @@ -7097,7 +7084,6 @@ fn substitute_in_stmt_help<'a>( condition: substitute(subs, *condition).unwrap_or(*condition), region: *region, lookups: new_lookups.into_bump_slice(), - layouts, remainder: new_remainder, }; @@ -7108,7 +7094,6 @@ fn substitute_in_stmt_help<'a>( condition, region, lookups, - layouts, remainder, } => { let new_remainder = @@ -7123,7 +7108,6 @@ fn substitute_in_stmt_help<'a>( condition: substitute(subs, *condition).unwrap_or(*condition), region: *region, lookups: new_lookups.into_bump_slice(), - layouts, remainder: new_remainder, }; diff --git a/crates/compiler/mono/src/reset_reuse.rs b/crates/compiler/mono/src/reset_reuse.rs index c47f2e6d56..a8e8cd5f29 100644 --- a/crates/compiler/mono/src/reset_reuse.rs +++ b/crates/compiler/mono/src/reset_reuse.rs @@ -195,7 +195,6 @@ fn function_s<'a, 'i>( condition, region, lookups, - layouts, remainder, } => { let continuation: &Stmt = remainder; @@ -208,7 +207,6 @@ fn function_s<'a, 'i>( condition: *condition, region: *region, lookups, - layouts, remainder: new_continuation, }; @@ -220,7 +218,6 @@ fn function_s<'a, 'i>( condition, region, lookups, - layouts, remainder, } => { let continuation: &Stmt = remainder; @@ -233,7 +230,6 @@ fn function_s<'a, 'i>( condition: *condition, region: *region, lookups, - layouts, remainder: new_continuation, }; @@ -442,7 +438,6 @@ fn function_d_main<'a, 'i>( condition, region, lookups, - layouts, remainder, } => { let (b, found) = function_d_main(env, x, c, remainder); @@ -452,7 +447,6 @@ fn function_d_main<'a, 'i>( condition: *condition, region: *region, lookups, - layouts, remainder: b, }; @@ -464,7 +458,6 @@ fn function_d_main<'a, 'i>( condition: *condition, region: *region, lookups, - layouts, remainder: b, }; @@ -475,7 +468,6 @@ fn function_d_main<'a, 'i>( condition, region, lookups, - layouts, remainder, } => { let (b, found) = function_d_main(env, x, c, remainder); @@ -485,7 +477,6 @@ fn function_d_main<'a, 'i>( condition: *condition, region: *region, lookups, - layouts, remainder: b, }; @@ -497,7 +488,6 @@ fn function_d_main<'a, 'i>( condition: *condition, region: *region, lookups, - layouts, remainder: b, }; @@ -660,7 +650,6 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a> condition, region, lookups, - layouts, remainder, } => { let b = function_r(env, remainder); @@ -669,7 +658,6 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a> condition: *condition, region: *region, lookups, - layouts, remainder: b, }; @@ -680,7 +668,6 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a> condition, region, lookups, - layouts, remainder, } => { let b = function_r(env, remainder); @@ -689,7 +676,6 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a> condition: *condition, region: *region, lookups, - layouts, remainder: b, }; diff --git a/crates/compiler/mono/src/tail_recursion.rs b/crates/compiler/mono/src/tail_recursion.rs index 96bc7df8f2..5c152550a8 100644 --- a/crates/compiler/mono/src/tail_recursion.rs +++ b/crates/compiler/mono/src/tail_recursion.rs @@ -253,7 +253,6 @@ fn insert_jumps<'a>( condition, region, lookups, - layouts, remainder, } => match insert_jumps( arena, @@ -267,7 +266,6 @@ fn insert_jumps<'a>( condition: *condition, region: *region, lookups, - layouts, remainder: cont, })), None => None, @@ -277,7 +275,6 @@ fn insert_jumps<'a>( condition, region, lookups, - layouts, remainder, } => match insert_jumps( arena, @@ -291,7 +288,6 @@ fn insert_jumps<'a>( condition: *condition, region: *region, lookups, - layouts, remainder: cont, })), None => None, diff --git a/crates/compiler/test_mono/generated/issue_4749.txt b/crates/compiler/test_mono/generated/issue_4749.txt new file mode 100644 index 0000000000..2190c63b4e --- /dev/null +++ b/crates/compiler/test_mono/generated/issue_4749.txt @@ -0,0 +1,316 @@ +procedure Bool.11 (#Attr.2, #Attr.3): + let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3; + dec #Attr.3; + dec #Attr.2; + ret Bool.23; + +procedure Bool.11 (#Attr.2, #Attr.3): + let Bool.31 : Int1 = lowlevel Eq #Attr.2 #Attr.3; + ret Bool.31; + +procedure Bool.11 (#Attr.2, #Attr.3): + let Bool.38 : Int1 = lowlevel Eq #Attr.2 #Attr.3; + ret Bool.38; + +procedure Bool.12 (#Attr.2, #Attr.3): + let Bool.30 : Int1 = lowlevel NotEq #Attr.2 #Attr.3; + ret Bool.30; + +procedure Bool.7 (Bool.19, Bool.20): + let Bool.29 : Int1 = CallByName Bool.12 Bool.19 Bool.20; + ret Bool.29; + +procedure Decode.23 (Decode.94): + ret Decode.94; + +procedure Decode.24 (Decode.95, Decode.114, Decode.97): + let Decode.127 : {List U8, [C {}, C Str]} = CallByName Json.293 Decode.95 Decode.97; + ret Decode.127; + +procedure Decode.25 (Decode.98, Decode.99): + let Decode.126 : {} = Struct {}; + let Decode.125 : {List U8, [C {}, C Str]} = CallByName Decode.24 Decode.98 Decode.126 Decode.99; + ret Decode.125; + +procedure Decode.26 (Decode.100, Decode.101): + let Decode.115 : {List U8, [C {}, C Str]} = CallByName Decode.25 Decode.100 Decode.101; + let Decode.103 : List U8 = StructAtIndex 0 Decode.115; + inc Decode.103; + let Decode.102 : [C {}, C Str] = StructAtIndex 1 Decode.115; + inc Decode.102; + dec Decode.115; + let Decode.118 : Int1 = CallByName List.1 Decode.103; + if Decode.118 then + dec Decode.103; + let Decode.122 : U8 = 1i64; + let Decode.123 : U8 = GetTagId Decode.102; + let Decode.124 : Int1 = lowlevel Eq Decode.122 Decode.123; + if Decode.124 then + let Decode.104 : Str = UnionAtIndex (Id 1) (Index 0) Decode.102; + inc Decode.104; + dec Decode.102; + let Decode.119 : [C [C List U8, C ], C Str] = TagId(1) Decode.104; + ret Decode.119; + else + dec Decode.102; + let Decode.121 : [C List U8, C ] = TagId(1) ; + let Decode.120 : [C [C List U8, C ], C Str] = TagId(0) Decode.121; + ret Decode.120; + else + dec Decode.102; + let Decode.117 : [C List U8, C ] = TagId(0) Decode.103; + let Decode.116 : [C [C List U8, C ], C Str] = TagId(0) Decode.117; + ret Decode.116; + +procedure Json.139 (Json.450, Json.451): + joinpoint Json.421 Json.418 Json.138: + let Json.141 : List U8 = StructAtIndex 0 Json.418; + inc Json.141; + let Json.140 : List U8 = StructAtIndex 1 Json.418; + inc Json.140; + dec Json.418; + let Json.422 : [C {}, C U8] = CallByName List.9 Json.141; + let Json.436 : U8 = 1i64; + let Json.437 : U8 = GetTagId Json.422; + let Json.438 : Int1 = lowlevel Eq Json.436 Json.437; + if Json.438 then + let Json.142 : U8 = UnionAtIndex (Id 1) (Index 0) Json.422; + let Json.424 : Int1 = CallByName Json.283 Json.142; + if Json.424 then + let Json.434 : U64 = 1i64; + let Json.430 : {List U8, List U8} = CallByName List.52 Json.141 Json.434; + let Json.431 : {} = Struct {}; + let Json.428 : List U8 = CallByName Json.143 Json.430; + let Json.429 : List U8 = CallByName List.4 Json.140 Json.142; + let Json.426 : {List U8, List U8} = Struct {Json.428, Json.429}; + jump Json.421 Json.426 Json.138; + else + let Json.423 : {List U8, List U8} = Struct {Json.141, Json.140}; + ret Json.423; + else + let Json.435 : {List U8, List U8} = Struct {Json.141, Json.140}; + ret Json.435; + in + jump Json.421 Json.450 Json.451; + +procedure Json.143 (Json.432): + let Json.433 : List U8 = StructAtIndex 1 Json.432; + inc Json.433; + dec Json.432; + ret Json.433; + +procedure Json.2 (): + let Json.396 : {} = Struct {}; + ret Json.396; + +procedure Json.22 (Json.137, Json.138): + let Json.440 : List U8 = Array []; + let Json.420 : {List U8, List U8} = Struct {Json.137, Json.440}; + let Json.419 : {List U8, List U8} = CallByName Json.139 Json.420 Json.138; + ret Json.419; + +procedure Json.283 (Json.284): + let Json.442 : U8 = 34i64; + let Json.441 : Int1 = CallByName Bool.7 Json.284 Json.442; + ret Json.441; + +procedure Json.293 (Json.294, Json.399): + let Json.400 : {List U8, [C {}, C Str]} = CallByName Json.40 Json.294; + ret Json.400; + +procedure Json.40 (Json.276): + let Json.446 : U64 = 1i64; + inc Json.276; + let Json.445 : {List U8, List U8} = CallByName List.52 Json.276 Json.446; + let Json.277 : List U8 = StructAtIndex 0 Json.445; + inc Json.277; + let Json.279 : List U8 = StructAtIndex 1 Json.445; + inc Json.279; + dec Json.445; + let Json.444 : U8 = 34i64; + let Json.443 : List U8 = Array [Json.444]; + let Json.404 : Int1 = CallByName Bool.11 Json.277 Json.443; + dec Json.443; + dec Json.277; + if Json.404 then + dec Json.276; + let Json.417 : {} = Struct {}; + let Json.416 : {List U8, List U8} = CallByName Json.22 Json.279 Json.417; + let Json.282 : List U8 = StructAtIndex 0 Json.416; + inc Json.282; + let Json.281 : List U8 = StructAtIndex 1 Json.416; + inc Json.281; + dec Json.416; + let Json.405 : [C {U64, U8}, C Str] = CallByName Str.9 Json.281; + let Json.413 : U8 = 1i64; + let Json.414 : U8 = GetTagId Json.405; + let Json.415 : Int1 = lowlevel Eq Json.413 Json.414; + if Json.415 then + let Json.285 : Str = UnionAtIndex (Id 1) (Index 0) Json.405; + inc Json.285; + dec Json.405; + let Json.409 : U64 = 1i64; + let Json.408 : {List U8, List U8} = CallByName List.52 Json.282 Json.409; + let Json.287 : List U8 = StructAtIndex 1 Json.408; + inc Json.287; + dec Json.408; + let Json.407 : [C {}, C Str] = TagId(1) Json.285; + let Json.406 : {List U8, [C {}, C Str]} = Struct {Json.287, Json.407}; + ret Json.406; + else + dec Json.405; + let Json.412 : {} = Struct {}; + let Json.411 : [C {}, C Str] = TagId(0) Json.412; + let Json.410 : {List U8, [C {}, C Str]} = Struct {Json.282, Json.411}; + ret Json.410; + else + dec Json.279; + let Json.403 : {} = Struct {}; + let Json.402 : [C {}, C Str] = TagId(0) Json.403; + let Json.401 : {List U8, [C {}, C Str]} = Struct {Json.276, Json.402}; + ret Json.401; + +procedure Json.41 (): + let Json.398 : {} = Struct {}; + let Json.397 : {} = CallByName Decode.23 Json.398; + ret Json.397; + +procedure List.1 (List.94): + let List.479 : U64 = CallByName List.6 List.94; + let List.480 : U64 = 0i64; + let List.478 : Int1 = CallByName Bool.11 List.479 List.480; + ret List.478; + +procedure List.2 (List.95, List.96): + let List.536 : U64 = CallByName List.6 List.95; + let List.532 : Int1 = CallByName Num.22 List.96 List.536; + if List.532 then + let List.534 : U8 = CallByName List.66 List.95 List.96; + let List.533 : [C {}, C U8] = TagId(1) List.534; + ret List.533; + else + let List.531 : {} = Struct {}; + let List.530 : [C {}, C U8] = TagId(0) List.531; + ret List.530; + +procedure List.4 (List.106, List.107): + let List.520 : U64 = 1i64; + let List.518 : List U8 = CallByName List.70 List.106 List.520; + let List.517 : List U8 = CallByName List.71 List.518 List.107; + ret List.517; + +procedure List.49 (List.366, List.367): + let List.492 : U64 = StructAtIndex 0 List.367; + let List.493 : U64 = 0i64; + let List.490 : Int1 = CallByName Bool.11 List.492 List.493; + if List.490 then + dec List.366; + let List.491 : List U8 = Array []; + ret List.491; + else + let List.487 : U64 = StructAtIndex 1 List.367; + let List.488 : U64 = StructAtIndex 0 List.367; + let List.486 : List U8 = CallByName List.72 List.366 List.487 List.488; + ret List.486; + +procedure List.52 (List.381, List.382): + let List.383 : U64 = CallByName List.6 List.381; + joinpoint List.515 List.384: + let List.513 : U64 = 0i64; + let List.512 : {U64, U64} = Struct {List.384, List.513}; + inc List.381; + let List.385 : List U8 = CallByName List.49 List.381 List.512; + let List.511 : U64 = CallByName Num.20 List.383 List.384; + let List.510 : {U64, U64} = Struct {List.511, List.384}; + let List.386 : List U8 = CallByName List.49 List.381 List.510; + let List.509 : {List U8, List U8} = Struct {List.385, List.386}; + ret List.509; + in + let List.516 : Int1 = CallByName Num.24 List.383 List.382; + if List.516 then + jump List.515 List.382; + else + jump List.515 List.383; + +procedure List.6 (#Attr.2): + let List.556 : U64 = lowlevel ListLen #Attr.2; + ret List.556; + +procedure List.66 (#Attr.2, #Attr.3): + let List.535 : U8 = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.535; + +procedure List.70 (#Attr.2, #Attr.3): + let List.521 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.521; + +procedure List.71 (#Attr.2, #Attr.3): + let List.519 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.519; + +procedure List.72 (#Attr.2, #Attr.3, #Attr.4): + let List.489 : List U8 = lowlevel ListSublist #Attr.2 #Attr.3 #Attr.4; + ret List.489; + +procedure List.9 (List.283): + let List.529 : U64 = 0i64; + let List.522 : [C {}, C U8] = CallByName List.2 List.283 List.529; + let List.526 : U8 = 1i64; + let List.527 : U8 = GetTagId List.522; + let List.528 : Int1 = lowlevel Eq List.526 List.527; + if List.528 then + let List.284 : U8 = UnionAtIndex (Id 1) (Index 0) List.522; + let List.523 : [C {}, C U8] = TagId(1) List.284; + ret List.523; + else + let List.525 : {} = Struct {}; + let List.524 : [C {}, C U8] = TagId(0) List.525; + ret List.524; + +procedure Num.20 (#Attr.2, #Attr.3): + let Num.258 : U64 = lowlevel NumSub #Attr.2 #Attr.3; + ret Num.258; + +procedure Num.22 (#Attr.2, #Attr.3): + let Num.262 : Int1 = lowlevel NumLt #Attr.2 #Attr.3; + ret Num.262; + +procedure Num.24 (#Attr.2, #Attr.3): + let Num.261 : Int1 = lowlevel NumGt #Attr.2 #Attr.3; + ret Num.261; + +procedure Str.48 (#Attr.2, #Attr.3, #Attr.4): + let Str.274 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4; + ret Str.274; + +procedure Str.9 (Str.76): + let Str.272 : U64 = 0i64; + let Str.273 : U64 = CallByName List.6 Str.76; + let Str.77 : {U64, Str, Int1, U8} = CallByName Str.48 Str.76 Str.272 Str.273; + let Str.269 : Int1 = StructAtIndex 2 Str.77; + if Str.269 then + let Str.271 : Str = StructAtIndex 1 Str.77; + inc Str.271; + dec Str.77; + let Str.270 : [C {U64, U8}, C Str] = TagId(1) Str.271; + ret Str.270; + else + let Str.267 : U8 = StructAtIndex 3 Str.77; + let Str.268 : U64 = StructAtIndex 0 Str.77; + dec Str.77; + let Str.266 : {U64, U8} = Struct {Str.268, Str.267}; + let Str.265 : [C {U64, U8}, C Str] = TagId(0) Str.266; + ret Str.265; + +procedure Test.3 (): + let Test.0 : List U8 = Array [82i64, 111i64, 99i64]; + let Test.8 : {} = CallByName Json.2; + inc Test.0; + let Test.1 : [C [C List U8, C ], C Str] = CallByName Decode.26 Test.0 Test.8; + let Test.7 : Str = "Roc"; + let Test.6 : [C [C List U8, C ], C Str] = TagId(1) Test.7; + inc Test.1; + let Test.5 : Int1 = CallByName Bool.11 Test.1 Test.6; + expect Test.5; + let Test.4 : {} = Struct {}; + ret Test.4; diff --git a/crates/compiler/test_mono/src/tests.rs b/crates/compiler/test_mono/src/tests.rs index 99383302fc..9791c9a139 100644 --- a/crates/compiler/test_mono/src/tests.rs +++ b/crates/compiler/test_mono/src/tests.rs @@ -2159,3 +2159,17 @@ fn issue_4705() { "### ) } + +#[mono_test(mode = "test")] +fn issue_4749() { + indoc!( + r###" + interface Test exposes [] imports [Json] + + expect + input = [82, 111, 99] + got = Decode.fromBytes input Json.fromUtf8 + got == Ok "Roc" + "### + ) +}