Skip to content

Commit

Permalink
[cfe] Eliminate UnknownType in async type downcasts
Browse files Browse the repository at this point in the history
Cherry Pick CL for #42615

Closes #43013.

Bug: #42615
Change-Id: Ieb289acee04b3868304d320d3c2231fd6eb94dd6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154322
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
  • Loading branch information
a-siva authored and athomas committed Aug 12, 2020
1 parent 6eb1765 commit ed43bcf
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,8 @@ class _AsyncClosureContext implements ClosureContext {
statement.expression = inferrer.ensureAssignable(
futureValueType, expressionType, statement.expression,
fileOffset: statement.expression.fileOffset,
runtimeCheckedType: _returnContext,
runtimeCheckedType:
inferrer.computeGreatestClosure2(_returnContext),
isVoidAllowed: false)
..parent = statement;
}
Expand Down Expand Up @@ -559,7 +560,8 @@ class _AsyncClosureContext implements ClosureContext {
statement.expression,
fileOffset: statement.fileOffset,
isVoidAllowed: true,
runtimeCheckedType: _returnContext);
runtimeCheckedType:
inferrer.computeGreatestClosure(_returnContext));
statement.expression = expression..parent = statement;
}

Expand Down
15 changes: 15 additions & 0 deletions pkg/front_end/testcases/general/issue42615.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

class Class<T> {
Class({FutureOr<List<T>> Function() a});
}

dynamic method() => null;

main() {
Class(a: () async => method());
}
24 changes: 24 additions & 0 deletions pkg/front_end/testcases/general/issue42615.dart.outline.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
library;
import self as self;
import "dart:core" as core;

import "dart:async";

class Class<T extends core::Object* = dynamic> extends core::Object {
constructor •({() →* FutureOr<core::List<self::Class::T*>*>* a}) → self::Class<self::Class::T*>*
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
static method method() → dynamic
;
static method main() → dynamic
;
30 changes: 30 additions & 0 deletions pkg/front_end/testcases/general/issue42615.dart.strong.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
library;
import self as self;
import "dart:core" as core;

import "dart:async";

class Class<T extends core::Object* = dynamic> extends core::Object {
constructor •({() →* FutureOr<core::List<self::Class::T*>*>* a = #C1}) → self::Class<self::Class::T*>*
: super core::Object::•()
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
static method method() → dynamic
return null;
static method main() → dynamic {
new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* async => self::method() as{TypeError} FutureOr<core::List<dynamic>*>*);
}

constants {
#C1 = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;

import "dart:async";

class Class<T extends core::Object* = dynamic> extends core::Object {
constructor •({() →* FutureOr<core::List<self::Class::T*>*>* a = #C1}) → self::Class<self::Class::T*>*
: super core::Object::•()
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
static method method() → dynamic
return null;
static method main() → dynamic {
new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* /* originally async */ {
final asy::_AsyncAwaitCompleter<core::List<dynamic>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<dynamic>*>();
FutureOr<core::List<dynamic>*>* :return_value;
dynamic :async_stack_trace;
(dynamic) →* dynamic :async_op_then;
(core::Object*, core::StackTrace*) →* dynamic :async_op_error;
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
:return_value = self::method() as{TypeError} FutureOr<core::List<dynamic>*>*;
break #L1;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
return;
}
on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
:async_completer.{asy::Completer::completeError}(exception, stack_trace);
}
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
return :async_completer.{asy::Completer::future};
});
}

constants {
#C1 = null
}

0 comments on commit ed43bcf

Please sign in to comment.