eclipse-archived/ceylon

problem with shortcut refinement of generics

Closed this issue · 3 comments

Consider:

abstract class Foo()
{
    shared formal Value foo<Value>(Value something);
}

final class Bar()
    extends Foo()
{
    foo = Bar().foo;
    
    Float float = foo(1.0);
}

I get the following errors in line Float float = foo(1.0);:

Specified expression must be assignable to declared type of float of Bar with strict null checking: Value is not assignable to Float
Argument must be assignable to parameter something of foo in Bar: Float is not assignable to Value

Additionally, if I replace the line foo = Bar().foo; with foo = identity;, I get the following error in that line:

Specified expression must be assignable to declared type of foo of Foo with strict null checking: <Value> => Value(Value) is not assignable to <Value> => Value(Value)

@gavinking told me shortcut refinement assignment for generic functions is not supported, but even then, the errors don't really imply that (they are not even on the offending assignment!), and the following supposedly unsupported code happily compiles:

abstract class Foo()
{
	shared formal Value foo<Value>();
}

final class Bar()
	extends Foo()
{
	foo = Bar().foo;
	
	value float = foo<Float>();
	value huh = foo();
}

If I tell IntelliJ to explicit the type of either float or huh, it will incorrectly explicit Value for both.

My initial analysis of this problem was way off base. It turns out that you can do shortcut refinement on generic methods. Or, at least, you're supposed to be able to, but it's simply broken.

@gavinking

Well, I'm glad. It feels like allowing such thing is a good quality-of-life feature to the language. My usecase was to create a custom immutable Map on top of the map function. For example:

class CustomMap()
	satisfies Map<String, Float>
{
	import ceylon.language {map}
	
	value foo = map<String, Float>(somethingHereProbablyAParameter);
	
	iterator = foo.iterator;
	defines = foo.defines;
	get = foo.get;
	getOrDefault = foo.getOrDefault; // generic overriden with shortcut refinement assignment
}

Fixed.