mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[kernel] Support for partial tearoff type application operator in the VM, take 3.
The original change is available in patchset 1. The changes since then are just status file updates. Change-Id: I0c45c4b09a187bdd60c6a38bf23f6b7a0cf80c97 Reviewed-on: https://dart-review.googlesource.com/34400 Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
6178cc17ed
commit
42a639973d
|
@ -92,7 +92,6 @@ inference/generic_methods_correctly_recognize_generic_upper_bound: TypeCheckErro
|
|||
inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
|
||||
inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
|
||||
inference/generic_methods_infer_js_builtin: Fail # Issue #30029
|
||||
inference/generic_methods_nested_generic_instantiation: RuntimeError # Issue #31304
|
||||
inference/infer_field_override_multiple: TypeCheckError
|
||||
inference/infer_method_missing_params: TypeCheckError
|
||||
inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "vm/compiler/frontend/kernel_binary_flowgraph.h"
|
||||
#include "vm/compiler/frontend/prologue_builder.h"
|
||||
#include "vm/compiler/jit/compiler.h"
|
||||
#include "vm/longjump.h"
|
||||
#include "vm/object_store.h"
|
||||
|
@ -1427,6 +1428,15 @@ void StreamingScopeBuilder::VisitExpression() {
|
|||
builder_->SkipConstantReference();
|
||||
return;
|
||||
}
|
||||
case kInstantiation: {
|
||||
VisitExpression();
|
||||
const intptr_t list_length =
|
||||
builder_->ReadListLength(); // read list length.
|
||||
for (intptr_t i = 0; i < list_length; ++i) {
|
||||
VisitDartType(); // read ith type.
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
H.ReportError("Unsupported tag at this point: %d.", tag);
|
||||
UNREACHABLE();
|
||||
|
@ -3880,10 +3890,63 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
|
|||
Fragment body(instruction_cursor);
|
||||
body += flow_graph_builder_->CheckStackOverflowInPrologue();
|
||||
|
||||
// Forwarding the type parameters is complicated by our approach to
|
||||
// implementing the partial tearoff instantiation.
|
||||
//
|
||||
// When a tearoff is partially applied to a set of type arguments, the type
|
||||
// arguments are saved in the closure's "function_type_arguments" field. The
|
||||
// partial type application operator is guaranteed to provide arguments for
|
||||
// all of a generic tearoff's type parameters, so we will only have to forward
|
||||
// type arguments from the caller or from the closure object. In other words,
|
||||
// if there are type arguments saved on the tearoff, we must throw
|
||||
// NoSuchMethod.
|
||||
intptr_t type_args_len = 0;
|
||||
if (I->reify_generic_functions() && function.IsGeneric()) {
|
||||
type_args_len = target.NumTypeParameters();
|
||||
ASSERT(parsed_function()->function_type_arguments() != NULL);
|
||||
type_args_len = target.NumTypeParameters();
|
||||
|
||||
Fragment copy_type_args;
|
||||
|
||||
LocalVariable* closure =
|
||||
parsed_function()->node_sequence()->scope()->VariableAt(0);
|
||||
copy_type_args += LoadLocal(closure);
|
||||
copy_type_args += LoadField(Closure::function_type_arguments_offset());
|
||||
|
||||
TargetEntryInstr *is_instantiated, *is_not_instantiated;
|
||||
copy_type_args +=
|
||||
BranchIfNull(&is_not_instantiated, &is_instantiated, /*negate=*/false);
|
||||
JoinEntryInstr* join = BuildJoinEntry();
|
||||
|
||||
// We found type arguments saved on the tearoff to be provided to the
|
||||
// function.
|
||||
|
||||
Fragment copy_instantiated_args(is_instantiated);
|
||||
|
||||
copy_instantiated_args +=
|
||||
LoadLocal(parsed_function()->function_type_arguments());
|
||||
|
||||
TargetEntryInstr *no_type_args, *passed_type_args;
|
||||
copy_instantiated_args +=
|
||||
BranchIfNull(&no_type_args, &passed_type_args, /*negate=*/false);
|
||||
|
||||
Fragment use_instantiated_args(no_type_args);
|
||||
use_instantiated_args += LoadLocal(closure);
|
||||
use_instantiated_args +=
|
||||
LoadField(Closure::function_type_arguments_offset());
|
||||
use_instantiated_args += StoreLocal(
|
||||
TokenPosition::kNoSource, parsed_function()->function_type_arguments());
|
||||
use_instantiated_args += Drop();
|
||||
use_instantiated_args += Goto(join);
|
||||
|
||||
Fragment goto_nsm(passed_type_args);
|
||||
goto_nsm += Goto(flow_graph_builder_->BuildThrowNoSuchMethod());
|
||||
|
||||
// The tearoff was not partially applied, so we forward type arguments from
|
||||
// the caller.
|
||||
Fragment forward_caller_args(is_not_instantiated);
|
||||
forward_caller_args += Goto(join);
|
||||
|
||||
body += Fragment(copy_type_args.entry, join);
|
||||
body += LoadLocal(parsed_function()->function_type_arguments());
|
||||
body += PushArgument();
|
||||
}
|
||||
|
@ -4560,6 +4623,8 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
|
|||
return BuildClosureCreation(position);
|
||||
case kConstantExpression:
|
||||
return BuildConstantExpression(position);
|
||||
case kInstantiation:
|
||||
return BuildPartialTearoffInstantiation(position);
|
||||
default:
|
||||
H.ReportError("Unsupported tag at this point: %d.", tag);
|
||||
UNREACHABLE();
|
||||
|
@ -7903,6 +7968,67 @@ Fragment StreamingFlowGraphBuilder::BuildConstantExpression(
|
|||
return Constant(Object::ZoneHandle(Z, H.constants().At(constant_index)));
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildPartialTearoffInstantiation(
|
||||
TokenPosition* position) {
|
||||
if (position != NULL) *position = TokenPosition::kNoSource;
|
||||
|
||||
// Create a copy of the closure.
|
||||
|
||||
Fragment instructions = BuildExpression();
|
||||
LocalVariable* original_closure = MakeTemporary();
|
||||
|
||||
instructions += AllocateObject(
|
||||
TokenPosition::kNoSource,
|
||||
Class::ZoneHandle(Z, I->object_store()->closure_class()), 0);
|
||||
LocalVariable* new_closure = MakeTemporary();
|
||||
|
||||
instructions += LoadLocal(new_closure);
|
||||
|
||||
intptr_t num_type_args = ReadListLength();
|
||||
const TypeArguments* type_args = &T.BuildTypeArguments(num_type_args);
|
||||
|
||||
// Even if all dynamic types are passed in, we need to put a vector in here to
|
||||
// distinguish this partially applied tearoff from a normal tearoff. This is
|
||||
// necessary because the tearoff wrapper (BuildGraphOfImplicitClosureFunction)
|
||||
// needs to throw NSM if type arguments are passed to a partially applied
|
||||
// tearoff.
|
||||
if (type_args->IsNull()) {
|
||||
type_args =
|
||||
&TypeArguments::ZoneHandle(Z, TypeArguments::New(num_type_args));
|
||||
for (intptr_t i = 0; i < num_type_args; ++i) {
|
||||
type_args->SetTypeAt(i, Type::ZoneHandle(Z, Type::DynamicType()));
|
||||
}
|
||||
}
|
||||
instructions += TranslateInstantiatedTypeArguments(*type_args);
|
||||
instructions += StoreInstanceField(TokenPosition::kNoSource,
|
||||
Closure::function_type_arguments_offset());
|
||||
|
||||
// Copy over the target function.
|
||||
instructions += LoadLocal(new_closure);
|
||||
instructions += LoadLocal(original_closure);
|
||||
instructions += LoadField(Closure::function_offset());
|
||||
instructions +=
|
||||
StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset());
|
||||
|
||||
// Copy over the instantiator type arguments.
|
||||
instructions += LoadLocal(new_closure);
|
||||
instructions += LoadLocal(original_closure);
|
||||
instructions += LoadField(Closure::instantiator_type_arguments_offset());
|
||||
instructions += StoreInstanceField(
|
||||
TokenPosition::kNoSource, Closure::instantiator_type_arguments_offset());
|
||||
|
||||
// Copy over the context.
|
||||
instructions += LoadLocal(new_closure);
|
||||
instructions += LoadLocal(original_closure);
|
||||
instructions += LoadField(Closure::context_offset());
|
||||
instructions +=
|
||||
StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset());
|
||||
|
||||
instructions += DropTempsPreserveTop(1); // drop old closure
|
||||
|
||||
return instructions;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() {
|
||||
Fragment instructions = BuildExpression(); // read expression.
|
||||
instructions += Drop();
|
||||
|
|
|
@ -1230,6 +1230,7 @@ class StreamingFlowGraphBuilder {
|
|||
Fragment BuildVectorCopy(TokenPosition* position);
|
||||
Fragment BuildClosureCreation(TokenPosition* position);
|
||||
Fragment BuildConstantExpression(TokenPosition* position);
|
||||
Fragment BuildPartialTearoffInstantiation(TokenPosition* position);
|
||||
|
||||
Fragment BuildExpressionStatement();
|
||||
Fragment BuildBlock();
|
||||
|
|
|
@ -2554,6 +2554,18 @@ Fragment BaseFlowGraphBuilder::StoreFpRelativeSlot(intptr_t offset) {
|
|||
return Fragment(instr);
|
||||
}
|
||||
|
||||
JoinEntryInstr* BaseFlowGraphBuilder::BuildThrowNoSuchMethod() {
|
||||
JoinEntryInstr* nsm = BuildJoinEntry();
|
||||
|
||||
Fragment failing(nsm);
|
||||
const Code& nsm_handler =
|
||||
Code::ZoneHandle(StubCode::CallClosureNoSuchMethod_entry()->code());
|
||||
failing += LoadArgDescriptor();
|
||||
failing += TailCall(nsm_handler);
|
||||
|
||||
return nsm;
|
||||
}
|
||||
|
||||
RawObject* EvaluateMetadata(const Field& metadata_field) {
|
||||
LongJumpScope jump;
|
||||
if (setjmp(*jump.Set()) == 0) {
|
||||
|
|
|
@ -598,6 +598,13 @@ class BaseFlowGraphBuilder {
|
|||
|
||||
intptr_t AllocateTryIndex() { return next_used_try_index_++; }
|
||||
|
||||
Fragment LoadArgDescriptor() {
|
||||
ASSERT(parsed_function_->has_arg_desc_var());
|
||||
return LoadLocal(parsed_function_->arg_desc_var());
|
||||
}
|
||||
|
||||
JoinEntryInstr* BuildThrowNoSuchMethod();
|
||||
|
||||
protected:
|
||||
intptr_t AllocateBlockId() { return ++last_used_block_id_; }
|
||||
intptr_t CurrentTryIndex();
|
||||
|
|
|
@ -78,18 +78,6 @@ BlockEntryInstr* PrologueBuilder::BuildPrologue(BlockEntryInstr* entry,
|
|||
}
|
||||
}
|
||||
|
||||
JoinEntryInstr* PrologueBuilder::BuildThrowNoSuchMethod() {
|
||||
JoinEntryInstr* nsm = BuildJoinEntry();
|
||||
|
||||
Fragment failing(nsm);
|
||||
const Code& nsm_handler =
|
||||
Code::ZoneHandle(StubCode::CallClosureNoSuchMethod_entry()->code());
|
||||
failing += LoadArgDescriptor();
|
||||
failing += TailCall(nsm_handler);
|
||||
|
||||
return nsm;
|
||||
}
|
||||
|
||||
Fragment PrologueBuilder::BuildTypeArgumentsLengthCheck(bool strong,
|
||||
JoinEntryInstr* nsm,
|
||||
bool expect_type_args) {
|
||||
|
|
|
@ -50,8 +50,6 @@ class PrologueBuilder : public BaseFlowGraphBuilder {
|
|||
intptr_t last_used_block_id() const { return last_used_block_id_; }
|
||||
|
||||
private:
|
||||
JoinEntryInstr* BuildThrowNoSuchMethod();
|
||||
|
||||
Fragment BuildTypeArgumentsLengthCheck(bool strong,
|
||||
JoinEntryInstr* nsm,
|
||||
bool expect_type_args);
|
||||
|
@ -68,11 +66,6 @@ class PrologueBuilder : public BaseFlowGraphBuilder {
|
|||
return parsed_function_->RawParameterVariable(index);
|
||||
}
|
||||
|
||||
Fragment LoadArgDescriptor() {
|
||||
ASSERT(parsed_function_->has_arg_desc_var());
|
||||
return LoadLocal(parsed_function_->arg_desc_var());
|
||||
}
|
||||
|
||||
const Instance& DefaultParameterValueAt(intptr_t i) {
|
||||
if (parsed_function_->default_parameter_values() != NULL) {
|
||||
return parsed_function_->DefaultParameterValueAt(i);
|
||||
|
|
|
@ -6533,25 +6533,34 @@ RawFunction* Function::InstantiateSignatureFrom(
|
|||
// Note that parent pointers in newly instantiated signatures still points to
|
||||
// the original uninstantiated parent signatures. That is not a problem.
|
||||
const Function& parent = Function::Handle(zone, parent_function());
|
||||
ASSERT(!HasInstantiatedSignature(kAny, num_free_fun_type_params));
|
||||
|
||||
// A generic typedef may declare a non-generic function type and get
|
||||
// instantiated with unrelated function type parameters. In that case, its
|
||||
// signature is still uninstantiated, because these type parameters are
|
||||
// free (they are not declared by the typedef).
|
||||
// For that reason, we only adjust num_free_fun_type_params if this
|
||||
// signature is generic or has a generic parent.
|
||||
if (IsGeneric() || HasGenericParent()) {
|
||||
// We only consider the function type parameters declared by the parents
|
||||
// of this signature function as free.
|
||||
const int num_parent_type_params = NumParentTypeParameters();
|
||||
if (num_parent_type_params < num_free_fun_type_params) {
|
||||
num_free_fun_type_params = num_parent_type_params;
|
||||
// See the comment on kCurrentAndEnclosingFree to understand why we don't
|
||||
// adjust 'num_free_fun_type_params' downward in this case.
|
||||
bool delete_type_parameters = false;
|
||||
if (num_free_fun_type_params == kCurrentAndEnclosingFree) {
|
||||
num_free_fun_type_params = kAllFree;
|
||||
delete_type_parameters = true;
|
||||
} else {
|
||||
ASSERT(!HasInstantiatedSignature(kAny, num_free_fun_type_params));
|
||||
|
||||
// A generic typedef may declare a non-generic function type and get
|
||||
// instantiated with unrelated function type parameters. In that case, its
|
||||
// signature is still uninstantiated, because these type parameters are
|
||||
// free (they are not declared by the typedef).
|
||||
// For that reason, we only adjust num_free_fun_type_params if this
|
||||
// signature is generic or has a generic parent.
|
||||
if (IsGeneric() || HasGenericParent()) {
|
||||
// We only consider the function type parameters declared by the parents
|
||||
// of this signature function as free.
|
||||
const int num_parent_type_params = NumParentTypeParameters();
|
||||
if (num_parent_type_params < num_free_fun_type_params) {
|
||||
num_free_fun_type_params = num_parent_type_params;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function& sig = Function::Handle(zone, Function::null());
|
||||
if (IsConvertedClosureFunction()) {
|
||||
if (IsConvertedClosureFunction() && !delete_type_parameters) {
|
||||
sig = Function::NewConvertedClosureFunction(
|
||||
String::Handle(zone, name()), parent, TokenPosition::kNoSource);
|
||||
// TODO(30455): Kernel generic methods undone. Handle type parameters
|
||||
|
@ -6562,7 +6571,9 @@ RawFunction* Function::InstantiateSignatureFrom(
|
|||
} else {
|
||||
sig = Function::NewSignatureFunction(owner, parent,
|
||||
TokenPosition::kNoSource, space);
|
||||
sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
|
||||
if (!delete_type_parameters) {
|
||||
sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
|
||||
}
|
||||
}
|
||||
|
||||
AbstractType& type = AbstractType::Handle(zone, result_type());
|
||||
|
@ -6587,6 +6598,10 @@ RawFunction* Function::InstantiateSignatureFrom(
|
|||
sig.SetParameterTypeAt(i, type);
|
||||
}
|
||||
sig.set_parameter_names(Array::Handle(zone, parameter_names()));
|
||||
|
||||
if (delete_type_parameters) {
|
||||
ASSERT(sig.HasInstantiatedSignature(kFunctions));
|
||||
}
|
||||
return sig.raw();
|
||||
}
|
||||
|
||||
|
@ -7476,7 +7491,9 @@ bool Function::HasInstantiatedSignature(Genericity genericity,
|
|||
return genericity == kCurrentClass || NumTypeParameters() == 0;
|
||||
}
|
||||
|
||||
if (genericity != kCurrentClass) {
|
||||
if (num_free_fun_type_params == kCurrentAndEnclosingFree) {
|
||||
num_free_fun_type_params = kAllFree;
|
||||
} else if (genericity != kCurrentClass) {
|
||||
// A generic typedef may declare a non-generic function type and get
|
||||
// instantiated with unrelated function type parameters. In that case, its
|
||||
// signature is still uninstantiated, because these type parameters are
|
||||
|
@ -15701,18 +15718,12 @@ RawAbstractType* Instance::GetType(Heap::Space space) const {
|
|||
}
|
||||
const Class& cls = Class::Handle(clazz());
|
||||
if (cls.IsClosureClass()) {
|
||||
const Function& signature =
|
||||
Function::Handle(Closure::Cast(*this).function());
|
||||
Function& signature =
|
||||
Function::Handle(Closure::Cast(*this).GetInstantiatedSignature(
|
||||
Thread::Current()->zone()));
|
||||
Type& type = Type::Handle(signature.SignatureType());
|
||||
if (!type.IsInstantiated()) {
|
||||
const TypeArguments& instantiator_type_arguments = TypeArguments::Handle(
|
||||
Closure::Cast(*this).instantiator_type_arguments());
|
||||
const TypeArguments& function_type_arguments =
|
||||
TypeArguments::Handle(Closure::Cast(*this).function_type_arguments());
|
||||
// No bound error possible, since the instance exists.
|
||||
type ^= type.InstantiateFrom(instantiator_type_arguments,
|
||||
function_type_arguments, kAllFree, NULL,
|
||||
NULL, NULL, space);
|
||||
if (!type.IsFinalized()) {
|
||||
type.SetIsFinalized();
|
||||
}
|
||||
type ^= type.Canonicalize();
|
||||
return type.raw();
|
||||
|
@ -15799,16 +15810,8 @@ bool Instance::IsInstanceOf(
|
|||
}
|
||||
Function& other_signature =
|
||||
Function::Handle(zone, Type::Cast(instantiated_other).signature());
|
||||
Function& sig_fun = Function::Handle(zone, Closure::Cast(*this).function());
|
||||
if (!sig_fun.HasInstantiatedSignature()) {
|
||||
const TypeArguments& instantiator_type_arguments = TypeArguments::Handle(
|
||||
zone, Closure::Cast(*this).instantiator_type_arguments());
|
||||
const TypeArguments& function_type_arguments = TypeArguments::Handle(
|
||||
zone, Closure::Cast(*this).function_type_arguments());
|
||||
sig_fun = sig_fun.InstantiateSignatureFrom(instantiator_type_arguments,
|
||||
function_type_arguments,
|
||||
kAllFree, Heap::kOld);
|
||||
}
|
||||
const Function& sig_fun =
|
||||
Function::Handle(Closure::Cast(*this).GetInstantiatedSignature(zone));
|
||||
return sig_fun.IsSubtypeOf(other_signature, bound_error, NULL, Heap::kOld);
|
||||
}
|
||||
TypeArguments& type_arguments = TypeArguments::Handle(zone);
|
||||
|
@ -22437,6 +22440,26 @@ RawClosure* Closure::New() {
|
|||
return reinterpret_cast<RawClosure*>(raw);
|
||||
}
|
||||
|
||||
RawFunction* Closure::GetInstantiatedSignature(Zone* zone) const {
|
||||
Function& sig_fun = Function::Handle(zone, function());
|
||||
const TypeArguments& fn_type_args =
|
||||
TypeArguments::Handle(zone, function_type_arguments());
|
||||
const TypeArguments& inst_type_args =
|
||||
TypeArguments::Handle(zone, instantiator_type_arguments());
|
||||
// We detect the case of a partial tearoff type application and substitute the
|
||||
// type arguments for the type parameters of the function.
|
||||
intptr_t num_free_params =
|
||||
sig_fun.IsImplicitClosureFunction() && !fn_type_args.IsNull()
|
||||
? kCurrentAndEnclosingFree
|
||||
: kAllFree;
|
||||
if (num_free_params == kCurrentAndEnclosingFree ||
|
||||
!sig_fun.HasInstantiatedSignature(kAny)) {
|
||||
return sig_fun.InstantiateSignatureFrom(inst_type_args, fn_type_args,
|
||||
num_free_params, Heap::kOld);
|
||||
}
|
||||
return sig_fun.raw();
|
||||
}
|
||||
|
||||
intptr_t StackTrace::Length() const {
|
||||
const Array& code_array = Array::Handle(raw_ptr()->code_array_);
|
||||
return code_array.Length();
|
||||
|
|
|
@ -2053,6 +2053,19 @@ class ICData : public Object {
|
|||
// Often used constants for number of free function type parameters.
|
||||
enum {
|
||||
kNoneFree = 0,
|
||||
|
||||
// 'kCurrentAndEnclosingFree' is used when partially applying a signature
|
||||
// function to a set of type arguments. It indicates that the set of type
|
||||
// parameters declared by the current function and enclosing functions should
|
||||
// be considered free, and the current function type parameters should be
|
||||
// substituted as well.
|
||||
//
|
||||
// For instance, if the signature "<T>(T, R) => T" is instantiated with
|
||||
// function type arguments [int, String] and kCurrentAndEnclosingFree is
|
||||
// supplied, the result of the instantiation will be "(String, int) => int".
|
||||
kCurrentAndEnclosingFree = kMaxInt32 - 1,
|
||||
|
||||
// Only parameters declared by enclosing functions are free.
|
||||
kAllFree = kMaxInt32,
|
||||
};
|
||||
|
||||
|
@ -8652,6 +8665,8 @@ class Closure : public Instance {
|
|||
const Context& context,
|
||||
Heap::Space space = Heap::kNew);
|
||||
|
||||
RawFunction* GetInstantiatedSignature(Zone* zone) const;
|
||||
|
||||
private:
|
||||
static RawClosure* New();
|
||||
|
||||
|
|
|
@ -6,21 +6,38 @@ import "package:expect/expect.dart";
|
|||
|
||||
T f<T>(T x) => x;
|
||||
|
||||
int intToInt(int x) => x;
|
||||
String stringToString(String x) => x;
|
||||
|
||||
main() {
|
||||
int Function(int) intFunc = f;
|
||||
dynamic intFuncDynamic = intFunc;
|
||||
Expect.isTrue(intFuncDynamic is int Function(int));
|
||||
Expect.isFalse(intFuncDynamic is String Function(String));
|
||||
Expect.equals(intFuncDynamic(1), 1);
|
||||
Expect.equals("${intFuncDynamic.runtimeType}", "${intToInt.runtimeType}");
|
||||
Expect.throwsTypeError(() {
|
||||
intFuncDynamic('oops');
|
||||
});
|
||||
Expect.throwsNoSuchMethodError(() {
|
||||
intFuncDynamic<String>('oops');
|
||||
});
|
||||
String Function(String) stringFunc = f;
|
||||
dynamic stringFuncDynamic = stringFunc;
|
||||
Expect.isTrue(stringFuncDynamic is String Function(String));
|
||||
Expect.isFalse(stringFuncDynamic is int Function(int));
|
||||
Expect.equals(stringFuncDynamic('hello'), 'hello');
|
||||
Expect.equals(
|
||||
"${stringFuncDynamic.runtimeType}", "${stringToString.runtimeType}");
|
||||
Expect.throwsTypeError(() {
|
||||
stringFuncDynamic(1);
|
||||
});
|
||||
Expect.throwsNoSuchMethodError(() {
|
||||
stringFuncDynamic<int>(1);
|
||||
});
|
||||
dynamic Function(dynamic) dynamicFunc = f;
|
||||
dynamic dynamicFuncDynamic = dynamicFunc;
|
||||
Expect.throwsNoSuchMethodError(() {
|
||||
dynamicFuncDynamic<int>(1);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ import_private_test/01: MissingCompileTimeError # Issue 29920
|
|||
initializing_formal_final_test: MissingCompileTimeError
|
||||
instantiate_tearoff_after_contravariance_check_test: RuntimeError
|
||||
instantiate_tearoff_of_call_test: RuntimeError
|
||||
instantiate_tearoff_test: RuntimeError
|
||||
interface_test/00: MissingCompileTimeError
|
||||
internal_library_test/01: MissingCompileTimeError # Issue 29920
|
||||
issue31596_test: CompileTimeError
|
||||
|
@ -786,6 +787,7 @@ regress_30339_test: RuntimeError # Uncaught Expect.isTrue(false) fails.
|
|||
runtime_type_function_test: RuntimeError # Expect.fail('Type print string does not match expectation
|
||||
syncstar_yield_test/copyParameters: RuntimeError # Expect.equals(expected: <2>, actual: <3>) fails.
|
||||
type_literal_test: RuntimeError # Expect.equals(expected: <Func>, actual: <(bool) => int>) fails.
|
||||
instantiate_tearoff_test: RuntimeError
|
||||
|
||||
# Compiler tests for dartdevc and dartdevk. These contain common expectations
|
||||
# for all runtimes including $runtime == none. They are organized by: shared
|
||||
|
|
|
@ -237,11 +237,11 @@ async_star_regression_fisk_test: RuntimeError
|
|||
async_star_test/01: CompileTimeError # Issue 2238.
|
||||
async_star_test/01: Pass
|
||||
async_star_test/01: RuntimeError
|
||||
async_star_test/02: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
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)
|
||||
async_star_test/02: RuntimeError # Issue 31402 (Invocation arguments)
|
||||
async_star_test/03: RuntimeError # Issue 31402 (Invocation arguments)
|
||||
async_star_test/04: RuntimeError # Issue 31402 (Invocation arguments)
|
||||
async_star_test/05: RuntimeError # Issue 31402 (Invocation arguments)
|
||||
async_star_test/none: RuntimeError # Issue 31402 (Invocation arguments)
|
||||
await_test: RuntimeError # Issue 31541
|
||||
bad_named_parameters2_test/01: MissingCompileTimeError
|
||||
bad_named_parameters_test/01: MissingCompileTimeError
|
||||
|
@ -437,8 +437,6 @@ function_subtype_bound_closure2_test: RuntimeError
|
|||
function_subtype_bound_closure5_test: RuntimeError
|
||||
function_subtype_bound_closure5a_test: RuntimeError
|
||||
function_subtype_bound_closure6_test: RuntimeError
|
||||
function_subtype_bound_closure7_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
function_subtype_bound_closure7_test: RuntimeError
|
||||
function_subtype_call1_test: RuntimeError
|
||||
function_subtype_call2_test: RuntimeError
|
||||
function_subtype_cast0_test: RuntimeError
|
||||
|
@ -466,7 +464,6 @@ generic_async_star_test: RuntimeError
|
|||
generic_closure_test: RuntimeError
|
||||
generic_function_bounds_test: RuntimeError
|
||||
generic_function_bounds_test: CompileTimeError
|
||||
generic_function_dcall_test: CompileTimeError
|
||||
generic_function_dcall_test: RuntimeError
|
||||
generic_instanceof2_test: RuntimeError
|
||||
generic_is_check_test: RuntimeError
|
||||
|
@ -474,10 +471,6 @@ generic_list_checked_test: CompileTimeError # Issue 31402 (Variable declaration)
|
|||
generic_methods_bounds_test/01: MissingCompileTimeError
|
||||
generic_methods_overriding_test/01: MissingCompileTimeError
|
||||
generic_methods_recursive_bound_test/02: MissingCompileTimeError
|
||||
generic_methods_tearoff_specialization_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
generic_methods_tearoff_specialization_test: RuntimeError
|
||||
generic_methods_unused_parameter_test: RuntimeError
|
||||
generic_methods_unused_parameter_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
generic_no_such_method_dispatcher_simple_test: CompileTimeError # Issue 31533
|
||||
generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
|
||||
generic_tearoff_test: CompileTimeError
|
||||
|
@ -494,9 +487,7 @@ implicit_this_test/01: MissingCompileTimeError
|
|||
implicit_this_test/04: MissingCompileTimeError
|
||||
initializing_formal_type_annotation_test/01: MissingCompileTimeError
|
||||
initializing_formal_type_annotation_test/02: MissingCompileTimeError
|
||||
instantiate_tearoff_after_contravariance_check_test: CompileTimeError
|
||||
instantiate_tearoff_of_call_test: CompileTimeError
|
||||
instantiate_tearoff_test: CompileTimeError
|
||||
invocation_mirror_test: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
issue13179_test: CompileTimeError # Issue 31402 (Parameter default value)
|
||||
issue18628_2_test/01: MissingCompileTimeError
|
||||
|
@ -805,6 +796,9 @@ mixin_black_listed_test/02: MissingCompileTimeError # Please triage.
|
|||
null_test/02: MissingCompileTimeError # Please triage.
|
||||
null_test/03: MissingCompileTimeError # Please triage.
|
||||
|
||||
[ $compiler == dartk && $strong && $arch == simdbc64 ]
|
||||
instantiate_tearoff_test: Crash #Issue 31880
|
||||
|
||||
[ $compiler == dartk && !$strong ]
|
||||
*: SkipByDesign # language_2 is only supported in strong mode.
|
||||
|
||||
|
@ -1293,7 +1287,7 @@ generalized_void_syntax_test: CompileTimeError # Issue #30176
|
|||
generic_async_star_test: RuntimeError
|
||||
generic_closure_test: RuntimeError
|
||||
generic_function_bounds_test: CompileTimeError
|
||||
generic_function_dcall_test: CompileTimeError
|
||||
generic_function_dcall_test: RuntimeError
|
||||
generic_instanceof2_test: RuntimeError
|
||||
generic_is_check_test: RuntimeError
|
||||
generic_list_checked_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
|
@ -1308,7 +1302,7 @@ generic_methods_recursive_bound_test/03: Pass
|
|||
generic_methods_reuse_type_variables_test: Pass
|
||||
generic_methods_tearoff_specialization_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
generic_methods_tearoff_specialization_test: RuntimeError
|
||||
generic_methods_unused_parameter_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
generic_methods_unused_parameter_test: RuntimeError # Issue 31402 (Variable declaration)
|
||||
generic_no_such_method_dispatcher_simple_test: CompileTimeError # Issue 31533
|
||||
generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
|
||||
generic_tearoff_test: CompileTimeError
|
||||
|
@ -1345,9 +1339,7 @@ implicit_this_test/04: MissingCompileTimeError
|
|||
initializing_formal_type_annotation_test/01: MissingCompileTimeError
|
||||
initializing_formal_type_annotation_test/02: MissingCompileTimeError
|
||||
instance_creation_in_function_annotation_test: SkipByDesign
|
||||
instantiate_tearoff_after_contravariance_check_test: CompileTimeError
|
||||
instantiate_tearoff_of_call_test: CompileTimeError
|
||||
instantiate_tearoff_test: CompileTimeError
|
||||
invocation_mirror2_test: SkipByDesign
|
||||
invocation_mirror_invoke_on2_test: SkipByDesign
|
||||
invocation_mirror_invoke_on_test: SkipByDesign
|
||||
|
|
|
@ -351,7 +351,7 @@ mirrors/invocation_fuzz_test/false: CompileTimeError, Pass # Please triage.
|
|||
mirrors/invocation_fuzz_test/none: CompileTimeError # Please triage.
|
||||
mirrors/invocation_fuzz_test/smi: CompileTimeError, DartkCrash, Crash, Pass # Please triage.
|
||||
mirrors/invocation_fuzz_test/string: CompileTimeError, Pass # Please triage.
|
||||
mirrors/library_uri_io_test: CompileTimeError # Please triage.
|
||||
mirrors/library_uri_io_test: RuntimeError # Please triage.
|
||||
mirrors/spawn_function_root_library_test: Skip
|
||||
|
||||
# ===== Skip dartk and darkp in !$strong mode ====
|
||||
|
|
Loading…
Reference in a new issue