mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
[cfe] Use inferred types on forwarding constructors
Closes #40428 Change-Id: I26bf1e21684605d85312c5e808191ad035eb574b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134289 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
12b5e23084
commit
d826ecc447
16 changed files with 302 additions and 20 deletions
|
@ -318,6 +318,7 @@ class KernelTarget extends TargetImplementation {
|
|||
loader.addNoSuchMethodForwarders(myClasses);
|
||||
loader.checkMixins(myClasses);
|
||||
loader.buildOutlineExpressions(loader.coreTypes);
|
||||
_updateDelayedParameterTypes();
|
||||
installAllComponentProblems(loader.allComponentProblems);
|
||||
loader.allComponentProblems.clear();
|
||||
return component;
|
||||
|
@ -450,6 +451,17 @@ class KernelTarget extends TargetImplementation {
|
|||
ticker.logMs("Installed synthetic constructors");
|
||||
}
|
||||
|
||||
List<DelayedParameterType> _delayedParameterTypes = <DelayedParameterType>[];
|
||||
|
||||
/// Update the type of parameters cloned from parameters with inferred
|
||||
/// parameter types.
|
||||
void _updateDelayedParameterTypes() {
|
||||
for (DelayedParameterType delayedParameterType in _delayedParameterTypes) {
|
||||
delayedParameterType.updateType();
|
||||
}
|
||||
_delayedParameterTypes.clear();
|
||||
}
|
||||
|
||||
ClassBuilder get objectClassBuilder => objectType.declaration;
|
||||
|
||||
Class get objectClass => objectClassBuilder.cls;
|
||||
|
@ -565,6 +577,9 @@ class KernelTarget extends TargetImplementation {
|
|||
isFinal: formal.isFinal, isConst: formal.isConst);
|
||||
if (formal.type != null) {
|
||||
copy.type = substitute(formal.type, substitutionMap);
|
||||
} else {
|
||||
_delayedParameterTypes
|
||||
.add(new DelayedParameterType(formal, copy, substitutionMap));
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
@ -1082,3 +1097,21 @@ class KernelDiagnosticReporter
|
|||
loader.addProblem(message, charOffset, noLength, fileUri, context: context);
|
||||
}
|
||||
}
|
||||
|
||||
/// Data for updating cloned parameters of parameters with inferred parameter
|
||||
/// types.
|
||||
///
|
||||
/// The type of [source] is not declared so the type of [target] needs to be
|
||||
/// updated when the type of [source] has been inferred.
|
||||
class DelayedParameterType {
|
||||
final VariableDeclaration source;
|
||||
final VariableDeclaration target;
|
||||
final Map<TypeParameter, DartType> substitutionMap;
|
||||
|
||||
DelayedParameterType(this.source, this.target, this.substitutionMap);
|
||||
|
||||
void updateType() {
|
||||
assert(source.type != null, "No type computed for $source.");
|
||||
target.type = substitute(source.type, substitutionMap);
|
||||
}
|
||||
}
|
||||
|
|
30
pkg/front_end/testcases/general/issue40428.dart
Normal file
30
pkg/front_end/testcases/general/issue40428.dart
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
|
||||
abstract class SuperClass1 {
|
||||
final String value;
|
||||
|
||||
SuperClass1(this.value);
|
||||
}
|
||||
|
||||
abstract class SuperClass2 {
|
||||
final String value;
|
||||
|
||||
SuperClass2(String i) : value = i;
|
||||
}
|
||||
|
||||
class Mixin {}
|
||||
|
||||
class NamedMixin1 = SuperClass1 with Mixin;
|
||||
class NamedMixin2 = SuperClass2 with Mixin;
|
||||
|
||||
void main() {
|
||||
new NamedMixin1('');
|
||||
new NamedMixin2('');
|
||||
}
|
||||
|
||||
errors() {
|
||||
new NamedMixin1(0);
|
||||
new NamedMixin2(0);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class SuperClass1 extends core::Object {
|
||||
final field core::String* value;
|
||||
constructor •(core::String* value) → self::SuperClass1*
|
||||
;
|
||||
}
|
||||
abstract class SuperClass2 extends core::Object {
|
||||
final field core::String* value;
|
||||
constructor •(core::String* i) → self::SuperClass2*
|
||||
;
|
||||
}
|
||||
class Mixin extends core::Object {
|
||||
synthetic constructor •() → self::Mixin*
|
||||
;
|
||||
}
|
||||
class NamedMixin1 = self::SuperClass1 with self::Mixin {
|
||||
synthetic constructor •(core::String* value) → self::NamedMixin1*
|
||||
: super self::SuperClass1::•(value)
|
||||
;
|
||||
}
|
||||
class NamedMixin2 = self::SuperClass2 with self::Mixin {
|
||||
synthetic constructor •(core::String* i) → self::NamedMixin2*
|
||||
: super self::SuperClass2::•(i)
|
||||
;
|
||||
}
|
||||
static method main() → void
|
||||
;
|
||||
static method errors() → dynamic
|
||||
;
|
|
@ -0,0 +1,54 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/issue40428.dart:28:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
// new NamedMixin1(0);
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/general/issue40428.dart:29:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
// new NamedMixin2(0);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class SuperClass1 extends core::Object {
|
||||
final field core::String* value;
|
||||
constructor •(core::String* value) → self::SuperClass1*
|
||||
: self::SuperClass1::value = value, super core::Object::•()
|
||||
;
|
||||
}
|
||||
abstract class SuperClass2 extends core::Object {
|
||||
final field core::String* value;
|
||||
constructor •(core::String* i) → self::SuperClass2*
|
||||
: self::SuperClass2::value = i, super core::Object::•()
|
||||
;
|
||||
}
|
||||
class Mixin extends core::Object {
|
||||
synthetic constructor •() → self::Mixin*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class NamedMixin1 = self::SuperClass1 with self::Mixin {
|
||||
synthetic constructor •(core::String* value) → self::NamedMixin1*
|
||||
: super self::SuperClass1::•(value)
|
||||
;
|
||||
}
|
||||
class NamedMixin2 = self::SuperClass2 with self::Mixin {
|
||||
synthetic constructor •(core::String* i) → self::NamedMixin2*
|
||||
: super self::SuperClass2::•(i)
|
||||
;
|
||||
}
|
||||
static method main() → void {
|
||||
new self::NamedMixin1::•("");
|
||||
new self::NamedMixin2::•("");
|
||||
}
|
||||
static method errors() → dynamic {
|
||||
new self::NamedMixin1::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/issue40428.dart:28:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
new NamedMixin1(0);
|
||||
^" in 0 as{TypeError} core::String*);
|
||||
new self::NamedMixin2::•(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/issue40428.dart:29:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
new NamedMixin2(0);
|
||||
^" in 0 as{TypeError} core::String*);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/issue40428.dart:28:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
// new NamedMixin1(0);
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/general/issue40428.dart:29:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
// new NamedMixin2(0);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class SuperClass1 extends core::Object {
|
||||
final field core::String* value;
|
||||
constructor •(core::String* value) → self::SuperClass1*
|
||||
: self::SuperClass1::value = value, super core::Object::•()
|
||||
;
|
||||
}
|
||||
abstract class SuperClass2 extends core::Object {
|
||||
final field core::String* value;
|
||||
constructor •(core::String* i) → self::SuperClass2*
|
||||
: self::SuperClass2::value = i, super core::Object::•()
|
||||
;
|
||||
}
|
||||
class Mixin extends core::Object {
|
||||
synthetic constructor •() → self::Mixin*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class NamedMixin1 extends self::SuperClass1 implements self::Mixin {
|
||||
synthetic constructor •(core::String* value) → self::NamedMixin1*
|
||||
: super self::SuperClass1::•(value)
|
||||
;
|
||||
}
|
||||
class NamedMixin2 extends self::SuperClass2 implements self::Mixin {
|
||||
synthetic constructor •(core::String* i) → self::NamedMixin2*
|
||||
: super self::SuperClass2::•(i)
|
||||
;
|
||||
}
|
||||
static method main() → void {
|
||||
new self::NamedMixin1::•("");
|
||||
new self::NamedMixin2::•("");
|
||||
}
|
||||
static method errors() → dynamic {
|
||||
new self::NamedMixin1::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/issue40428.dart:28:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
new NamedMixin1(0);
|
||||
^" in 0 as{TypeError} core::String*);
|
||||
new self::NamedMixin2::•(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/issue40428.dart:29:19: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
|
||||
new NamedMixin2(0);
|
||||
^" in 0 as{TypeError} core::String*);
|
||||
}
|
|
@ -13,8 +13,9 @@ class Super {
|
|||
class Class = Super with Mixin;
|
||||
|
||||
main() {
|
||||
// TODO(johnniwinther): The parameter is created before the super constructor
|
||||
// parameter type is inferred. Set up a way to propagate the inferred type
|
||||
// to its use sites.
|
||||
new Class(0);
|
||||
}
|
||||
|
||||
error() {
|
||||
new Class('');
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class = self::Super with self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method error() → dynamic
|
||||
;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart:20:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
// new Class('');
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -14,10 +21,15 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class = self::Super with self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
new self::Class::•("");
|
||||
new self::Class::•(0);
|
||||
}
|
||||
static method error() → dynamic {
|
||||
new self::Class::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart:20:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
new Class('');
|
||||
^" in "" as{TypeError} core::int*);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart:20:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
// new Class('');
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -14,10 +21,15 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class extends self::Super implements self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
new self::Class::•("");
|
||||
new self::Class::•(0);
|
||||
}
|
||||
static method error() → dynamic {
|
||||
new self::Class::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart:20:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
new Class('');
|
||||
^" in "" as{TypeError} core::int*);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@ class Super {
|
|||
class Class = Super with Mixin;
|
||||
|
||||
main() {
|
||||
// TODO(johnniwinther): The parameter is created before the super constructor
|
||||
// parameter type is inferred. Set up a way to propagate the inferred type
|
||||
// to its use sites.
|
||||
new Class(0);
|
||||
}
|
||||
|
||||
error() {
|
||||
new Class('');
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class = self::Super with self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method error() → dynamic
|
||||
;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
// new Class('');
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -14,10 +21,15 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class = self::Super with self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
new self::Class::•("");
|
||||
new self::Class::•(0);
|
||||
}
|
||||
static method error() → dynamic {
|
||||
new self::Class::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
new Class('');
|
||||
^" in "" as{TypeError} core::int*);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
// new Class('');
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -14,10 +21,15 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class extends self::Super implements self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
new self::Class::•("");
|
||||
new self::Class::•(0);
|
||||
}
|
||||
static method error() → dynamic {
|
||||
new self::Class::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
new Class('');
|
||||
^" in "" as{TypeError} core::int*);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
// new Class('');
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -14,10 +21,15 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class = self::Super with self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
new self::Class::•("");
|
||||
new self::Class::•(0);
|
||||
}
|
||||
static method error() → dynamic {
|
||||
new self::Class::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
new Class('');
|
||||
^" in "" as{TypeError} core::int*);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
// new Class('');
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -14,10 +21,15 @@ class Super extends core::Object {
|
|||
;
|
||||
}
|
||||
class Class extends self::Super implements self::Mixin {
|
||||
synthetic constructor •(dynamic field) → self::Class*
|
||||
synthetic constructor •(core::int* field) → self::Class*
|
||||
: super self::Super::•(field)
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
new self::Class::•("");
|
||||
new self::Class::•(0);
|
||||
}
|
||||
static method error() → dynamic {
|
||||
new self::Class::•(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart:22:13: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
new Class('');
|
||||
^" in "" as{TypeError} core::int*);
|
||||
}
|
||||
|
|
|
@ -228,6 +228,7 @@ general/issue38961: TextSerializationFailure
|
|||
general/issue39344: TextSerializationFailure
|
||||
general/issue39421: TextSerializationFailure
|
||||
general/issue39817: TextSerializationFailure
|
||||
general/issue40428: TextSerializationFailure
|
||||
general/literals: TextSerializationFailure # Was: Pass
|
||||
general/local_generic_function: TextSerializationFailure # Was: Pass
|
||||
general/long_chain_of_typedefs: TextSerializationFailure
|
||||
|
|
Loading…
Reference in a new issue