tokiwa-software / fuzion

The Fuzion Language Implementation
https://fuzion-lang.dev
GNU General Public License v3.0
46 stars 11 forks source link

`no targets for call` during DFA #3250

Closed fridis closed 3 days ago

fridis commented 3 months ago

This example inspired by this Twitter post

semigroup(T type) is
  append(a,b T) T => abstract

i32_semigroup : semigroup i32 is
  redef append(a,b i32) => a+b

Seq_semigroup(A type) : semigroup (Sequence A) is
  redef append(a,b Sequence A) Sequence A => a ++ b

say (i32_semigroup.append 1 2)
l1 := [3,1,2]
l2 := [0,1,2]
say ((Seq_semigroup i32).append l1 l2)

app3(s S : semigroup T, a,b,c T) =>
  s.append (s.append a b) c

say (app3 i32_semigroup 1 2 3)
say (app3 (Seq_semigroup i32) [1] [2,3] [4,5,6])

results in a crash during DFA

 > ../clean/fuzion.1/build/bin/fz test_semigroup.fz

$MODULE/Sequence.fz:303:8: error 1: NYI: in (array i32).as_string(0 args) at 805312393 no targets for Call (array i32).finite(outer array i32) bool target (array i32).as_string@$MODULE/io/print_effect.fz:55:14: embedded in (array i32).as_string@$MODULE/io/print_effect.fz:55:14:
    if finite
-------^^^^^^
Considered targets: array i32
program entry point
    |
    +- performs call universe#0 => *** VOID *** ENV: 'NO ENV'
      |
      +- performs call say a0={boxed(ref array i32):boxed(ref list i32):list i32[tag:0,val:UNIT],boxed(ref array i32):boxed(ref list i32):list i32[tag:1,val:boxed((array i32).ref array_cons):(array i32).array_cons@$MODULE/array.fz:160:11:],boxed(ref array i32):boxed(ref list i32):list i32[tag:1,val:boxed((list i32).anonymous):(list i32).anonymous@$MODULE/list.fz:520:3:]} => *** VOID *** ENV: 'NO ENV'
/home/fridi/fuzion/work/test_semigroup.fz:19:1:
say (app3 (Seq_semigroup i32) [1] [2,3] [4,5,6])
^^^
        |
        +- performs call io.out.println target=io.out@$MODULE/io/out.fz:32:9: a0={boxed(ref array i32):boxed(ref list i32):list i32[tag:0,val:UNIT],boxed(ref array i32):boxed(ref list i32):list i32[tag:1,val:boxed((array i32).ref array_cons):(array i32).array_cons@$MODULE/array.fz:160:11:],boxed(ref array i32):boxed(ref list i32):list i32[tag:1,val:boxed((list i32).anonymous):(list i32).anonymous@$MODULE/list.fz:520:3:]} => *** VOID *** ENV: 'NO ENV'
$MODULE/say.fz:31:29:
public say(s Any) => io.out.println s
----------------------------^^^^^^^
          |
          +- performs call ((io.#type io).out.#type io.out).default_print_handler.println target=((io.#type io).out.#type io.out).default_print_handler@<source position not available>: a0={boxed(ref array i32):boxed(ref list i32):list i32[tag:0,val:UNIT],boxed(ref array i32):boxed(ref list i32):list i32[tag:1,val:boxed((array i32).ref array_cons):(array i32).array_cons@$MODULE/array.fz:160:11:],boxed(ref array i32):boxed(ref list i32):list i32[tag:1,val:boxed((list i32).anonymous):(list i32).anonymous@$MODULE/list.fz:520:3:],boxed(ref i32):i32:--any value--,boxed(ref list i32):list i32[tag:0,val:UNIT],boxed(ref list i32):list i32[tag:1,val:boxed((array i32).ref array_cons):(array i32).array_cons@$MODULE/array.fz:160:11:],boxed(ref list i32):list i32[tag:1,val:boxed((list i32).anonymous):(list i32).anonymous@$MODULE/list.fz:520:3:]} => *** VOID *** ENV: 'NO ENV'
$MODULE/io/print_effect.fz:36:7:
    p.println s
------^^^^^^^
            |
            +- performs call (array i32).as_string target=boxed(ref list i32):list i32[tag:0,val:UNIT] => *** VOID *** ENV: 'NO ENV'
$MODULE/io/print_effect.fz:55:14:
    print (s.as_string + (codepoint 10))
-------------^^^^^^^^^

one error.

Reducing the example to

semigroup(T type) is
  append(a,b T) T => abstract

Seq_semigroup(A type) : semigroup (Sequence A) is
  redef append(a,b Sequence A) Sequence A => a ++ b

dup(s S : semigroup T, a T) =>
  s.append a a

_ := dup (Seq_semigroup i32) [1]

causes problems in the backends, e.g JVM:

 > ../clean/fuzion.1/build/bin/fz test_semigroup2.fz

error 1: java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    fzC_2dup__Seq_semigroup_i32__array_i32.fzRoutine(LfzC_4array_i32;)LfzC_4array_i32; @105: getfield
  Reason:
    Type 'fzI_Sequence_i32' (current frame, stack[2]) is not assignable to 'fzC_4array_i32'
  Current Frame:
    bci: @105
    flags: { }
    locals: { 'fzC_4array_i32', 'fzC_2dup__Seq_semigroup_i32__array_i32', 'fzC_4array_i32', 'fzC_4array_i32', top, top, 'fzI_Sequence_i32', 'fzC_4array_i32' }
    stack: { 'fzC_2dup__Seq_semigroup_i32__array_i32', 'fzC_4array_i32', 'fzI_Sequence_i32' }
  Bytecode:
    0000000: bb00 0259 b700 114c 2b2a 4dbb 0013 59b7
    0000010: 0014 4e2d 2cb4 0018 59c6 0028 3a04 bb00
    0000020: 1a59 b700 1b3a 0519 0519 04b4 001f 59c7
    0000030: 0003 b500 1f19 0519 04b4 0023 b500 2319
    0000040: 05b5 0018 2db5 0025 2b2b b400 25b8 002b
    0000050: 2bb4 0025 b800 2bb8 0031 3a06 bb00 1359
    0000060: b700 143a 0719 0719 06b4 0018 59c6 0028
    0000070: 3a08 bb00 1a59 b700 1b3a 0919 0919 08b4
    0000080: 001f 59c7 0003 b500 1f19 0919 08b4 0023
    0000090: b500 2319 09b5 0018 1907 b500 332b b400
    00000a0: 33b0                                   
  Stackmap Table:
    full_frame(@0,{Object[#19]},{})
    full_frame(@25,{Object[#19],Object[#2],Object[#19],Object[#19]},{Object[#2],Object[#19],Object[#26],Object[#26]})
    full_frame(@47,{Object[#19],Object[#2],Object[#19],Object[#19],Object[#26],Object[#26]},{Object[#2],Object[#19],Object[#26],Object[#54],Object[#54]})
    full_frame(@50,{Object[#19],Object[#2],Object[#19],Object[#19],Object[#26],Object[#26]},{Object[#2],Object[#19],Object[#26],Object[#54]})
    full_frame(@65,{Object[#19],Object[#2],Object[#19],Object[#19]},{Object[#2],Object[#19],Object[#26]})
    full_frame(@109,{Object[#19],Object[#2],Object[#19],Object[#19],Top,Top,Object[#19],Object[#19]},{Object[#2],Object[#19],Object[#26],Object[#26]})
    full_frame(@131,{Object[#19],Object[#2],Object[#19],Object[#19],Top,Top,Object[#19],Object[#19],Object[#26],Object[#26]},{Object[#2],Object[#19],Object[#26],Object[#54],Object[#54]})
    full_frame(@134,{Object[#19],Object[#2],Object[#19],Object[#19],Top,Top,Object[#19],Object[#19],Object[#26],Object[#26]},{Object[#2],Object[#19],Object[#26],Object[#54]})
    full_frame(@149,{Object[#19],Object[#2],Object[#19],Object[#19],Top,Top,Object[#19],Object[#19]},{Object[#2],Object[#19],Object[#26]})

    at fzC_universe.fzRoutine(--builtin--:10)
    at fzC_universe.fz_run(--builtin--)
    at dev.flang.be.jvm.runtime.FuzionThread.lambda$new$1(FuzionThread.java:97)
    at dev.flang.util.Errors.runAndExit(Errors.java:957)
    at dev.flang.be.jvm.runtime.FuzionThread.lambda$new$2(FuzionThread.java:106)
    at java.base/java.lang.Thread.run(Thread.java:1583)

*** fatal errors encountered, stopping.
one error.
fridis commented 2 months ago

The behavious changed, now we get

 > PRECONDITIONS=true POSTCONDITIONS=true ./build/bin/fz test_semigroup.fz 

error 1: java.lang.Error: require-condition1 failed: RefValue.java:74 "(!dfa._fuir.clazzIsRef(original._clazz), original._clazz == vc, dfa._fuir.clazzIsRef(rc));"
    at dev.flang.util.ANY.require(ANY.java:133)
    at dev.flang.fuir.analysis.dfa.RefValue.<init>(RefValue.java:74)
    at dev.flang.fuir.analysis.dfa.Value.box(Value.java:347)
    at dev.flang.fuir.analysis.dfa.ValueSet.box(ValueSet.java:204)
    at dev.flang.fuir.analysis.dfa.DFA$Analyze.box(DFA.java:420)
    at dev.flang.fuir.analysis.dfa.DFA$Analyze.box(DFA.java:90)