mirror of
https://github.com/dart-lang/sdk
synced 2024-09-21 03:13:14 +00:00
Make finalization of recursive function types more robust, especially since
the Kernel frontend may omit the information that a function type is a typedef. Re-enable several previously failing tests for dartk. R=asiva@google.com Review-Url: https://codereview.chromium.org/2806893002 .
This commit is contained in:
parent
d75edfb408
commit
8ca244ba27
|
@ -815,19 +815,8 @@ intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments(
|
|||
}
|
||||
}
|
||||
|
||||
// Self referencing types may get finalized indirectly.
|
||||
if (!type.IsFinalized()) {
|
||||
ASSERT(full_arguments.IsNull() ||
|
||||
!full_arguments.IsRaw(0, num_type_arguments));
|
||||
if (FLAG_trace_type_finalization) {
|
||||
THR_Print("Marking type '%s' as finalized for class '%s'\n",
|
||||
String::Handle(zone, type.Name()).ToCString(),
|
||||
String::Handle(zone, cls.Name()).ToCString());
|
||||
}
|
||||
// Mark the type as finalized.
|
||||
type.SetIsFinalized();
|
||||
// Do not yet remove the type from the pending_types array.
|
||||
}
|
||||
ASSERT(full_arguments.IsNull() ||
|
||||
!full_arguments.IsRaw(0, num_type_arguments));
|
||||
return full_arguments.IsNull() ? 0 : full_arguments.Length();
|
||||
}
|
||||
|
||||
|
@ -1225,6 +1214,57 @@ RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
|
|||
const intptr_t num_expanded_type_arguments =
|
||||
ExpandAndFinalizeTypeArguments(cls, type, pending_types);
|
||||
|
||||
// Self referencing types may get finalized indirectly.
|
||||
if (!type.IsFinalized()) {
|
||||
// If the type is a function type, we also need to finalize the types in its
|
||||
// signature, i.e. finalize the result type and parameter types of the
|
||||
// signature function of this function type.
|
||||
// We do this after marking this type as finalized in order to allow a
|
||||
// typedef function type to refer to itself via its parameter types and
|
||||
// result type.
|
||||
if (type.IsFunctionType()) {
|
||||
const Type& fun_type = Type::Cast(type);
|
||||
const Class& scope_class = Class::Handle(zone, fun_type.type_class());
|
||||
if (scope_class.IsTypedefClass()) {
|
||||
Function& signature =
|
||||
Function::Handle(zone, scope_class.signature_function());
|
||||
if (!scope_class.is_type_finalized()) {
|
||||
FinalizeSignature(scope_class, signature);
|
||||
}
|
||||
// If the function type is a generic typedef, instantiate its signature
|
||||
// from its type arguments.
|
||||
// Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T.
|
||||
// The instantiated signature of F(int) becomes (int x) => int.
|
||||
// Note that after this step, the signature of the function type is not
|
||||
// identical to the canonical signature of the typedef class anymore.
|
||||
if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) {
|
||||
const TypeArguments& type_args =
|
||||
TypeArguments::Handle(zone, fun_type.arguments());
|
||||
if (FLAG_trace_type_finalization) {
|
||||
THR_Print("Instantiating signature '%s' of typedef '%s'\n",
|
||||
String::Handle(zone, signature.Signature()).ToCString(),
|
||||
String::Handle(zone, fun_type.Name()).ToCString());
|
||||
}
|
||||
signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld);
|
||||
// Note that if type_args contains type parameters, signature is still
|
||||
// uninstantiated here (typedef type parameters were substituted in
|
||||
// the signature with typedef type arguments).
|
||||
}
|
||||
fun_type.set_signature(signature);
|
||||
} else {
|
||||
FinalizeSignature(cls, Function::Handle(zone, fun_type.signature()));
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAG_trace_type_finalization) {
|
||||
THR_Print("Marking type '%s' as finalized for class '%s'\n",
|
||||
String::Handle(zone, type.Name()).ToCString(),
|
||||
String::Handle(zone, cls.Name()).ToCString());
|
||||
}
|
||||
// Mark the type as finalized.
|
||||
type.SetIsFinalized();
|
||||
}
|
||||
|
||||
// If we are done finalizing a graph of mutually recursive types, check their
|
||||
// bounds.
|
||||
if (is_root_type) {
|
||||
|
@ -1236,52 +1276,6 @@ RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls,
|
|||
}
|
||||
}
|
||||
|
||||
// If the type is a function type, we also need to finalize the types in its
|
||||
// signature, i.e. finalize the result type and parameter types of the
|
||||
// signature function of this function type.
|
||||
// We do this after marking this type as finalized in order to allow a
|
||||
// typedef function type to refer to itself via its parameter types and
|
||||
// result type.
|
||||
if (type.IsFunctionType()) {
|
||||
ASSERT(!type.IsBeingFinalized());
|
||||
const Type& fun_type = Type::Cast(type);
|
||||
const Class& scope_class = Class::Handle(zone, fun_type.type_class());
|
||||
if (scope_class.IsTypedefClass()) {
|
||||
Function& signature =
|
||||
Function::Handle(zone, scope_class.signature_function());
|
||||
if (!scope_class.is_type_finalized()) {
|
||||
FinalizeSignature(scope_class, signature);
|
||||
}
|
||||
// If the function type is a generic typedef, instantiate its signature
|
||||
// from its type arguments.
|
||||
// Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T.
|
||||
// The instantiated signature of F(int) becomes (int x) => int.
|
||||
// Note that after this step, the signature of the function type is not
|
||||
// identical to the canonical signature of the typedef class anymore.
|
||||
if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) {
|
||||
const TypeArguments& type_args =
|
||||
TypeArguments::Handle(zone, fun_type.arguments());
|
||||
if (FLAG_trace_type_finalization) {
|
||||
THR_Print("Instantiating signature '%s' of typedef '%s'\n",
|
||||
String::Handle(zone, signature.Signature()).ToCString(),
|
||||
String::Handle(zone, fun_type.Name()).ToCString());
|
||||
}
|
||||
signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld);
|
||||
// Note that if type_args contains type parameters, signature is still
|
||||
// uninstantiated here (typedef type parameters were substituted in the
|
||||
// signature with typedef type arguments).
|
||||
}
|
||||
fun_type.set_signature(signature);
|
||||
// The type was already marked as finalized and uninstantiated in
|
||||
// ExpandAndFinalizeTypeArguments above when its signature was not
|
||||
// instantiated yet. Check again by calling ResetIsFinalized().
|
||||
fun_type.ResetIsFinalized();
|
||||
} else {
|
||||
const Function& signature = Function::Handle(zone, fun_type.signature());
|
||||
FinalizeSignature(cls, signature);
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAG_trace_type_finalization) {
|
||||
THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n",
|
||||
String::Handle(zone, type.Name()).ToCString(),
|
||||
|
|
|
@ -16875,6 +16875,12 @@ bool Type::IsInstantiated(Genericity genericity, TrailPtr trail) const {
|
|||
if (HasResolvedTypeClass()) {
|
||||
const Class& cls = Class::Handle(type_class());
|
||||
len = cls.NumTypeParameters(); // Check the type parameters only.
|
||||
if (len > num_type_args) {
|
||||
// This type has the wrong number of arguments and is not finalized yet.
|
||||
// Type arguments are reset to null when finalizing such a type.
|
||||
ASSERT(!IsFinalized());
|
||||
len = num_type_args;
|
||||
}
|
||||
}
|
||||
return (len == 0) ||
|
||||
args.IsSubvectorInstantiated(num_type_args - len, len, genericity,
|
||||
|
@ -16921,10 +16927,12 @@ RawAbstractType* Type::InstantiateFrom(
|
|||
const LanguageError& bound_error = LanguageError::Handle(zone, error());
|
||||
instantiated_type.set_error(bound_error);
|
||||
}
|
||||
// If this type is a function type, instantiate its signature.
|
||||
// For a function type, possibly instantiate and set its signature.
|
||||
if (!sig_fun.IsNull()) {
|
||||
// If we are finalizing a typedef, do not yet instantiate its signature.
|
||||
// Other function types should never be instantiated while unfinalized.
|
||||
// If we are finalizing a typedef, do not yet instantiate its signature,
|
||||
// since it gets instantiated just before the type is marked as finalized.
|
||||
// Other function types should never get instantiated while unfinalized,
|
||||
// even while checking bounds of recursive types.
|
||||
if (IsFinalized()) {
|
||||
// A generic typedef may actually declare an instantiated signature.
|
||||
if (!sig_fun.HasInstantiatedSignature()) {
|
||||
|
@ -16932,7 +16940,8 @@ RawAbstractType* Type::InstantiateFrom(
|
|||
space);
|
||||
}
|
||||
} else {
|
||||
ASSERT(cls.IsTypedefClass());
|
||||
// The Kernel frontend does not keep the information that a function type
|
||||
// is a typedef, so we cannot assert that cls.IsTypedefClass().
|
||||
}
|
||||
instantiated_type.set_signature(sig_fun);
|
||||
}
|
||||
|
|
|
@ -88,11 +88,6 @@ cyclic_constructor_test/01: MissingCompileTimeError
|
|||
cyclic_type_test/00: RuntimeError
|
||||
cyclic_type_test/01: RuntimeError
|
||||
cyclic_type_test/03: RuntimeError
|
||||
cyclic_type_variable_test/01: Crash
|
||||
cyclic_type_variable_test/02: Crash
|
||||
cyclic_type_variable_test/03: Crash
|
||||
cyclic_type_variable_test/04: Crash
|
||||
cyclic_type_variable_test/none: Crash
|
||||
cyclic_typedef_test/01: MissingCompileTimeError
|
||||
cyclic_typedef_test/02: MissingCompileTimeError
|
||||
cyclic_typedef_test/03: MissingCompileTimeError
|
||||
|
@ -406,7 +401,6 @@ vm/optimized_stacktrace_test: Skip # Issue 28788
|
|||
[ $compiler == dartk && $mode == debug ]
|
||||
constructor_duplicate_initializers_test/03: Crash
|
||||
deopt_inlined_function_lazy_test: Skip
|
||||
function_malformed_result_type_test: Crash
|
||||
hello_dart_test: Crash # error: expected: cls.is_type_finalized()
|
||||
not_enough_positional_arguments_test/02: Crash # Dartk Issue 28301
|
||||
not_enough_positional_arguments_test/05: Crash # Dartk Issue 28301
|
||||
|
@ -419,7 +413,6 @@ ref_before_declaration_test/05: Crash
|
|||
ref_before_declaration_test/06: Crash
|
||||
ref_before_declaration_test/07: Crash
|
||||
ref_before_declaration_test/none: Crash
|
||||
regress_29025_test: Crash
|
||||
try_catch_syntax_test/05: Crash
|
||||
vm/lazy_deopt_vm_test: Crash
|
||||
|
||||
|
|
Loading…
Reference in a new issue