Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1344)

Unified Diff: runtime/vm/object.cc

Issue 2696783002: Properly resolve upper bounds of generic function's type parameters. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8a61e4ca56842e6df2e0cc1d1cda00478a59ccec..e90a3cce45c7980ceaab5a5608f26d5d237bbb93 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -5905,24 +5905,28 @@ RawTypeParameter* Function::LookupTypeParameter(
Function& function = thread->FunctionHandle();
function ^= this->raw();
- intptr_t parent_level = -1;
+ intptr_t parent_level = 0;
while (!function.IsNull()) {
type_params ^= function.type_parameters();
if (!type_params.IsNull()) {
- parent_level++;
const intptr_t num_type_params = type_params.Length();
for (intptr_t i = 0; i < num_type_params; i++) {
type_param ^= type_params.TypeAt(i);
type_param_name = type_param.name();
if (type_param_name.Equals(type_name)) {
if (parent_level > 0) {
- // TODO(regis): Clone type parameter and set parent_level.
+ // Clone type parameter and set parent_level.
+ return TypeParameter::New(
+ Class::Handle(), function, type_param.index(), parent_level,
+ type_param_name, AbstractType::Handle(type_param.bound()),
+ TokenPosition::kNoSource);
}
return type_param.raw();
}
}
}
function ^= function.parent_function();
+ parent_level++;
if (function_level != NULL) {
(*function_level)--;
}
@@ -15601,6 +15605,9 @@ bool Instance::IsInstanceOf(const AbstractType& other,
Function::Handle(zone, Closure::Cast(*this).function());
const TypeArguments& type_arguments =
TypeArguments::Handle(zone, GetTypeArguments());
+ // TODO(regis): If signature function is generic, pass its type parameters
+ // as function instantiator, otherwise pass null.
+ // Pass the closure context as well to the the IsSubtypeOf call.
return signature.IsSubtypeOf(type_arguments, other_signature,
other_type_arguments, bound_error, Heap::kOld);
}
@@ -17775,7 +17782,7 @@ RawAbstractType* TypeParameter::CloneUnfinalized() const {
// No need to clone bound, as it is not part of the finalization state.
return TypeParameter::New(Class::Handle(parameterized_class()),
Function::Handle(parameterized_function()), index(),
- String::Handle(name()),
+ parent_level(), String::Handle(name()),
AbstractType::Handle(bound()), token_pos());
}
@@ -17789,11 +17796,16 @@ RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner,
return clone.raw();
}
const Class& old_owner = Class::Handle(parameterized_class());
+ if (old_owner.IsNull()) {
+ ASSERT(IsFunctionTypeParameter());
+ // Function type parameters do not need cloning.
+ return raw();
+ }
const intptr_t new_index =
index() + new_owner.NumTypeArguments() - old_owner.NumTypeArguments();
AbstractType& upper_bound = AbstractType::Handle(bound());
ASSERT(parameterized_function() == Function::null());
- clone = TypeParameter::New(new_owner, Function::Handle(), new_index,
+ clone = TypeParameter::New(new_owner, Function::Handle(), new_index, 0,
String::Handle(name()),
upper_bound, // Not cloned yet.
token_pos());
@@ -17844,6 +17856,7 @@ RawTypeParameter* TypeParameter::New() {
RawTypeParameter* TypeParameter::New(const Class& parameterized_class,
const Function& parameterized_function,
intptr_t index,
+ intptr_t parent_level,
const String& name,
const AbstractType& bound,
TokenPosition token_pos) {
@@ -17852,6 +17865,7 @@ RawTypeParameter* TypeParameter::New(const Class& parameterized_class,
result.set_parameterized_class(parameterized_class);
result.set_parameterized_function(parameterized_function);
result.set_index(index);
+ result.set_parent_level(parent_level);
result.set_name(name);
result.set_bound(bound);
result.SetHash(0);
@@ -17868,7 +17882,9 @@ void TypeParameter::set_token_pos(TokenPosition token_pos) const {
}
-void TypeParameter::set_parent_level(uint8_t value) const {
+void TypeParameter::set_parent_level(intptr_t value) const {
+ // TODO(regis): Report error in caller if not uint8.
+ ASSERT(Utils::IsUint(8, value));
StoreNonPointer(&raw_ptr()->parent_level_, value);
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698