Skip to content

Commit 7b055dd

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[cfe] Add work-around for partial inference
Type arguments in object patterns are only partially inferred and leads to crashing because of unknown types. This adds a work-around to fully infer the type arguments while waiting for the resolution of language issue #2770. Change-Id: I2af228b472414f0077c005105c971a4f84189e07 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280082 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 062b3aa commit 7b055dd

10 files changed

+167
-0
lines changed

pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10012,6 +10012,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase
1001210012
typeParametersToInfer, matchedType, libraryBuilder.library);
1001310013
List<DartType> inferredTypes = typeSchemaEnvironment.partialInfer(
1001410014
gatherer, typeParametersToInfer, null, libraryBuilder.library);
10015+
10016+
// TODO(johnniwinther): Remove this work-around once language issue #2770
10017+
// has been resolved.
10018+
inferredTypes = typeSchemaEnvironment.upwardsInfer(
10019+
gatherer, typeParametersToInfer, inferredTypes, libraryBuilder.library);
10020+
1001510021
Substitution substitution =
1001610022
Substitution.fromPairs(typeParametersToInfer, inferredTypes);
1001710023
return substitution.substituteType(typeToInfer);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2023, 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+
class Class<T extends Object> {
6+
T field;
7+
Class(this.field);
8+
}
9+
10+
method1(Object object) {
11+
if (object case Class(:var field)) {
12+
print(field);
13+
}
14+
}
15+
16+
main() {
17+
method1(new Class(42));
18+
method1(new Class('foo'));
19+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Class<T extends core::Object> extends core::Object {
6+
covariant-by-class field self::Class::T field;
7+
constructor •(self::Class::T field) → self::Class<self::Class::T>
8+
: self::Class::field = field, super core::Object::•()
9+
;
10+
}
11+
static method method1(core::Object object) → dynamic {
12+
{
13+
core::Object field;
14+
final core::Object #0#0 = object;
15+
if(#0#0 is{ForNonNullableByDefault} self::Class<core::Object> && (let final dynamic #t1 = field = #0#0{self::Class<core::Object>}.{self::Class::field}{core::Object} in true)) {
16+
core::print(field);
17+
}
18+
}
19+
}
20+
static method main() → dynamic {
21+
self::method1(new self::Class::•<core::int>(42));
22+
self::method1(new self::Class::•<core::String>("foo"));
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Class<T extends core::Object> extends core::Object {
6+
covariant-by-class field self::Class::T field;
7+
constructor •(self::Class::T field) → self::Class<self::Class::T>
8+
: self::Class::field = field, super core::Object::•()
9+
;
10+
}
11+
static method method1(core::Object object) → dynamic {
12+
{
13+
core::Object field;
14+
final core::Object #0#0 = object;
15+
if(#0#0 is{ForNonNullableByDefault} self::Class<core::Object> && (let final core::Object #t1 = field = #0#0{self::Class<core::Object>}.{self::Class::field}{core::Object} in true)) {
16+
core::print(field);
17+
}
18+
}
19+
}
20+
static method main() → dynamic {
21+
self::method1(new self::Class::•<core::int>(42));
22+
self::method1(new self::Class::•<core::String>("foo"));
23+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Class<T extends Object> {
2+
T field;
3+
Class(this.field);
4+
}
5+
6+
method1(Object object) {}
7+
main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Class<T extends Object> {
2+
Class(this.field);
3+
T field;
4+
}
5+
6+
main() {}
7+
method1(Object object) {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Class<T extends core::Object> extends core::Object {
6+
covariant-by-class field self::Class::T field;
7+
constructor •(self::Class::T field) → self::Class<self::Class::T>
8+
: self::Class::field = field, super core::Object::•()
9+
;
10+
}
11+
static method method1(core::Object object) → dynamic {
12+
{
13+
core::Object field;
14+
final core::Object #0#0 = object;
15+
if(#0#0 is{ForNonNullableByDefault} self::Class<core::Object> && (let final dynamic #t1 = field = #0#0{self::Class<core::Object>}.{self::Class::field}{core::Object} in true)) {
16+
core::print(field);
17+
}
18+
}
19+
}
20+
static method main() → dynamic {
21+
self::method1(new self::Class::•<core::int>(42));
22+
self::method1(new self::Class::•<core::String>("foo"));
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Class<T extends core::Object> extends core::Object {
6+
covariant-by-class field self::Class::T field;
7+
constructor •(self::Class::T field) → self::Class<self::Class::T>
8+
: self::Class::field = field, super core::Object::•()
9+
;
10+
}
11+
static method method1(core::Object object) → dynamic {
12+
{
13+
core::Object field;
14+
final core::Object #0#0 = object;
15+
if(#0#0 is{ForNonNullableByDefault} self::Class<core::Object> && (let final dynamic #t1 = field = #0#0{self::Class<core::Object>}.{self::Class::field}{core::Object} in true)) {
16+
core::print(field);
17+
}
18+
}
19+
}
20+
static method main() → dynamic {
21+
self::method1(new self::Class::•<core::int>(42));
22+
self::method1(new self::Class::•<core::String>("foo"));
23+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Class<T extends core::Object> extends core::Object {
6+
covariant-by-class field self::Class::T field;
7+
constructor •(self::Class::T field) → self::Class<self::Class::T>
8+
;
9+
}
10+
static method method1(core::Object object) → dynamic
11+
;
12+
static method main() → dynamic
13+
;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Class<T extends core::Object> extends core::Object {
6+
covariant-by-class field self::Class::T field;
7+
constructor •(self::Class::T field) → self::Class<self::Class::T>
8+
: self::Class::field = field, super core::Object::•()
9+
;
10+
}
11+
static method method1(core::Object object) → dynamic {
12+
{
13+
core::Object field;
14+
final core::Object #0#0 = object;
15+
if(#0#0 is{ForNonNullableByDefault} self::Class<core::Object> && (let final core::Object #t1 = field = #0#0{self::Class<core::Object>}.{self::Class::field}{core::Object} in true)) {
16+
core::print(field);
17+
}
18+
}
19+
}
20+
static method main() → dynamic {
21+
self::method1(new self::Class::•<core::int>(42));
22+
self::method1(new self::Class::•<core::String>("foo"));
23+
}

0 commit comments

Comments
 (0)