Skip to content

Commit

Permalink
[cfe] Implement spec update on generator element type
Browse files Browse the repository at this point in the history
The update can be found here:
https://github.com/dart-lang/language/pull/3218/files

Closes #53052

Change-Id: I08146a6ca09667cc5e0ebcd564e60f454d03a468
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320763
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
  • Loading branch information
chloestefantsova authored and Commit Queue committed Aug 16, 2023
1 parent c867de3 commit 4352f10
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,16 @@ abstract class ClosureContext {
if (isGenerator) {
if (isAsync) {
DartType yieldContext = inferrer.getTypeArgumentOf(
returnContext, inferrer.coreTypes.streamClass);
inferrer.typeSchemaEnvironment.getUnionFreeType(returnContext,
isNonNullableByDefault: inferrer.isNonNullableByDefault),
inferrer.coreTypes.streamClass);
return new _AsyncStarClosureContext(
inferrer, yieldContext, declaredReturnType, needToInferReturnType);
} else {
DartType yieldContext = inferrer.getTypeArgumentOf(
returnContext, inferrer.coreTypes.iterableClass);
inferrer.typeSchemaEnvironment.getUnionFreeType(returnContext,
isNonNullableByDefault: inferrer.isNonNullableByDefault),
inferrer.coreTypes.iterableClass);
return new _SyncStarClosureContext(
inferrer, yieldContext, declaredReturnType, needToInferReturnType);
}
Expand Down
45 changes: 45 additions & 0 deletions pkg/front_end/testcases/general/issue53052.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2023, 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';

FutureOr<Iterable<int>> f() sync* {
yield 'Hello!' as dynamic;
}

FutureOr<Stream<int>> g() async* {
yield* 'Hello!' as dynamic;
}

main() async {
var iterable = f();
if (iterable is Future<Object?>) return;
expectThrows(() { int i = iterable.first; });

var stream = g();
if (stream is Future<Object?>) return;
await expectAsyncThrows(() async { int i = await stream.first; });
}

expectThrows(f) {
bool hasThrown = true;
try {
f();
hasThrown = false;
} catch(e) {}
if (!hasThrown) {
throw "Expected the function to throw.";
}
}

expectAsyncThrows(f) async {
bool hasThrown = true;
try {
await f();
hasThrown = false;
} catch(e) {}
if (!hasThrown) {
throw "Expected the function to throw.";
}
}
51 changes: 51 additions & 0 deletions pkg/front_end/testcases/general/issue53052.dart.strong.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;

import "dart:async";

static method f() → FutureOr<core::Iterable<core::int>> sync* {
yield("Hello!" as dynamic) as{TypeError,ForDynamic} core::int;
}
static method g() → FutureOr<asy::Stream<core::int>> async* {
yield*("Hello!" as dynamic) as{TypeError,ForDynamic} asy::Stream<core::int>;
}
static method main() → dynamic async /* futureValueType= dynamic */ {
FutureOr<core::Iterable<core::int>>iterable = self::f();
if(iterable is asy::Future<core::Object?>)
return;
self::expectThrows(() → Null {
core::int i = iterable{core::Iterable<core::int>}.{core::Iterable::first}{core::int};
});
FutureOr<asy::Stream<core::int>>stream = self::g();
if(stream is asy::Future<core::Object?>)
return;
await self::expectAsyncThrows(() → asy::Future<Null> async /* futureValueType= Null */ {
core::int i = await stream{asy::Stream<core::int>}.{asy::Stream::first}{asy::Future<core::int>};
}) /* runtimeCheckType= asy::Future<dynamic> */ ;
}
static method expectThrows(dynamic f) → dynamic {
core::bool hasThrown = true;
try {
f{dynamic}.call();
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
static method expectAsyncThrows(dynamic f) → dynamic async /* futureValueType= dynamic */ {
core::bool hasThrown = true;
try {
await f{dynamic}.call() /* runtimeCheckType= asy::Future<dynamic> */ ;
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
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";

static method f() → FutureOr<core::Iterable<core::int>> sync* {
yield("Hello!" as dynamic) as{TypeError,ForDynamic} core::int;
}
static method g() → FutureOr<asy::Stream<core::int>> async* {
yield*("Hello!" as dynamic) as{TypeError,ForDynamic} asy::Stream<core::int>;
}
static method main() → dynamic async /* futureValueType= dynamic */ {
FutureOr<core::Iterable<core::int>>iterable = self::f();
if(iterable is asy::Future<core::Object?>)
return;
self::expectThrows(() → Null {
core::int i = iterable{core::Iterable<core::int>}.{core::Iterable::first}{core::int};
});
FutureOr<asy::Stream<core::int>>stream = self::g();
if(stream is asy::Future<core::Object?>)
return;
await self::expectAsyncThrows(() → asy::Future<Null> async /* futureValueType= Null */ {
core::int i = await stream{asy::Stream<core::int>}.{asy::Stream::first}{asy::Future<core::int>};
}) /* runtimeCheckType= asy::Future<dynamic> */ ;
}
static method expectThrows(dynamic f) → dynamic {
core::bool hasThrown = true;
try {
f{dynamic}.call();
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
static method expectAsyncThrows(dynamic f) → dynamic async /* futureValueType= dynamic */ {
core::bool hasThrown = true;
try {
await f{dynamic}.call() /* runtimeCheckType= asy::Future<dynamic> */ ;
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}


Extra constant evaluation status:
Evaluated: AsExpression @ org-dartlang-testcase:///issue53052.dart:8:18 -> StringConstant("Hello!")
Evaluated: AsExpression @ org-dartlang-testcase:///issue53052.dart:12:19 -> StringConstant("Hello!")
Extra constant evaluation: evaluated: 33, effectively constant: 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'dart:async';

FutureOr<Iterable<int>> f() sync* {}
FutureOr<Stream<int>> g() async* {}
main() async {}
expectThrows(f) {}
expectAsyncThrows(f) async {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'dart:async';

FutureOr<Iterable<int>> f() sync* {}
FutureOr<Stream<int>> g() async* {}
expectAsyncThrows(f) async {}
expectThrows(f) {}
main() async {}
51 changes: 51 additions & 0 deletions pkg/front_end/testcases/general/issue53052.dart.weak.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;

import "dart:async";

static method f() → FutureOr<core::Iterable<core::int>> sync* {
yield("Hello!" as dynamic) as{TypeError,ForDynamic} core::int;
}
static method g() → FutureOr<asy::Stream<core::int>> async* {
yield*("Hello!" as dynamic) as{TypeError,ForDynamic} asy::Stream<core::int>;
}
static method main() → dynamic async /* futureValueType= dynamic */ {
FutureOr<core::Iterable<core::int>>iterable = self::f();
if(iterable is asy::Future<core::Object?>)
return;
self::expectThrows(() → Null {
core::int i = iterable{core::Iterable<core::int>}.{core::Iterable::first}{core::int};
});
FutureOr<asy::Stream<core::int>>stream = self::g();
if(stream is asy::Future<core::Object?>)
return;
await self::expectAsyncThrows(() → asy::Future<Null> async /* futureValueType= Null */ {
core::int i = await stream{asy::Stream<core::int>}.{asy::Stream::first}{asy::Future<core::int>};
}) /* runtimeCheckType= asy::Future<dynamic> */ ;
}
static method expectThrows(dynamic f) → dynamic {
core::bool hasThrown = true;
try {
f{dynamic}.call();
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
static method expectAsyncThrows(dynamic f) → dynamic async /* futureValueType= dynamic */ {
core::bool hasThrown = true;
try {
await f{dynamic}.call() /* runtimeCheckType= asy::Future<dynamic> */ ;
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;

import "dart:async";

static method f() → FutureOr<core::Iterable<core::int>> sync* {
yield("Hello!" as dynamic) as{TypeError,ForDynamic} core::int;
}
static method g() → FutureOr<asy::Stream<core::int>> async* {
yield*("Hello!" as dynamic) as{TypeError,ForDynamic} asy::Stream<core::int>;
}
static method main() → dynamic async /* futureValueType= dynamic */ {
FutureOr<core::Iterable<core::int>>iterable = self::f();
if(iterable is asy::Future<core::Object?>)
return;
self::expectThrows(() → Null {
core::int i = iterable{core::Iterable<core::int>}.{core::Iterable::first}{core::int};
});
FutureOr<asy::Stream<core::int>>stream = self::g();
if(stream is asy::Future<core::Object?>)
return;
await self::expectAsyncThrows(() → asy::Future<Null> async /* futureValueType= Null */ {
core::int i = await stream{asy::Stream<core::int>}.{asy::Stream::first}{asy::Future<core::int>};
}) /* runtimeCheckType= asy::Future<dynamic> */ ;
}
static method expectThrows(dynamic f) → dynamic {
core::bool hasThrown = true;
try {
f{dynamic}.call();
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
static method expectAsyncThrows(dynamic f) → dynamic async /* futureValueType= dynamic */ {
core::bool hasThrown = true;
try {
await f{dynamic}.call() /* runtimeCheckType= asy::Future<dynamic> */ ;
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;

import "dart:async";

static method f() → FutureOr<core::Iterable<core::int>> sync*
;
static method g() → FutureOr<asy::Stream<core::int>> async*
;
static method main() → dynamic async
;
static method expectThrows(dynamic f) → dynamic
;
static method expectAsyncThrows(dynamic f) → dynamic async
;
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";

static method f() → FutureOr<core::Iterable<core::int>> sync* {
yield("Hello!" as dynamic) as{TypeError,ForDynamic} core::int;
}
static method g() → FutureOr<asy::Stream<core::int>> async* {
yield*("Hello!" as dynamic) as{TypeError,ForDynamic} asy::Stream<core::int>;
}
static method main() → dynamic async /* futureValueType= dynamic */ {
FutureOr<core::Iterable<core::int>>iterable = self::f();
if(iterable is asy::Future<core::Object?>)
return;
self::expectThrows(() → Null {
core::int i = iterable{core::Iterable<core::int>}.{core::Iterable::first}{core::int};
});
FutureOr<asy::Stream<core::int>>stream = self::g();
if(stream is asy::Future<core::Object?>)
return;
await self::expectAsyncThrows(() → asy::Future<Null> async /* futureValueType= Null */ {
core::int i = await stream{asy::Stream<core::int>}.{asy::Stream::first}{asy::Future<core::int>};
}) /* runtimeCheckType= asy::Future<dynamic> */ ;
}
static method expectThrows(dynamic f) → dynamic {
core::bool hasThrown = true;
try {
f{dynamic}.call();
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
static method expectAsyncThrows(dynamic f) → dynamic async /* futureValueType= dynamic */ {
core::bool hasThrown = true;
try {
await f{dynamic}.call() /* runtimeCheckType= asy::Future<dynamic> */ ;
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}


Extra constant evaluation status:
Evaluated: AsExpression @ org-dartlang-testcase:///issue53052.dart:8:18 -> StringConstant("Hello!")
Evaluated: AsExpression @ org-dartlang-testcase:///issue53052.dart:12:19 -> StringConstant("Hello!")
Extra constant evaluation: evaluated: 33, effectively constant: 2
Loading

0 comments on commit 4352f10

Please sign in to comment.