Skip to content

Commit 3603af3

Browse files
sjindel-googlecommit-bot@chromium.org
authored andcommitted
[vm] Instantiate type parameter bounds on closures.
Fixes #34308. Change-Id: I7d998daa752ada13368631fc327a5c3595ec406c Reviewed-on: https://dart-review.googlesource.com/72160 Commit-Queue: Samir Jindel <[email protected]> Reviewed-by: Régis Crelier <[email protected]>
1 parent 9803d5c commit 3603af3

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

runtime/vm/object.cc

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7131,11 +7131,50 @@ RawFunction* Function::InstantiateSignatureFrom(
71317131

71327132
Function& sig = Function::Handle(Function::NewSignatureFunction(
71337133
owner, parent, TokenPosition::kNoSource, space));
7134+
AbstractType& type = AbstractType::Handle(zone);
7135+
7136+
// Copy the type parameters and instantiate their bounds (if necessary).
71347137
if (!delete_type_parameters) {
7135-
sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
7138+
const TypeArguments& type_params =
7139+
TypeArguments::Handle(zone, type_parameters());
7140+
if (!type_params.IsNull()) {
7141+
TypeArguments& instantiated_type_params = TypeArguments::Handle(zone);
7142+
TypeParameter& type_param = TypeParameter::Handle(zone);
7143+
Class& cls = Class::Handle(zone);
7144+
String& param_name = String::Handle(zone);
7145+
for (intptr_t i = 0; i < type_params.Length(); ++i) {
7146+
type_param ^= type_params.TypeAt(i);
7147+
type = type_param.bound();
7148+
if (!type.IsInstantiated(kAny, num_free_fun_type_params)) {
7149+
type = type.InstantiateFrom(
7150+
instantiator_type_arguments, function_type_arguments,
7151+
num_free_fun_type_params, NULL, NULL, NULL, space);
7152+
cls = type_param.parameterized_class();
7153+
param_name = type_param.name();
7154+
ASSERT(type_param.IsFinalized());
7155+
type_param ^=
7156+
TypeParameter::New(cls, sig, type_param.index(), param_name, type,
7157+
type_param.token_pos());
7158+
type_param.SetIsFinalized();
7159+
if (instantiated_type_params.IsNull()) {
7160+
instantiated_type_params = TypeArguments::New(type_params.Length());
7161+
for (intptr_t j = 0; j < i; ++j) {
7162+
type = type_params.TypeAt(j);
7163+
instantiated_type_params.SetTypeAt(j, type);
7164+
}
7165+
}
7166+
instantiated_type_params.SetTypeAt(i, type_param);
7167+
} else if (!instantiated_type_params.IsNull()) {
7168+
instantiated_type_params.SetTypeAt(i, type_param);
7169+
}
7170+
}
7171+
sig.set_type_parameters(instantiated_type_params.IsNull()
7172+
? type_params
7173+
: instantiated_type_params);
7174+
}
71367175
}
71377176

7138-
AbstractType& type = AbstractType::Handle(zone, result_type());
7177+
type = result_type();
71397178
if (!type.IsInstantiated(kAny, num_free_fun_type_params)) {
71407179
type = type.InstantiateFrom(
71417180
instantiator_type_arguments, function_type_arguments,
@@ -7888,6 +7927,15 @@ bool Function::HasInstantiatedSignature(Genericity genericity,
78887927
return false;
78897928
}
78907929
}
7930+
TypeArguments& type_params = TypeArguments::Handle(type_parameters());
7931+
TypeParameter& type_param = TypeParameter::Handle();
7932+
for (intptr_t i = 0; i < type_params.Length(); ++i) {
7933+
type_param ^= type_params.TypeAt(i);
7934+
type = type_param.bound();
7935+
if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) {
7936+
return false;
7937+
}
7938+
}
78917939
return true;
78927940
}
78937941

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// This test checks that the type parameter bounds on tearoffs from generic
6+
// classes are properly instantiated in the signature of the tearoff.
7+
8+
import "package:expect/expect.dart";
9+
10+
class C<T> {
11+
void foo<S extends T>(S x) {}
12+
}
13+
14+
void foo<S extends int>(S x) {}
15+
16+
void main() {
17+
dynamic c = C<int>();
18+
dynamic fn = c.foo;
19+
Expect.equals("${fn.runtimeType}", "${foo.runtimeType}");
20+
}

0 commit comments

Comments
 (0)