ceylon / ceylon-js

DEPRECATED
Apache License 2.0
54 stars 9 forks source link

member type aliases unavailable at runtime #554

Closed jvasileff closed 9 years ago

jvasileff commented 9 years ago

This:

class Foo<T>() {
    shared alias U => T;
}

void fun<T>() {}

shared void run() {
    fun<Foo<String>.U>();
}

results in:

$ ceylon compile-js && ceylon run-js simple
Note: Created module simple/1.0.0

/private/tmp/simple/modules/simple/1.0.0/simple-1.0.0.js:21
foo$.U$Foo=function(){var foo$=this,$2=foo$.$$targs$$.T$Foo;$2.$crtmm$=functio
                                                     ^
TypeError: Cannot read property 'T$Foo' of undefined
    at $init$Foo.foo$.U$Foo (/private/tmp/simple/modules/simple/1.0.0/simple-1.0.0.js:21:54)
    at run (/private/tmp/simple/modules/simple/1.0.0/simple-1.0.0.js:31:29)
    at [eval]:1:282
    at Object.<anonymous> ([eval]-wrapper:6:22)
    at Module._compile (module.js:456:26)
    at evalScript (node.js:536:25)
    at startup (node.js:80:7)
    at node.js:906:3

BTW - I think I have some really cool higher order generics code that would work if just this one issue were fixed!

chochos commented 9 years ago

Foo.U only works on instances of Foo, not on the type directly, because it requires the instance's type arguments.

jvasileff commented 9 years ago

According to 3.2.10 in the spec, isn't all of this supposed to be resolved at compile time?

Although, I guess it's not clear to me whether making the original example work would be enough to also make higher order generics with type aliases for type lambdas work.

For reference, the use case is exactly the toString call at line 100 https://github.com/ceylon/ceylon-spec/blob/master/test/main/functor/functors.ceylon#L100, which is parameterized like:

toString<String, MapFunctor<Integer,String>.Mapish>(MapFunctor(map));
gavinking commented 9 years ago

@jvasileff Well this is a pretty interesting one which I had forgotten was even possible.

The typechecker definitely knows how to handle it, and clearly sees that the type Foot<String>.U is exactly the type String. But it doesn't do that replacement automatically.

What I'm thinking is that @chochos just needs to explicitly call resolveAliases() somewhere, to replace the alias at compile time.

chochos commented 9 years ago

OK I'll look into it

jvasileff commented 9 years ago

Cool, so this works for me now.

But the type lambda use case still fails. Should I create an issue for that? (Not sure if you guys are looking for bug reports on experimental features...)

gavinking commented 9 years ago

@jvasileff I figure we may as well start collecting the bugs as issues, though they aren't a priority for 1.2, of course.