-
Notifications
You must be signed in to change notification settings - Fork 28
#3057. Add promotion via type test tests. Check top and bottom types and Null #3165
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
base: master
Are you sure you want to change the base?
Conversation
…om types and Null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I'm suggesting that a couple of tests should be deleted, because they unfold some cases where the test is basically not possible to perform ("check how this promotion works, except that this promotion never occurs").
Also, a couple of typos.
test4() { | ||
Object? s = 1 > 2 ? null : "a"; | ||
if (s is FutureOr<void>) { // ignore: unnecessary_type_check | ||
s.expectStaticType<Exactly<Object?>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one won't actually fail in the case where the type of s
is changed to FutureOr<void>
.
Let's assume that s
does have type FutureOr<void>
here. We should then be able to test for Future<void>
, and in the false continuation of that test s
should have type void
, so we should be able to see that by getting an error at s.hashCode
.
So if it works correctly then s
won't have type void
at that point and s.hashCode
is not an error.
test1() { | ||
Object? o = 1 > 2 ? null : "a"; | ||
if (o is Void) { // ignore: unnecessary_type_check | ||
print(o); // `void` <: `Object?`, `o` promoted to `void` and cannot be used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, o
should not be promoted because void
is not a proper subtype of Object?
(so S <: T
, that is, "not S <: T
" doesn't hold, so the promotion step cannot be taken).
(Note that the rules already imply this, so we don't actually need to wait for clarification of anything in order to be able to say that promotion only promotes to proper subtypes, that's already what the spec says).
test2() { | ||
dynamic d = 42; | ||
if (d is Void) { // ignore: unnecessary_type_check | ||
print(d); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing: The test is fine if we just change the expectation to "no error" because d
still has the type dynamic
.
main() { | ||
dynamic d = "a"; | ||
if (d is Object?) { // ignore: unnecessary_type_check | ||
d.expectStaticType<Exactly<Object?>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't promote from dynamic
to Object?
, but this test won't tell us that d
still has the type dynamic
before run time (it will throw because there is no such method).
Perhaps use if (1 > 2) d.testDynamic;
instead?
Object? o = 1 > 2 ? null : "a"; | ||
if (o is dynamic) { // ignore: unnecessary_type_check | ||
try { | ||
o.whatever; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just expect an error here: There are no other tests in this library, so it's not a problem if we change it from being a "compiles and runs" test into an "encounters compile-time errors" test.
(Or would that imply that the test should have a different name because error tests and non-error tests can somehow be recognized by their names? In that case I guess it could just be renamed).
/// - and `T <: S` or (`S` is `X extends R` and `T <: R`) or (`S` is `X & R` and | ||
/// `T <: R`) | ||
/// | ||
/// @description Checks that a variable is promoted after the type test in one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo:
/// @description Checks that a variable is promoted after the type test in one | |
/// @description Checks that if a variable is promoted after the type test in one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the same phrase occurs in all the tests following this one.
/// | ||
/// @description Checks that a variable is promoted after the type test in one | ||
/// of the branches, then is is not promoted in another branch and after it. | ||
/// Test type `void`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid I'd recommend that this particular test is deleted.
The point is that a variable can never be promoted to have type void
(because it would then have to have at least a declared type which is a proper supertype of void
, and there is no such type). So we can't even get started investigating how a promotion to void
would work, because they don't exist.
/// | ||
/// @description Checks that a variable is promoted after the type test in one | ||
/// of the branches, then is is not promoted in another branch and after it. | ||
/// Test type `dynamic`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
/// | ||
/// @description Checks that a variable is promoted after the type test in one | ||
/// of the branches, then is is not promoted in another branch and after it. | ||
/// Test type `Object?`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And again same here.
test1() { | ||
String? s = 1 > 2 ? null : "a"; | ||
if (s is Never) { | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do have another test (or several) about the outcome of testing for Never
, but it might still be good for the overall consistency and readability of this test to add this to the "then" part:
s.expectStaticType<Exactly<String?>>(); // Dead code and no promotion.
No description provided.