dfinity / motoko

Simple high-level language for writing Internet Computer canisters
Apache License 2.0
514 stars 97 forks source link

[Bug] Type renaming(s) incorrectly rejected as cyclic #2529

Closed crusso closed 3 years ago

crusso commented 3 years ago

repro: Compiler incorrectly rejects type abbreviations as cyclic. Eg.

import QR "canister:qr";

actor {

/* BUG: rejected as cyclic
  type ErrorCorrection_ = QR.ErrorCorrection;
  type Mode = QR.Mode;
  type Version = QR.Version;
*/

  public func encode(
    version : QR.Version,
    level : QR.ErrorCorrection,
    mode : QR.Mode,
    text : Text
  ) : async Text {
    let result = await QR.encode(version, level, mode, text);
    switch result {
      case (?matrix) "\n" # (await QR.show(matrix));
      case _ "Error: Invalid input!";
    }
  };
}

Full repro: https://github.com/crusso/motoko-qr/tree/claudio/0.7.0

crusso commented 3 years ago

It gets weirder:

Given files:

issue-2529/rkp4c-7iaaa-aaaaa-aaaca-cai.did:

type Version_3 = variant {Version: nat;};
type Version_2 = Version_3;
type Version = Version_2;
type Mode_3 = 
 variant {
   Alphanumeric;
   EightBit;
   Kanji;
   Numeric;
 };
type Mode_2 = Mode_3;
type Mode = Mode_2;
type Matrix_3 = variant {Matrix: vec vec bool;};
type Matrix_2 = Matrix_3;
type Matrix = Matrix_2;
type ErrorCorrection_3 = 
 variant {
   H;
   L;
   M;
   Q;
 };
type ErrorCorrection_2 = ErrorCorrection_3;
type ErrorCorrection = ErrorCorrection_2;
service : {
  encode: (Version, ErrorCorrection, Mode, text) -> (opt Matrix);
  show: (Matrix) -> (text);
}

and

issue-2529.mo

// moc --actor-idl issue-2529 --actor-alias qr rkp4c-7iaaa-aaaaa-aaaca-cai issue-2529.mo

import QR "canister:qr";

actor {

  type ErrorCorrection = QR.ErrorCorrection;
  type Mode = QR.Mode;
  type Version = QR.Version;

  public func encode(
    version : Version,
    level : ErrorCorrection,
    mode : Mode,
    text : Text,
  ) : async Text {
    let result = await QR.encode(version, level, mode, text);
    switch result {
      case (?matrix) "\n" # (await QR.show(matrix));
      case _ "Error: Invalid input!";
    }
  };
}

running moc -idl produces broken candid with circular definitions (which I believe may be the cause of the error I was seeing, but is broken even if not:

[nix-shell:~/motoko/test/fail]$ moc --idl --actor-idl issue-2529 --actor-alias qr rkp4c-7iaaa-aaaaa-aaaca-cai issue-2529.mo

[nix-shell:~/motoko/test/fail]$ more issue-2529.did 
type Version_2 = Version_2;
type Version = Version_2;
type Mode_2 = Mode_2;
type Mode = Mode_2;
type ErrorCorrection_2 = ErrorCorrection_2;
type ErrorCorrection = ErrorCorrection_2;
service : {
  encode: (Version, ErrorCorrection, Mode, text) -> (text);

Looks like mo-idl isn't chasing imported constructors for some reason...are they still abstract?

crusso commented 3 years ago

I'll construct a smaller repro tomorrow...

crusso commented 3 years ago

@rossberg, @chenyan-dfinity @nomeata I can't recall who wrote the mo-idl functionality, but if this bug rings a bell....

chenyan-dfinity commented 3 years ago

Do you have a branch I can take a look? issue-2529.mo is empty?

crusso commented 3 years ago

Oops. Give me ten minutes

crusso commented 3 years ago

https://github.com/dfinity/motoko/pull/2531 contains a repro - see the command at the end of the file and inspect the .did it produces.

crusso commented 3 years ago

@chenyan-dfinity ^^^ the repro should live under test/mo_idl but is currently in test/fail

crusso commented 3 years ago

(Using different names - not puns - avoids the bug, btw)

crusso commented 3 years ago

@chenyan-dfinity I think I've figured out the bug - working on a fix unless you've already got one up your sleeve.

crusso commented 3 years ago

see #2531