diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart index 0b2385bbead..9888c6abb10 100644 --- a/pkg/compiler/lib/src/ir/scope_visitor.dart +++ b/pkg/compiler/lib/src/ir/scope_visitor.dart @@ -403,6 +403,9 @@ class ScopeModelBuilder extends ir.VisitorDefault @override EvaluationComplexity visitStructuralParameter( ir.StructuralParameter typeParameter) { + // Visit the default type to register any necessary type parameters that RTI + // might need if the associated function is used as a generic tear off. + visitNode(typeParameter.defaultType); return const EvaluationComplexity.constant(); } diff --git a/tests/web/regress/issue/54451_test.dart b/tests/web/regress/issue/54451_test.dart new file mode 100644 index 00000000000..1cf9bb51a82 --- /dev/null +++ b/tests/web/regress/issue/54451_test.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Tests that the bounds for structural parameters of a Function type are +// visited and any type variables RTI might need are registered. + +class A { + void foo1() { + void bar1()>() {} + print(bar1.runtimeType); // Crashes compiler if A.T is not accessible. + } +} + +extension on T { + void foo2() { + void bar2()>() {} + print(bar2.runtimeType); // Crashes compiler if T is not accessible. + } +} + +void main() { + A().foo1(); + 1.foo2(); +}