mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 07:31:43 +00:00
Do assignability checks on return/yield using the greatest closure of the context.
Without this fix, there is a risk that the unknown type ("?") will leak into kernel code via the "as" expression inserted for an implicit downcast. Change-Id: Iea7276c8489eff80fe32f33e53efd42571c94a89 Reviewed-on: https://dart-review.googlesource.com/26861 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
b81d8a1c33
commit
5710de9c78
|
@ -213,7 +213,13 @@ class ClosureContext {
|
|||
var expectedType = isYieldStar
|
||||
? _wrapAsyncOrGenerator(inferrer, returnContext)
|
||||
: returnContext;
|
||||
inferrer.checkAssignability(expectedType, type, expression, fileOffset);
|
||||
if (expectedType != null) {
|
||||
inferrer.checkAssignability(
|
||||
greatestClosure(inferrer.coreTypes, expectedType),
|
||||
type,
|
||||
expression,
|
||||
fileOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,6 +399,7 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
/// an implicit downcast if appropriate.
|
||||
Expression checkAssignability(DartType expectedType, DartType actualType,
|
||||
Expression expression, int fileOffset) {
|
||||
assert(expectedType == null || isKnown(expectedType));
|
||||
// We don't need to insert assignability checks when doing top level type
|
||||
// inference since top level type inference only cares about the type that
|
||||
// is inferred (the kernel code is discarded).
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
|
||||
bool f(List x) {
|
||||
return x.expand((y) {
|
||||
// Since y has type dynamic, y.split(',') has type dynamic, so an implicit
|
||||
// downcast is needed. The return context is Iterable<?>. We should
|
||||
// generate an implicit downcast to Iterable<dynamic>.
|
||||
return y.split(',');
|
||||
}).any((y) => y == 'z');
|
||||
}
|
||||
|
||||
main() {}
|
|
@ -0,0 +1,10 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static method f(core::List<dynamic> x) → core::bool {
|
||||
return x.expand((dynamic y) → dynamic {
|
||||
return y.split(",");
|
||||
}).any((dynamic y) → dynamic => y.==("z"));
|
||||
}
|
||||
static method main() → dynamic {}
|
|
@ -0,0 +1,8 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static method f(core::List<dynamic> x) → core::bool
|
||||
;
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -0,0 +1,10 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static method f(core::List<dynamic> x) → core::bool {
|
||||
return x.{core::Iterable::expand}<dynamic>((dynamic y) → core::Iterable<dynamic> {
|
||||
return y.split(",") as{TypeError} core::Iterable<dynamic>;
|
||||
}).{core::Iterable::any}((dynamic y) → core::bool => y.{core::Object::==}("z"));
|
||||
}
|
||||
static method main() → dynamic {}
|
|
@ -1244,6 +1244,7 @@ async_star_test/03: CompileTimeError # Issue 31402 (Invocation arguments)
|
|||
async_star_test/04: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
async_star_test/05: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
async_star_test/none: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
await_test: CompileTimeError # Issue 31541
|
||||
bad_named_parameters2_test/01: MissingCompileTimeError
|
||||
bad_named_parameters_test/01: MissingCompileTimeError
|
||||
bad_named_parameters_test/02: MissingCompileTimeError
|
||||
|
|
Loading…
Reference in a new issue