tokiwa-software / fuzion

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

require-condition2 failed: dev.flang.air.Clazz:lookup:1023 #486

Closed michaellilltokiwa closed 1 year ago

michaellilltokiwa commented 2 years ago

the example:

ex is
  my_choice : choice unit nil is

  a_choice my_choice := unit

  say (a_choice)

the error (the lookup here means it tries to call void):

java.lang.Error: require-condition2 failed: dev.flang.air.Clazz:lookup:1023
    at dev.flang.util.ANY.require(ANY.java:94)
    at dev.flang.air.Clazz.lookup(Clazz.java:1023)
    at dev.flang.air.Clazz.correspondingFieldInValueInstance(Clazz.java:2432)
    at dev.flang.fuir.FUIR.correspondingFieldInValueInstance(FUIR.java:1778)
    at dev.flang.fuir.analysis.dfa.DFA$1.clazzNeedsCode(DFA.java:735)
    at dev.flang.be.c.C.lambda$createCode$0(C.java:636)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
    at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:292)
    at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
    at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:169)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:298)
    at java.base/java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
    at dev.flang.util.List.addAll(List.java:220)
    at dev.flang.util.List.<init>(List.java:128)
    at dev.flang.be.c.C.lambda$createCode$4(C.java:648)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
    at java.base/java.util.stream.ReferencePipeline$Head.forEachOrdered(ReferencePipeline.java:772)
    at dev.flang.be.c.C.createCode(C.java:619)
    at dev.flang.be.c.C.compile(C.java:526)
    at dev.flang.tools.Fuzion$Backend$2.process(Fuzion.java:128)
    at dev.flang.tools.Fuzion$Backend.processFrontEnd(Fuzion.java:343)
    at dev.flang.tools.Fuzion.lambda$parseArgsForBackend$3(Fuzion.java:788)
    at dev.flang.tools.Tool.run(Tool.java:153)
    at dev.flang.tools.Fuzion.main(Fuzion.java:463)

Analysis:

  /**
   * Set of direct parent clazzes this inherits from.
   */
  private Set<Clazz> directParents()
  {
    var result = new TreeSet<Clazz>();
    result.add(this);
    for (var p: feature().inherits())
      {
        var pt = p.type();
        var pc = actualClazz(isRef() ? pt.asRef() : pt.asValue());
        System.err.println("===");
        System.out.println(this.toString());
        System.out.println(p.toString());
        System.out.println(pt.toString());
        System.out.println(pc.toString());
        if (CHECKS) check
          (Errors.count() > 0 || isRef() == pc.isRef());
        result.add(pc);
      }
    return result;
  }
....
===
ex.my_choice
choice<unit, nil>
void
void
...

My understanding of the problem is currently: Choice types inherit from void. Usually this seems to not be a problem since choice is never directly called. In this case though it seems to think it needs to call void to get its asString feature? This of course then leads to failure.

Note that if I add an asString explicitly the example compiles:

ex is

  my_choice : choice unit nil is
  a_choice my_choice := unit
  say (a_choice.asString)

Another thing that I realized is that void-Clazz normally seems to be interned via its OnDemandClazz. In this case it is interned like this:

        at dev.flang.air.Clazzes.intern(Clazzes.java:248)
        at dev.flang.air.Clazzes.create(Clazzes.java:359)
        at dev.flang.air.Clazzes.create(Clazzes.java:273)
        at dev.flang.air.Clazzes$OnDemandClazz.get(Clazzes.java:139)
        at dev.flang.air.Clazz.isVoidType(Clazz.java:761)
        at dev.flang.air.Clazz.called(Clazz.java:1587)
        at dev.flang.air.Clazzes.findAllClasses(Clazzes.java:421)
        at dev.flang.fuir.FUIR.<init>(FUIR.java:201)
        at dev.flang.opt.Optimizer.fuir(Optimizer.java:73)
        at dev.flang.tools.Fuzion$Backend.processFrontEnd(Fuzion.java:342)
        at dev.flang.tools.Fuzion.lambda$parseArgsForBackend$3(Fuzion.java:788)
        at dev.flang.tools.Tool.run(Tool.java:153)
        at dev.flang.tools.Fuzion.main(Fuzion.java:463)

This leads to also interning absurd which is the argument to void because Clazzes.create() calls result.dependencies() (result is Clazz void here.)

michaellilltokiwa commented 1 year ago

fixed