Skip to content

Commit 5d1fbe0

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Handle unforseen type parameter intersections
Closes #42089 Change-Id: Ifb0dc0073e004051ae40aed51db24b0d4b10f50d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152646 Reviewed-by: Dmitry Stefantsov <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 878e2ca commit 5d1fbe0

16 files changed

+493
-11
lines changed

pkg/front_end/test/spell_checking_list_code.txt

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ arises
5353
arising
5454
arity
5555
artifact
56+
artifacts
5657
artificial
5758
asgerf
5859
askesc
@@ -894,6 +895,7 @@ repeating
894895
replacements
895896
replacer
896897
replaces
898+
replicated
897899
repo
898900
repositories
899901
requirement
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
test<X>(X? x) {
6+
if (x is String?) {
7+
Object o = x;
8+
o = x;
9+
}
10+
}
11+
12+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
static method test<X extends core::Object? = dynamic>(self::test::X? x) → dynamic
6+
;
7+
static method main() → dynamic
8+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
6+
// - 'Object' is from 'dart:core'.
7+
// Object o = x;
8+
// ^
9+
//
10+
// pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
11+
// - 'Object' is from 'dart:core'.
12+
// o = x;
13+
// ^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
static method test<X extends core::Object? = dynamic>(self::test::X? x) → dynamic {
19+
if(x is{ForNonNullableByDefault} core::String?) {
20+
core::Object o = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
21+
- 'Object' is from 'dart:core'.
22+
Object o = x;
23+
^" in x{self::test::X? & core::String? /* '?' & '?' = '?' */} as{TypeError,ForNonNullableByDefault} core::Object;
24+
o = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
25+
- 'Object' is from 'dart:core'.
26+
o = x;
27+
^" in x{self::test::X? & core::String? /* '?' & '?' = '?' */} as{TypeError,ForNonNullableByDefault} core::Object;
28+
}
29+
}
30+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
6+
// - 'Object' is from 'dart:core'.
7+
// Object o = x;
8+
// ^
9+
//
10+
// pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
11+
// - 'Object' is from 'dart:core'.
12+
// o = x;
13+
// ^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
static method test<X extends core::Object? = dynamic>(self::test::X? x) → dynamic {
19+
if(x is{ForNonNullableByDefault} core::String?) {
20+
core::Object o = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
21+
- 'Object' is from 'dart:core'.
22+
Object o = x;
23+
^" in let self::test::X? & core::String? /* '?' & '?' = '?' */ #t2 = x{self::test::X? & core::String? /* '?' & '?' = '?' */} in #t2.==(null) ?{core::Object} #t2 as{TypeError,ForNonNullableByDefault} core::Object : #t2{core::Object};
24+
o = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
25+
- 'Object' is from 'dart:core'.
26+
o = x;
27+
^" in let self::test::X? & core::String? /* '?' & '?' = '?' */ #t4 = x{self::test::X? & core::String? /* '?' & '?' = '?' */} in #t4.==(null) ?{core::Object} #t4 as{TypeError,ForNonNullableByDefault} core::Object : #t4{core::Object};
28+
}
29+
}
30+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test<X>(X? x) {}
2+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
main() {}
2+
test<X>(X? x) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
6+
// - 'Object' is from 'dart:core'.
7+
// Object o = x;
8+
// ^
9+
//
10+
// pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
11+
// - 'Object' is from 'dart:core'.
12+
// o = x;
13+
// ^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
static method test<X extends core::Object? = dynamic>(self::test::X? x) → dynamic {
19+
if(x is{ForNonNullableByDefault} core::String?) {
20+
core::Object o = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
21+
- 'Object' is from 'dart:core'.
22+
Object o = x;
23+
^" in x{self::test::X? & core::String? /* '?' & '?' = '?' */} as{TypeError,ForNonNullableByDefault} core::Object;
24+
o = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
25+
- 'Object' is from 'dart:core'.
26+
o = x;
27+
^" in x{self::test::X? & core::String? /* '?' & '?' = '?' */} as{TypeError,ForNonNullableByDefault} core::Object;
28+
}
29+
}
30+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
6+
// - 'Object' is from 'dart:core'.
7+
// Object o = x;
8+
// ^
9+
//
10+
// pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
11+
// - 'Object' is from 'dart:core'.
12+
// o = x;
13+
// ^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
static method test<X extends core::Object? = dynamic>(self::test::X? x) → dynamic {
19+
if(x is{ForNonNullableByDefault} core::String?) {
20+
core::Object o = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:7:16: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
21+
- 'Object' is from 'dart:core'.
22+
Object o = x;
23+
^" in x{self::test::X? & core::String? /* '?' & '?' = '?' */};
24+
o = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue42089.dart:8:9: Error: A value of type 'X?' can't be assigned to a variable of type 'Object'.
25+
- 'Object' is from 'dart:core'.
26+
o = x;
27+
^" in x{self::test::X? & core::String? /* '?' & '?' = '?' */};
28+
}
29+
}
30+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'type_parameter_nullability_lib.dart';
6+
7+
class C<T extends num?, S, U> {
8+
void promoteNullable(T? t) {
9+
if (t is int) /* Creates T? & int! */ {
10+
t;
11+
}
12+
if (t is int?) /* Creates T? & int? */ {
13+
t;
14+
}
15+
}
16+
17+
void nullableAsUndetermined(S? s) {
18+
s as U; /* Creates S? & U% */
19+
}
20+
}
21+
22+
main() {
23+
var c = new C<num, num, num>();
24+
c.promoteNullable(null);
25+
c.promoteNullable(0);
26+
c.nullableAsUndetermined(null);
27+
c.nullableAsUndetermined(0);
28+
var d = new D<num>();
29+
d.promoteLegacy(null);
30+
d.promoteLegacy(0);
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'type_parameter_nullability_lib.dart';
2+
3+
class C<T extends num?, S, U> {
4+
void promoteNullable(T? t) {}
5+
void nullableAsUndetermined(S? s) {}
6+
}
7+
8+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'type_parameter_nullability_lib.dart';
2+
3+
class C<T extends num?, S, U> {
4+
void nullableAsUndetermined(S? s) {}
5+
void promoteNullable(T? t) {}
6+
}
7+
8+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
import "type_parameter_nullability_lib.dart" as typ;
5+
6+
import "org-dartlang-testcase:///type_parameter_nullability_lib.dart";
7+
8+
class C<T extends core::num? = core::num?, S extends core::Object? = dynamic, U extends core::Object? = dynamic> extends core::Object {
9+
synthetic constructor •() → self::C<self::C::T%, self::C::S%, self::C::U%>
10+
: super core::Object::•()
11+
;
12+
method promoteNullable(generic-covariant-impl self::C::T? t) → void {
13+
if(t is{ForNonNullableByDefault} core::int) {
14+
t{self::C::T? & core::int /* '?' & '!' = '!' */};
15+
}
16+
if(t is{ForNonNullableByDefault} core::int?) {
17+
t{self::C::T? & core::int? /* '?' & '?' = '?' */};
18+
}
19+
}
20+
method nullableAsUndetermined(generic-covariant-impl self::C::S? s) → void {
21+
s as{ForNonNullableByDefault} self::C::U%;
22+
}
23+
}
24+
static method main() → dynamic {
25+
self::C<core::num, core::num, core::num> c = new self::C::•<core::num, core::num, core::num>();
26+
c.{self::C::promoteNullable}(null);
27+
c.{self::C::promoteNullable}(0);
28+
c.{self::C::nullableAsUndetermined}(null);
29+
c.{self::C::nullableAsUndetermined}(0);
30+
typ::D<core::num> d = new typ::D::•<core::num>();
31+
d.{typ::D::promoteLegacy}(null);
32+
d.{typ::D::promoteLegacy}(0);
33+
}
34+
35+
library;
36+
import self as typ;
37+
import "dart:core" as core;
38+
39+
class D<T extends core::num* = core::num*> extends core::Object {
40+
synthetic constructor •() → typ::D<typ::D::T*>*
41+
: super core::Object::•()
42+
;
43+
method promoteLegacy(generic-covariant-impl typ::D::T* t) → void {
44+
if(t is core::int*) {
45+
let final typ::D::T* & core::int* /* '*' & '*' = '*' */ #t1 = t{typ::D::T* & core::int* /* '*' & '*' = '*' */} in #t1.{core::num::==}(null) ?{core::bool*} null : #t1.{core::int::isEven};
46+
}
47+
}
48+
abstract member-signature get _identityHashCode() → core::int*;
49+
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
50+
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
51+
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
52+
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
53+
abstract member-signature operator ==(dynamic other) → core::bool*;
54+
abstract member-signature get hashCode() → core::int*;
55+
abstract member-signature method toString() → core::String*;
56+
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
57+
abstract member-signature get runtimeType() → core::Type*;
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
import "type_parameter_nullability_lib.dart" as typ;
5+
6+
import "org-dartlang-testcase:///type_parameter_nullability_lib.dart";
7+
8+
class C<T extends core::num? = core::num?, S extends core::Object? = dynamic, U extends core::Object? = dynamic> extends core::Object {
9+
synthetic constructor •() → self::C<self::C::T%, self::C::S%, self::C::U%>
10+
: super core::Object::•()
11+
;
12+
method promoteNullable(generic-covariant-impl self::C::T? t) → void {
13+
if(t is{ForNonNullableByDefault} core::int) {
14+
t{self::C::T? & core::int /* '?' & '!' = '!' */};
15+
}
16+
if(t is{ForNonNullableByDefault} core::int?) {
17+
t{self::C::T? & core::int? /* '?' & '?' = '?' */};
18+
}
19+
}
20+
method nullableAsUndetermined(generic-covariant-impl self::C::S? s) → void {
21+
s as{ForNonNullableByDefault} self::C::U%;
22+
}
23+
}
24+
static method main() → dynamic {
25+
self::C<core::num, core::num, core::num> c = new self::C::•<core::num, core::num, core::num>();
26+
c.{self::C::promoteNullable}(null);
27+
c.{self::C::promoteNullable}(0);
28+
c.{self::C::nullableAsUndetermined}(null);
29+
c.{self::C::nullableAsUndetermined}(0);
30+
typ::D<core::num> d = new typ::D::•<core::num>();
31+
d.{typ::D::promoteLegacy}(null);
32+
d.{typ::D::promoteLegacy}(0);
33+
}
34+
35+
library;
36+
import self as typ;
37+
import "dart:core" as core;
38+
39+
class D<T extends core::num* = core::num*> extends core::Object {
40+
synthetic constructor •() → typ::D<typ::D::T*>*
41+
: super core::Object::•()
42+
;
43+
method promoteLegacy(generic-covariant-impl typ::D::T* t) → void {
44+
if(t is core::int*) {
45+
let final typ::D::T* & core::int* /* '*' & '*' = '*' */ #t1 = t{typ::D::T* & core::int* /* '*' & '*' = '*' */} in #t1.{core::num::==}(null) ?{core::bool*} null : #t1.{core::int::isEven};
46+
}
47+
}
48+
abstract member-signature get _identityHashCode() → core::int*;
49+
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
50+
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
51+
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
52+
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
53+
abstract member-signature operator ==(dynamic other) → core::bool*;
54+
abstract member-signature get hashCode() → core::int*;
55+
abstract member-signature method toString() → core::String*;
56+
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
57+
abstract member-signature get runtimeType() → core::Type*;
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// @dart=2.6
6+
7+
class D<T extends num> {
8+
void promoteLegacy(T t) {
9+
if (t is int) {
10+
t?.isEven; // Creates T* & int!
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)