mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 21:18:03 +00:00
fix #34296, generic function instantiation should be checked eagerly
Change-Id: I8c6e0980c23d8ca2cb22db9411028b59be5eb8db Reviewed-on: https://dart-review.googlesource.com/72545 Reviewed-by: Vijay Menon <vsm@google.com> Commit-Queue: Jenny Messerly <jmesserly@google.com>
This commit is contained in:
parent
cd3ddede99
commit
be5cd6307f
|
@ -82,12 +82,14 @@ bindCall(obj, name) {
|
|||
///
|
||||
/// We need to apply the type arguments both to the function, as well as its
|
||||
/// associated function type.
|
||||
gbind(f, @rest typeArgs) {
|
||||
gbind(f, @rest List typeArgs) {
|
||||
GenericFunctionType type = JS('!', '#[#]', f, _runtimeType);
|
||||
type.checkBounds(typeArgs);
|
||||
// Create a JS wrapper function that will also pass the type arguments, and
|
||||
// tag it with the instantiated function type.
|
||||
var result =
|
||||
JS('', '(...args) => #.apply(null, #.concat(args))', f, typeArgs);
|
||||
var sig = JS('', '#[#].instantiate(#)', f, _runtimeType, typeArgs);
|
||||
fn(result, sig);
|
||||
return result;
|
||||
return fn(result, type.instantiate(typeArgs));
|
||||
}
|
||||
|
||||
dloadRepl(obj, field) => dload(obj, replNameLookup(obj, field), false);
|
||||
|
|
|
@ -536,7 +536,13 @@ class GenericFunctionType extends AbstractFunctionType {
|
|||
return _typeFormals = _typeFormalsFromFunction(_instantiateTypeParts);
|
||||
}
|
||||
|
||||
checkBounds(List typeArgs) {
|
||||
/// Checks that [typeArgs] satisfies the upper bounds of the [typeFormals],
|
||||
/// and throws a [TypeError] if they do not.
|
||||
void checkBounds(List typeArgs) {
|
||||
// If we don't have explicit type parameter bounds, the bounds default to
|
||||
// a top type, so there's nothing to check here.
|
||||
if (_instantiateTypeBounds == null) return;
|
||||
|
||||
var bounds = instantiateTypeBounds(typeArgs);
|
||||
var typeFormals = this.typeFormals;
|
||||
for (var i = 0; i < typeArgs.length; i++) {
|
||||
|
@ -554,11 +560,12 @@ class GenericFunctionType extends AbstractFunctionType {
|
|||
var boundsFn = _instantiateTypeBounds;
|
||||
if (boundsFn == null) {
|
||||
// The Dart 1 spec says omitted type parameters have an upper bound of
|
||||
// Object. However strong mode assumes `dynamic` for all purposes
|
||||
// (such as instantiate to bounds) so we use that here.
|
||||
// Object. However Dart 2 uses `dynamic` for the purpose of instantiate to
|
||||
// bounds, so we use that here.
|
||||
return List.filled(formalCount, _dynamic);
|
||||
}
|
||||
// If bounds are recursive, we need to apply type formals and return them.
|
||||
// Bounds can be recursive or depend on other type parameters, so we need to
|
||||
// apply type arguments and return the resulting bounds.
|
||||
return JS('List', '#.apply(null, #)', boundsFn, typeArgs);
|
||||
}
|
||||
|
||||
|
@ -738,10 +745,11 @@ getFunctionTypeMirror(AbstractFunctionType type) {
|
|||
bool isType(obj) => JS('', '#[#] === #', obj, _runtimeType, Type);
|
||||
|
||||
void checkTypeBound(type, bound, name) {
|
||||
// TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, it would
|
||||
// be nice to have similar optimizations for the subtype relation.
|
||||
if (JS('!', '#', isSubtype(type, bound))) return;
|
||||
|
||||
throwTypeError('type `$type` does not extend `$bound`'
|
||||
' of `$name`.');
|
||||
throwTypeError('type `$type` does not extend `$bound` of `$name`.');
|
||||
}
|
||||
|
||||
String typeName(type) => JS('', '''(() => {
|
||||
|
|
|
@ -476,7 +476,6 @@ number_identity2_test: RuntimeError # Issue 29920; Expect.isTrue(false) fails.
|
|||
number_identity_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
|
||||
numbers_test: RuntimeError # Issue 29920; Expect.equals(expected: <false>, actual: <true>) fails.
|
||||
parser_quirks_test: CompileTimeError
|
||||
partial_instantiation_eager_bounds_check_test: RuntimeError # Issue 34296
|
||||
regress_16640_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: E => {
|
||||
regress_22443_test: RuntimeError # Uncaught Expect.isTrue(false) fails.
|
||||
stack_overflow_stacktrace_test: RuntimeError # Issue 29920; RangeError: Maximum call stack size exceeded
|
||||
|
|
Loading…
Reference in a new issue