dylan-lang / opendylan

Open Dylan compiler and IDE
http://opendylan.org/
Other
458 stars 69 forks source link

Internal error on invalid CPL #1040

Closed waywardmonkeys closed 6 years ago

waywardmonkeys commented 8 years ago

I had an invalid class hierarchy and landed at this stack trace:

  frame #12   Kelement_range_errorVKeI                                     0x0000000003f1bc libdylan.dylib at collection.c:6003
  frame #13   KelementVKdMM25I                                             0x00000000060c80 libdylan.dylib at list.c:2454
  frame #21   Kcpl_searchVdfmc_conversionMM0I                              0x00000000da06c5 libdfmc-conversion.dylib at define-class-mop.c:15225
  frame #22   Kexplain_precedesVdfmc_conversionMM0I                        0x00000000d99f9b libdfmc-conversion.dylib at define-class-mop.c:15019
  frame #23   Knote_cpl_inconsistencyVdfmc_conversionMM0I                  0x00000000da017d libdfmc-conversion.dylib at define-class-mop.c:14635
  frame #24   Kmerge_listsF445I                                            0x00000000d9e154 libdfmc-conversion.dylib at define-class-mop.c:13850
  frame #25   KCcompute_class_precedence_listVdfmc_conversionI             0x00000000d98c04 libdfmc-conversion.dylib at define-class-mop.c:12117
  frame #27   Kcompute_and_install_form_model_objects_staticallyVdfmc_conversionMM0I 0x00000000d939f9 libdfmc-conversion.dylib at define-class.c:12141
  frame #28   Kcompute_and_install_form_model_objectsVdfmc_commonMdfmc_conversionM1I 0x00000000d8a796 libdfmc-conversion.dylib at define-class.c:5399
  frame #29   Kanonymous_of_maybe_compute_and_install_form_model_objectsF577I 0x00000000ec20ed libdfmc-management.dylib at compilation-driver.c:12200

The hierarchy was to have a class <a>. Then classes <b> and <c> inherit from <a>. Then I had a class <d> that inherited from both <b> and <c>.

waywardmonkeys commented 8 years ago

The error was:

Internal error: ELEMENT outside of range: 1

The code involved was the h.head[1] in this:

  local method search(el)
    let h = el.head;
    if (h.head[1] == c2)
      reverse(h)
    else
      let e = edges(h.head[1]);
      search(concatenate(el.tail, map(rcurry(pair, h), e)))
    end
  end;

At the point of the failure, both h and el are #().

waywardmonkeys commented 8 years ago

Oh, and c1 is the class object for <socket> (which is <a> in my explanation above).

pedro-w commented 6 years ago

Just to provide a bit more explicit information - I can reproduce this error with the following hierarchy:

define class <a> (<object>)
end;

// Internal error element outside of range
define class <b> (<object>,<a>)
end;

and the code cited above is here: https://github.com/dylan-lang/opendylan/blob/8f1d5d32ba1faf6ba304cfc588da60acf95ddfef/sources/dfmc/conversion/define-class-mop.dylan#L1251-L1259

called from line 1216 here https://github.com/dylan-lang/opendylan/blob/8f1d5d32ba1faf6ba304cfc588da60acf95ddfef/sources/dfmc/conversion/define-class-mop.dylan#L1215-L1219

pedro-w commented 6 years ago

On a related note,

define class <a1> (<object>)
end;

define class <b1> (<object>)
end;

define class <c1> (<a1>,<b1>)
end;

define class <d1> (<b1>,<a1>)
end;

// <subclass-explanation-2>
define class <e1> (<c1>,<d1>)
end;

gives the curious error

Internal error: The class-4-name slot is unbound in #"<a1>" precedes #"<b1>" 
in the CPL of #f because #f is a direct subclass of #"<c1>" and #"<a1>" 
precedes #"<b1>" in #"<c1>".

A quick look suggest this may be a copy-paste bug (second class-2: should be class-3:) https://github.com/dylan-lang/opendylan/blob/8f1d5d32ba1faf6ba304cfc588da60acf95ddfef/sources/dfmc/conversion/define-class-mop.dylan#L1208-L1211 and (class-3: init keyword should be class-4:) https://github.com/dylan-lang/opendylan/blob/8f1d5d32ba1faf6ba304cfc588da60acf95ddfef/sources/dfmc/conversion/define-class-mop.dylan#L1159-L1167

I'll try and fix this and the original issue at the same time.