| Index: runtime/vm/constant_propagator.cc
|
| diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
|
| index 95bc646a8e76ce2d03fd7c725300ba6361005d40..a1279ec5d69447758975a1a1bcfce403918b5185 100644
|
| --- a/runtime/vm/constant_propagator.cc
|
| +++ b/runtime/vm/constant_propagator.cc
|
| @@ -763,10 +763,13 @@ void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) {
|
| if (value.IsInstance()) {
|
| const Instance& instance = Instance::Cast(value);
|
| const AbstractType& checked_type = instr->type();
|
| - if (instr->instantiator_type_arguments()->BindsToConstantNull()) {
|
| + if (instr->instantiator_type_arguments()->BindsToConstantNull() &&
|
| + instr->function_type_arguments()->BindsToConstantNull() &&
|
| + checked_type.IsInstantiated(kParentFunctions)) {
|
| Error& bound_error = Error::Handle();
|
| - bool is_instance = instance.IsInstanceOf(
|
| - checked_type, Object::null_type_arguments(), &bound_error);
|
| + bool is_instance =
|
| + instance.IsInstanceOf(checked_type, Object::null_type_arguments(),
|
| + Object::null_type_arguments(), &bound_error);
|
| // Can only have bound error with generics.
|
| ASSERT(bound_error.IsNull());
|
| SetValue(instr, Bool::Get(is_instance));
|
| @@ -860,13 +863,13 @@ void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
|
| void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) {
|
| const Object& object =
|
| instr->instantiator_type_arguments()->definition()->constant_value();
|
| - // TODO(regis): Check function type arguments.
|
| if (IsNonConstant(object)) {
|
| SetValue(instr, non_constant_);
|
| return;
|
| }
|
| if (IsConstant(object)) {
|
| - if (instr->type().IsTypeParameter()) {
|
| + if (instr->type().IsTypeParameter() &&
|
| + TypeParameter::Cast(instr->type()).IsClassTypeParameter()) {
|
| if (object.IsNull()) {
|
| SetValue(instr, Object::dynamic_type());
|
| return;
|
| @@ -876,32 +879,46 @@ void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) {
|
| }
|
| SetValue(instr, non_constant_);
|
| }
|
| + // TODO(regis): We can do the same as above for a function type parameter.
|
| + // Better: If both instantiator type arguments and function type arguments are
|
| + // constant, instantiate the type if no bound error is reported.
|
| }
|
|
|
|
|
| void ConstantPropagator::VisitInstantiateTypeArguments(
|
| InstantiateTypeArgumentsInstr* instr) {
|
| - const Object& object =
|
| + const Object& instantiator_type_args =
|
| instr->instantiator_type_arguments()->definition()->constant_value();
|
| - // TODO(regis): Check function type arguments.
|
| - if (IsNonConstant(object)) {
|
| + const Object& function_type_args =
|
| + instr->function_type_arguments()->definition()->constant_value();
|
| + if (IsNonConstant(instantiator_type_args) ||
|
| + IsNonConstant(function_type_args)) {
|
| SetValue(instr, non_constant_);
|
| return;
|
| }
|
| - if (IsConstant(object)) {
|
| - const intptr_t len = instr->type_arguments().Length();
|
| - if (instr->type_arguments().IsRawInstantiatedRaw(len) && object.IsNull()) {
|
| - SetValue(instr, object);
|
| - return;
|
| + if (IsConstant(instantiator_type_args) && IsConstant(function_type_args)) {
|
| + if (instantiator_type_args.IsNull() && function_type_args.IsNull()) {
|
| + const intptr_t len = instr->type_arguments().Length();
|
| + if (instr->type_arguments().IsRawWhenInstantiatedFromRaw(len)) {
|
| + SetValue(instr, instantiator_type_args);
|
| + return;
|
| + }
|
| }
|
| if (instr->type_arguments().IsUninstantiatedIdentity() ||
|
| instr->type_arguments().CanShareInstantiatorTypeArguments(
|
| instr->instantiator_class())) {
|
| - SetValue(instr, object);
|
| + SetValue(instr, instantiator_type_args);
|
| return;
|
| }
|
| SetValue(instr, non_constant_);
|
| }
|
| + // TODO(regis): If both instantiator type arguments and function type
|
| + // arguments are constant, instantiate the type arguments if no bound error
|
| + // is reported.
|
| + // TODO(regis): If either instantiator type arguments or function type
|
| + // arguments are constant null, check
|
| + // type_arguments().IsRawWhenInstantiatedFromRaw() separately for each
|
| + // genericity.
|
| }
|
|
|
|
|
|
|