mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:56:57 +00:00
[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:
parent
c39c2c8ac1
commit
05f11aa74c
15
pkg/front_end/testcases/inference/bug33324.dart
Normal file
15
pkg/front_end/testcases/inference/bug33324.dart
Normal 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() {}
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -0,0 +1,8 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static method foo() → core::int
|
||||
;
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -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 {}
|
|
@ -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 {}
|
|
@ -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 {}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue