Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG/HELP] Extends Array does not compile #1351

Closed
bakasura980 opened this issue Jun 24, 2020 · 14 comments
Closed

[BUG/HELP] Extends Array does not compile #1351

bakasura980 opened this issue Jun 24, 2020 · 14 comments
Labels

Comments

@bakasura980
Copy link

Hello,

Version: assemblyscript@0.12.3
Story: I upgraded assemblyscript package to the last version and the code stops compiling. It does however with version 0.9.4

Summary: I went deeper and managed to find that extending an array returns a lot of errors on the compilation.

Code

export class MyArray extends Array<u8> { }

Compilation Log

ERROR AS202: Type 'i32' cannot be changed to type 'u8'.

     store<T>(base + (<usize>lastIndex << alignof<T>()), changetype<T>(0));
                                                         ~~~~~~~~~~~~~~~~
 in ~lib/array.ts(370,57)

ERROR AS102: User-defined: "Cannot call flat() on Array<T> where T is not an Array."

       ERROR("Cannot call flat() on Array<T> where T is not an Array.");
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(499,7)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

       size += child == 0 ? 0 : load<i32>(child, offsetof<T>("length_"));
                                                          ~
 in ~lib/array.ts(509,58)

ERROR AS220: Expression must be a compile-time constant.

       size += child == 0 ? 0 : load<i32>(child, offsetof<T>("length_"));
                                                 ~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(509,49)

ERROR TS2329: Index signature is missing in type 'u8'.

     var byteLength = <usize>size << usize(alignof<valueof<T>>());
                                                           ~
 in ~lib/array.ts(513,59)

ERROR TS2558: Expected 1 type arguments, but got 0.

     var byteLength = <usize>size << usize(alignof<valueof<T>>());
                                           ~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(513,43)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

     var result = __alloc(offsetof<T>(), idof<T>());
                                   ~
 in ~lib/array.ts(517,35)

ERROR AS203: Operation 'idof' cannot be applied to type 'u8'.

     var result = __alloc(offsetof<T>(), idof<T>());
                                              ~
 in ~lib/array.ts(517,46)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

     store<i32>(result, size, offsetof<T>("length_"));
                                       ~
 in ~lib/array.ts(518,39)

ERROR AS220: Expression must be a compile-time constant.

     store<i32>(result, size, offsetof<T>("length_"));
                              ~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(518,30)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

     store<i32>(result, byteLength, offsetof<T>("byteLength"));
                                             ~
 in ~lib/array.ts(521,45)

ERROR AS220: Expression must be a compile-time constant.

     store<i32>(result, byteLength, offsetof<T>("byteLength"));
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(521,36)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

     store<usize>(result, dataStart, offsetof<T>("dataStart"));
                                              ~
 in ~lib/array.ts(522,46)

ERROR AS220: Expression must be a compile-time constant.

     store<usize>(result, dataStart, offsetof<T>("dataStart"));
                                     ~~~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(522,37)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

     store<usize>(result, __retain(dataStart), offsetof<T>("buffer"));
                                                        ~
 in ~lib/array.ts(523,56)

ERROR AS220: Expression must be a compile-time constant.

     store<usize>(result, __retain(dataStart), offsetof<T>("buffer"));
                                               ~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(523,47)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

       let childDataLength = load<i32>(child, offsetof<T>("byteLength"));
                                                       ~
 in ~lib/array.ts(534,55)

ERROR AS220: Expression must be a compile-time constant.

       let childDataLength = load<i32>(child, offsetof<T>("byteLength"));
                                              ~~~~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(534,46)

ERROR AS203: Operation 'offsetof' cannot be applied to type 'u8'.

         load<usize>(child, offsetof<T>("dataStart")),
                                     ~
 in ~lib/array.ts(537,37)

ERROR AS220: Expression must be a compile-time constant.

         load<usize>(child, offsetof<T>("dataStart")),
                            ~~~~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(537,28)

ERROR TS2329: Index signature is missing in type 'u8'.

     if (isManaged<valueof<T>>()) {
                           ~
 in ~lib/array.ts(546,27)

ERROR TS2558: Expected 1 type arguments, but got 0.

     if (isManaged<valueof<T>>()) {
                   ~~~~~~~~~~
 in ~lib/array.ts(546,19)

ERROR TS2329: Index signature is missing in type 'u8'.

         __retain(load<usize>(dataStart + (<usize>i << usize(alignof<valueof<T>>()))));
                                                                             ~
 in ~lib/array.ts(548,77)

ERROR TS2558: Expected 1 type arguments, but got 0.

         __retain(load<usize>(dataStart + (<usize>i << usize(alignof<valueof<T>>()))));
                                                             ~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(548,61)

ERROR AS202: Type 'usize' cannot be changed to type 'u8'.

     return changetype<T>(result);
            ~~~~~~~~~~~~~~~~~~~~~
 in ~lib/array.ts(552,12)

WARNING AS232: Exported generic function or class has no concrete instances.

   map<U>(fn: (value: T, index: i32, array: Array<T>) => U): Array<U> {
   ~~~
 in ~lib/array.ts(312,3)

WARNING AS232: Exported generic function or class has no concrete instances.

   reduce<U>(
   ~~~~~~
 in ~lib/array.ts(337,3)

WARNING AS232: Exported generic function or class has no concrete instances.

   reduceRight<U>(
   ~~~~~~~~~~~
 in ~lib/array.ts(348,3)
@MaxGraey
Copy link
Member

MaxGraey commented Jun 24, 2020

Did you update as-pect to 0.4.x?

UPDATE Reproduced here

@MaxGraey
Copy link
Member

Quick workaround:

export class MyArray extends Uint8Array {
}

If it's possible

@MaxGraey
Copy link
Member

MaxGraey commented Jun 24, 2020

Or don't export MyArray. Currently problem relate to methods which return generic parameter T or accept extra parameter U like map<U> and reduce<U> / reduceRight<U>. So since U unresolved this cause to problems. Previous version (0.9.4) was simply unsound to such of edge cases

@bakasura980
Copy link
Author

Thank you so much for your help. Just to be on the same page -> Is it some kind of bug? If so, could we expect to be fixed in one of the next releases?

If, however, this is the expected behavior, that means there is no way to extend Array, right?

@MaxGraey
Copy link
Member

MaxGraey commented Jun 24, 2020

You could extend Array but you can't export such extended class as well as any other generic class or method cross wasm module boundary.

So this absolutely valid as you can see:
https://webassembly.studio/?f=j7a6mfqz1x

But not:

export function boo<T>(): void {} // `T` unresolved during export to JavaScript or other host

or

export class Foo<T> {} // `T` unresolved during export to JavaScript or other host

or

export class Boo extends Foo<u8> {
   flat<U>(): u8 { return 0 } // `U` unresolved during export to JavaScript or other host
}

All that cases will print warnings

@dcodeIO
Copy link
Member

dcodeIO commented Jun 24, 2020

The reason why this is failing is that Array<u8> is exported (by means of exporting a subclass), so the compiler attempts to compile all of its methods, which it can't do for Array<u8>#flat because it is designed to emit a compile-time error when T is not an array. As such, this is not so much about the generic export but more about the compiler attempting to compile that specific method.

Given that this is failing in an unexpected way, I suggest changing this line to a throw instead and adding its error message here, so it becomes a runtime error (currently abort) instead of a compile time error, in turn fixing this issue as long as Array<u8>#flat is never called.

@dcodeIO dcodeIO added bug and removed question labels Jun 24, 2020
@MaxGraey
Copy link
Member

MaxGraey commented Jun 24, 2020

@dcodeIO It's just half of problem. I tried just overload CustomArray#flat and errors relate to flat is gone but we still have similar problems for Array#map<U> and Array#reduce<U> / Array#reduceRight<U>

However I'll try make PR which expose such changes. Will see what happens

@MaxGraey
Copy link
Member

MaxGraey commented Jun 24, 2020

@dcodeIO So #1353 fix only one case when:

export class MyArray extends Array<i32> {}

But we still have issues for this case (when type is u8 instead i32):

export class MyArray extends Array<u8> {}

Output:

ERROR AS202: Type 'i32' cannot be changed to type 'u8'.

       store<T>(base + (<usize>lastIndex << alignof<T>()), changetype<T>(0));

 in ~lib/array.ts(370,57)

@dcodeIO
Copy link
Member

dcodeIO commented Jun 24, 2020

Maybe something like

if (isReference<T>()) {
  store<usize>(base + (<usize>lastIndex << alignof<T>()), 0);
} else {
  store<T>(base + (<usize>lastIndex << alignof<T>()), 0);
}

@MaxGraey
Copy link
Member

Currently I just switched to store<T>(base + (<usize>lastIndex << alignof<T>()), <T>0)

@dcodeIO
Copy link
Member

dcodeIO commented Jun 24, 2020

But does this work on export class MyArray extends Array<string> {}?

@MaxGraey
Copy link
Member

You're right.

@MaxGraey
Copy link
Member

Should be fixed in next minor release

@bakasura980
Copy link
Author

@MaxGraey and @dcodeIO, Thank you guys for your support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants