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

dart2js: use of generic type parameter as literal in constant expression yields compilation error #12287

Closed
DartBot opened this issue Aug 7, 2013 · 15 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@DartBot
Copy link

DartBot commented Aug 7, 2013

This issue was originally filed by ross.dart.la...@gmail.com


0.6.15_r25822
Windows 7x64

Consider the following program:

////////////////////////////////////////////////
class A<T> {
  final Type type = T;
  const A();
}

main() {
  print('${const A<int>().type}');
}
////////////////////////////////////////////////

In the Dart vm, this prints:

int

With dart2js, this used to do the same. As of this release, it generates a compilation error and then goes on to print 'int':

D:/github/bug/test.dart:85:21: Error: Not a compile-time constant.
  final Type type = T;

                    ^
Error: Compilation failed.
int

thanks,

@sethladd
Copy link
Contributor

sethladd commented Aug 7, 2013

Added Area-Dart2JS, Triaged labels.

@DartBot
Copy link
Author

DartBot commented Aug 14, 2013

This comment was originally written by ngeoffray@google.com


dart2js is right here, this is not a compile-time constant. So this is actually a VM bug.


Removed Area-Dart2JS label.
Added Area-VM label.

@DartBot
Copy link
Author

DartBot commented Aug 14, 2013

This comment was originally written by ross.dart.la...@gmail.com


From the spec (https://www.dartlang.org/docs/spec/latest/dart-language-specification.html#id.hzs87hup8wb):

"An identifier expression that denotes a constant variable or a class."

Is "T" here not an identifier expression that denotes a class?

@peter-ahe-google
Copy link
Contributor

You can think of a type variable as a final instance variable.

'T' is an identifier that denotes a type variable. The value of that type variable may be a class, or a function type (the latter is not recognized by the specification as a compile-time constant, but in this case, it is a bug in the specification).

@DartBot
Copy link
Author

DartBot commented Aug 14, 2013

This comment was originally written by ross.dart...@gmail.com


Okay, so back to the reported error:

D:/github/bug/test.dart:85:21: Error: Not a compile-time constant.
  final Type type = T;

If all forms of type variables are compile-time constant (assuming spec bug regarding function types) is this error from dart2js still valid?

thanks :)

@DartBot
Copy link
Author

DartBot commented Aug 14, 2013

This comment was originally written by ross.dart...@gmail.com


Hmm okay on further thought I think I was confusing the type variable and its value, sorry for the noise.

@iposva-google
Copy link
Contributor

cc @gbracha.
cc @mhausner.
Set owner to @crelier.
Added Accepted label.

@peter-ahe-google
Copy link
Contributor

I think Ross realized this, but just for the record: a type variable is not a compile-time constant.

And, Ross: thank you for the bug report. When dart2js and the VM disagree, clearly there is a bug somewhere. So this is not noise :-)

@crelier
Copy link
Contributor

crelier commented Aug 14, 2013

The initializer of a final variable does not need to be a compile-time constant expression.
The initializer of a const variable must be a compile-time constant expression, but only static variables can be const, so the type expression 'T' will never be seen in its uninstantiated form.
I'll wait for Gilad to confirm before reassigning this bug to dart2js.

@gbracha
Copy link
Contributor

gbracha commented Aug 14, 2013

So to be clear.

(1) T is not a compile-time constant.

(2) An instance variable, final or not need not be initialized to a compile-time constant.

(3) There is a restriction that initializers of instance variables may not refer to 'this'.

(4) T is NOT a reference to 'this'.

(5) The bug is in dart2js.

@peter-ahe-google
Copy link
Contributor

So T is not a compile time constant.

Neither is [].

So would this be fine:

class A {
  final list = [];
  const A();
}

main() {
  const A().list.add('a b c');
}

@iposva-google
Copy link
Contributor

Removed the owner.
Removed Area-VM label.
Added Area-Dart2JS, Triaged labels.

@peter-ahe-google
Copy link
Contributor

Set owner to @gbracha.
Removed Area-Dart2JS label.
Added Area-Language label.

@gbracha
Copy link
Contributor

gbracha commented Aug 14, 2013

Re comment 11. Yes, the spec is missing some restriction. Clearly when we liberalized the rules for instance variable initialization I neglected to modify the rules for const objects.

There are however at least two valid rules one could introduce. One is the one you seem to suggest (though you never actually state it), which is that in a const class (a class with a const constructor) instance variables initializers must be restricted compile time constants. I assume this is what dart2js implements.

The alternative is what the VM implements, which is that a constant object may only refer to constant objects. This is slightly more flexible, because the type variables of a class are going to be ultimately bound to constants.

We allow parameters to const constructors as long as they can be shown to be constant at the call site. Type parameters are always constant at the original call site. So it seems unnecessarily restrictive to disallow their use in this case.


Added Accepted label.

@DartBot DartBot added Type-Defect area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Aug 14, 2013
@kevmoo kevmoo added type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed priority-unassigned labels Feb 29, 2016
@lrhn
Copy link
Member

lrhn commented Jun 22, 2018

The specification now says:

It is a compile-time error if a constant constructor is declared by a class C if any instance variable declared in C is initialized with an expression that is not a constant expression.

Since T is still not constant, the dart2js behavior reported here is now correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

8 participants