[kernel] Account for defaultType in some of the Kernel visitors

Fixes #33324

Bug: http://dartbug.com/33324
Change-Id: I6c6a503a1fe016d7a8743df1597660c979ce27ea
Reviewed-on: https://dart-review.googlesource.com/58720
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
This commit is contained in:
Dmitry Stefantsov 2018-06-06 12:44:51 +00:00 committed by commit-bot@chromium.org
parent c39c2c8ac1
commit 05f11aa74c
19 changed files with 98 additions and 28 deletions

View file

@ -0,0 +1,15 @@
// Copyright (c) 2018, 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.
// This test checks that the greatest closure uses 'dynamic' and not Object as
// the top type.
int foo() {
Function f = (x) => x;
var l = ["bar"].map(f).toList();
l.add(42);
return l.first.length;
}
main() {}

View file

@ -0,0 +1,11 @@
library;
import self as self;
import "dart:core" as core;
static method foo() → core::int {
core::Function f = (dynamic x) → dynamic => x;
dynamic l = <dynamic>["bar"].map(f).toList();
l.add(42);
return l.first.length;
}
static method main() → dynamic {}

View file

@ -0,0 +1,11 @@
library;
import self as self;
import "dart:core" as core;
static method foo() → core::int {
core::Function f = (dynamic x) → dynamic => x;
dynamic l = <dynamic>["bar"].map(f).toList();
l.add(42);
return l.first.length;
}
static method main() → dynamic {}

View file

@ -0,0 +1,8 @@
library;
import self as self;
import "dart:core" as core;
static method foo() → core::int
;
static method main() → dynamic
;

View file

@ -0,0 +1,11 @@
library;
import self as self;
import "dart:core" as core;
static method foo() → core::int {
core::Function f = (dynamic x) → dynamic => x;
core::List<dynamic> l = <core::String>["bar"].{core::Iterable::map}<dynamic>(f as{TypeError} (core::String) → dynamic).{core::Iterable::toList}();
l.{core::List::add}(42);
return l.{core::Iterable::first}.length as{TypeError} core::int;
}
static method main() → dynamic {}

View file

@ -0,0 +1,11 @@
library;
import self as self;
import "dart:core" as core;
static method foo() → core::int {
core::Function f = (dynamic x) → dynamic => x;
core::List<dynamic> l = <core::String>["bar"].{core::Iterable::map}<dynamic>(f as{TypeError} (core::String) → dynamic).{core::Iterable::toList}();
l.{core::List::add}(42);
return l.{core::Iterable::first}.length as{TypeError} core::int;
}
static method main() → dynamic {}

View file

@ -10,6 +10,6 @@ class C<T extends core::Object = dynamic> extends core::Object {
return (self::C::T y) → core::Null {};
}
static method test(self::C<core::String> c) → void {
(core::int) → (core::String) → void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object>(U) → (core::String) → void<core::int>;
(core::int) → (core::String) → void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object = dynamic>(U) → (core::String) → void<core::int>;
}
static method main() → dynamic {}

View file

@ -10,6 +10,6 @@ class C<T extends core::Object = dynamic> extends core::Object {
return (self::C::T y) → core::Null {};
}
static method test(self::C<core::String> c) → void {
(core::int) → (core::String) → void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object>(U) → (core::String) → void<core::int>;
(core::int) → (core::String) → void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object = dynamic>(U) → (core::String) → void<core::int>;
}
static method main() → dynamic {}

View file

@ -4,7 +4,7 @@ import "dart:core" as core;
typedef Foo<S extends core::Object = dynamic> = <T extends core::Object = dynamic>(T) → S;
class A extends core::Object {
field <T extends core::Object>(T) → core::int f = null;
field <T extends core::Object = dynamic>(T) → core::int f = null;
synthetic constructor •() → void
: super core::Object::•()
;
@ -14,7 +14,7 @@ class A extends core::Object {
}
static method foo<T extends core::Object = dynamic>(self::foo::T x) → core::int
return 3;
static method bar() → <T extends core::Object>(T) → core::int
static method bar() → <T extends core::Object = dynamic>(T) → core::int
return self::foo;
static method test1() → void {
self::bar().call<core::String>("hello");

View file

@ -4,7 +4,7 @@ import "dart:core" as core;
typedef Foo<S extends core::Object = dynamic> = <T extends core::Object = dynamic>(T) → S;
class A extends core::Object {
field <T extends core::Object>(T) → core::int f = null;
field <T extends core::Object = dynamic>(T) → core::int f = null;
synthetic constructor •() → void
: super core::Object::•()
;
@ -14,7 +14,7 @@ class A extends core::Object {
}
static method foo<T extends core::Object = dynamic>(self::foo::T x) → core::int
return 3;
static method bar() → <T extends core::Object>(T) → core::int
static method bar() → <T extends core::Object = dynamic>(T) → core::int
return self::foo;
static method test1() → void {
self::bar().call<core::String>("hello");

View file

@ -4,7 +4,7 @@ import "dart:core" as core;
typedef Foo<S extends core::Object = dynamic> = <T extends core::Object = dynamic>(T) → S;
class A extends core::Object {
field <T extends core::Object>(T) → core::int f;
field <T extends core::Object = dynamic>(T) → core::int f;
synthetic constructor •() → void
;
method test() → void
@ -12,7 +12,7 @@ class A extends core::Object {
}
static method foo<T extends core::Object = dynamic>(self::foo::T x) → core::int
;
static method bar() → <T extends core::Object>(T) → core::int
static method bar() → <T extends core::Object = dynamic>(T) → core::int
;
static method test1() → void
;

View file

@ -4,7 +4,7 @@ import "dart:core" as core;
typedef Foo<S extends core::Object = dynamic> = <T extends core::Object = dynamic>(T) → S;
class A extends core::Object {
field <T extends core::Object>(T) → core::int f = null;
field <T extends core::Object = dynamic>(T) → core::int f = null;
synthetic constructor •() → void
: super core::Object::•()
;
@ -14,7 +14,7 @@ class A extends core::Object {
}
static method foo<T extends core::Object = dynamic>(self::foo::T x) → core::int
return 3;
static method bar() → <T extends core::Object>(T) → core::int
static method bar() → <T extends core::Object = dynamic>(T) → core::int
return self::foo;
static method test1() → void {
self::bar().call<core::String>("hello");

View file

@ -4,7 +4,7 @@ import "dart:core" as core;
typedef Foo<S extends core::Object = dynamic> = <T extends core::Object = dynamic>(T) → S;
class A extends core::Object {
field <T extends core::Object>(T) → core::int f = null;
field <T extends core::Object = dynamic>(T) → core::int f = null;
synthetic constructor •() → void
: super core::Object::•()
;
@ -14,7 +14,7 @@ class A extends core::Object {
}
static method foo<T extends core::Object = dynamic>(self::foo::T x) → core::int
return 3;
static method bar() → <T extends core::Object>(T) → core::int
static method bar() → <T extends core::Object = dynamic>(T) → core::int
return self::foo;
static method test1() → void {
self::bar().call<core::String>("hello");

View file

@ -3,12 +3,12 @@ import self as self;
import "dart:core" as core;
typedef C<A extends core::Object = dynamic, K extends core::Object = dynamic> = <B extends core::Object = dynamic>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, K, B) → core::int;
static method producer<K extends core::Object = dynamic>() → dynamic {
return <A extends core::Object = dynamic>(core::int v1) → dynamic {
return <B extends core::Object = dynamic>(A v2, self::producer::K v3, B v4) → dynamic => 0;
};
}
static method main() → dynamic {
assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
assert(self::producer<core::String>() is <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, core::String, B) → core::int);
}

View file

@ -3,12 +3,12 @@ import self as self;
import "dart:core" as core;
typedef C<A extends core::Object = dynamic, K extends core::Object = dynamic> = <B extends core::Object = dynamic>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, K, B) → core::int;
static method producer<K extends core::Object = dynamic>() → dynamic {
return <A extends core::Object = dynamic>(core::int v1) → dynamic {
return <B extends core::Object = dynamic>(A v2, self::producer::K v3, B v4) → dynamic => 0;
};
}
static method main() → dynamic {
assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
assert(self::producer<core::String>() is <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, core::String, B) → core::int);
}

View file

@ -3,7 +3,7 @@ import self as self;
import "dart:core" as core;
typedef C<A extends core::Object = dynamic, K extends core::Object = dynamic> = <B extends core::Object = dynamic>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, K, B) → core::int;
static method producer<K extends core::Object = dynamic>() → dynamic
;
static method main() → dynamic

View file

@ -3,12 +3,12 @@ import self as self;
import "dart:core" as core;
typedef C<A extends core::Object = dynamic, K extends core::Object = dynamic> = <B extends core::Object = dynamic>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, K, B) → core::int;
static method producer<K extends core::Object = dynamic>() → dynamic {
return <A extends core::Object = dynamic>(core::int v1) → <B extends core::Object = dynamic>(A, self::producer::K, B) → core::int {
return <B extends core::Object = dynamic>(A v2, self::producer::K v3, B v4) → core::int => 0;
};
}
static method main() → dynamic {
assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
assert(self::producer<core::String>() is <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, core::String, B) → core::int);
}

View file

@ -3,12 +3,12 @@ import self as self;
import "dart:core" as core;
typedef C<A extends core::Object = dynamic, K extends core::Object = dynamic> = <B extends core::Object = dynamic>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object>(A, K, B) → core::int;
typedef D<K extends core::Object = dynamic> = <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, K, B) → core::int;
static method producer<K extends core::Object = dynamic>() → dynamic {
return <A extends core::Object = dynamic>(core::int v1) → <B extends core::Object = dynamic>(A, self::producer::K, B) → core::int {
return <B extends core::Object = dynamic>(A v2, self::producer::K v3, B v4) → core::int => 0;
};
}
static method main() → dynamic {
assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
assert(self::producer<core::String>() is <A extends core::Object = dynamic>(core::int) → <B extends core::Object = dynamic>(A, core::String, B) → core::int);
}

View file

@ -229,12 +229,9 @@ FreshTypeParameters getFreshTypeParameters(List<TypeParameter> typeParameters) {
}
for (int i = 0; i < typeParameters.length; ++i) {
freshParameters[i].bound = substitute(typeParameters[i].bound, map);
// [defaultType] is populated using instantiate-to-bound algorithm, so it
// shouldn't refer to type parameters from the same declaration. However,
// if a transformation changes [defaultType], it may get such references,
// and the line below should invoke [substitute], like for [bound] above.
freshParameters[i].defaultType = typeParameters[i].defaultType;
freshParameters[i].defaultType = typeParameters[i].defaultType != null
? substitute(typeParameters[i].defaultType, map)
: null;
}
return new FreshTypeParameters(freshParameters, Substitution.fromMap(map));
}
@ -479,6 +476,9 @@ class _InnerTypeSubstitutor extends _TypeSubstitutor {
var fresh = new TypeParameter(node.name);
substitution[node] = new TypeParameterType(fresh);
fresh.bound = visit(node.bound);
if (node.defaultType != null) {
fresh.defaultType = visit(node.defaultType);
}
return fresh;
}
}
@ -846,7 +846,9 @@ class _OccurrenceVisitor extends DartTypeVisitor<bool> {
bool handleTypeParameter(TypeParameter node) {
assert(!variables.contains(node));
return node.bound.accept(this);
if (node.bound.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType.accept(this);
}
}
@ -882,6 +884,7 @@ class _OccurrenceCollectorVisitor extends DartTypeVisitor {
visitFunctionType(FunctionType node) {
for (TypeParameter typeParameter in node.typeParameters) {
typeParameter.bound.accept(this);
typeParameter.defaultType?.accept(this);
}
for (DartType parameter in node.positionalParameters) {
parameter.accept(this);