From 225b342d715cc72854270cff82a0a501dcb500b0 Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Thu, 16 Apr 2026 03:20:14 -0700 Subject: [PATCH] [cfe] Don't treat named parameters as wildcards Named parameters named '_' cannot be used neither as wildcards nor private named parameters. Such parameters were wrongfully treated as wildcards, triggering name mangling and consequently call site errors. This change avoids handling these as wildcards. Closes #63170 Change-Id: Ice594537e09892eec5033f64122aa665ad904773 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495301 Commit-Queue: Johnni Winther Reviewed-by: Chloe Stefantsova --- .../lib/src/source/fragment_factory_impl.dart | 4 +- ...rresponding_public_name.dart.strong.expect | 4 +- ...ing_public_name.dart.strong.modular.expect | 4 +- ...ing_public_name.dart.strong.outline.expect | 2 +- ...public_name.dart.strong.transformed.expect | 4 +- .../wildcard_named_parameters.dart | 17 +++++++ ...ldcard_named_parameters.dart.strong.expect | 48 +++++++++++++++++++ ...amed_parameters.dart.strong.modular.expect | 48 +++++++++++++++++++ ...amed_parameters.dart.strong.outline.expect | 41 ++++++++++++++++ ..._parameters.dart.strong.transformed.expect | 48 +++++++++++++++++++ ...med_parameters.dart.textual_outline.expect | 10 ++++ ...eters.dart.textual_outline_modelled.expect | 10 ++++ 12 files changed, 232 insertions(+), 8 deletions(-) create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.expect create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline_modelled.expect diff --git a/pkg/front_end/lib/src/source/fragment_factory_impl.dart b/pkg/front_end/lib/src/source/fragment_factory_impl.dart index 24cb11af35a..dbfd205c9d4 100644 --- a/pkg/front_end/lib/src/source/fragment_factory_impl.dart +++ b/pkg/front_end/lib/src/source/fragment_factory_impl.dart @@ -2241,7 +2241,9 @@ class FragmentFactoryImpl implements FragmentFactory { modifiers |= Modifiers.SuperInitializingFormal; } bool isWildcard = - libraryFeatures.wildcardVariables.isEnabled && name == '_'; + kind.isPositional && + libraryFeatures.wildcardVariables.isEnabled && + name == '_'; int? wildcardIndex; if (isWildcard) { wildcardIndex = wildcardVariableIndex++; diff --git a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.expect b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.expect index ab3d5d6e9b4..f931463083d 100644 --- a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.expect +++ b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.expect @@ -26,8 +26,8 @@ class C extends core::Object { field core::int? __extraPrivate; field core::int? _123; field core::int? _for; - constructor onlyUnderscore({wildcard initializing-formal core::int? _#wc0#formal = #C1}) → self::C - : self::C::_for = null, self::C::_123 = null, self::C::__extraPrivate = null, self::C::_ = _#wc0#formal, super core::Object::•() + constructor onlyUnderscore({initializing-formal core::int? _ = #C1}) → self::C + : self::C::_for = null, self::C::_123 = null, self::C::__extraPrivate = null, self::C::_ = _, super core::Object::•() ; constructor stillPrivate({initializing-formal core::int? __extraPrivate = #C1}) → self::C : self::C::_for = null, self::C::_123 = null, self::C::_ = null, self::C::__extraPrivate = __extraPrivate, super core::Object::•() diff --git a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.modular.expect b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.modular.expect index ab3d5d6e9b4..f931463083d 100644 --- a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.modular.expect +++ b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.modular.expect @@ -26,8 +26,8 @@ class C extends core::Object { field core::int? __extraPrivate; field core::int? _123; field core::int? _for; - constructor onlyUnderscore({wildcard initializing-formal core::int? _#wc0#formal = #C1}) → self::C - : self::C::_for = null, self::C::_123 = null, self::C::__extraPrivate = null, self::C::_ = _#wc0#formal, super core::Object::•() + constructor onlyUnderscore({initializing-formal core::int? _ = #C1}) → self::C + : self::C::_for = null, self::C::_123 = null, self::C::__extraPrivate = null, self::C::_ = _, super core::Object::•() ; constructor stillPrivate({initializing-formal core::int? __extraPrivate = #C1}) → self::C : self::C::_for = null, self::C::_123 = null, self::C::_ = null, self::C::__extraPrivate = __extraPrivate, super core::Object::•() diff --git a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.outline.expect b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.outline.expect index ec580ea4c48..20931a8c069 100644 --- a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.outline.expect +++ b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.outline.expect @@ -26,7 +26,7 @@ class C extends core::Object { field core::int? __extraPrivate; field core::int? _123; field core::int? _for; - constructor onlyUnderscore({wildcard initializing-formal core::int? _#wc0#formal = null}) → self::C + constructor onlyUnderscore({initializing-formal core::int? _ = null}) → self::C ; constructor stillPrivate({initializing-formal core::int? __extraPrivate = null}) → self::C ; diff --git a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.transformed.expect b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.transformed.expect index ab3d5d6e9b4..f931463083d 100644 --- a/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/private_named_parameters/no_corresponding_public_name.dart.strong.transformed.expect @@ -26,8 +26,8 @@ class C extends core::Object { field core::int? __extraPrivate; field core::int? _123; field core::int? _for; - constructor onlyUnderscore({wildcard initializing-formal core::int? _#wc0#formal = #C1}) → self::C - : self::C::_for = null, self::C::_123 = null, self::C::__extraPrivate = null, self::C::_ = _#wc0#formal, super core::Object::•() + constructor onlyUnderscore({initializing-formal core::int? _ = #C1}) → self::C + : self::C::_for = null, self::C::_123 = null, self::C::__extraPrivate = null, self::C::_ = _, super core::Object::•() ; constructor stillPrivate({initializing-formal core::int? __extraPrivate = #C1}) → self::C : self::C::_for = null, self::C::_123 = null, self::C::_ = null, self::C::__extraPrivate = __extraPrivate, super core::Object::•() diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart new file mode 100644 index 00000000000..7f6424e4853 --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2026, 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. + +void f1({int _ = 0}) {} +void f2({int _ = 0, String _ = ''}) {} + +class C { + int _; + C({this._ = 0}); +} + +test() { + f1(_: 1); + f2(_: 2); + C(_: 3); +} diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.expect b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.expect new file mode 100644 index 00000000000..bba1340c50f --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.expect @@ -0,0 +1,48 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:5:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f1({int _ = 0}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: Duplicated parameter name '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Context: Other parameter named '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:10:11: Error: A private named parameter must have a corresponding public name. +// C({this._ = 0}); +// ^ +// +import self as self; +import "dart:core" as core; + +class C extends core::Object { + field core::int _; + constructor •({initializing-formal core::int _ = #C1}) → self::C + : self::C::_ = _, super core::Object::•() + ; +} +static method f1({core::int _ = #C1}) → void {} +static method f2({core::int _ = #C1, core::String _ = #C2}) → void {} +static method test() → dynamic { + self::f1(_: 1); + self::f2(_: 2); + new self::C::•(_: 3); +} + +constants { + #C1 = 0 + #C2 = "" +} diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.modular.expect b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.modular.expect new file mode 100644 index 00000000000..bba1340c50f --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.modular.expect @@ -0,0 +1,48 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:5:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f1({int _ = 0}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: Duplicated parameter name '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Context: Other parameter named '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:10:11: Error: A private named parameter must have a corresponding public name. +// C({this._ = 0}); +// ^ +// +import self as self; +import "dart:core" as core; + +class C extends core::Object { + field core::int _; + constructor •({initializing-formal core::int _ = #C1}) → self::C + : self::C::_ = _, super core::Object::•() + ; +} +static method f1({core::int _ = #C1}) → void {} +static method f2({core::int _ = #C1, core::String _ = #C2}) → void {} +static method test() → dynamic { + self::f1(_: 1); + self::f2(_: 2); + new self::C::•(_: 3); +} + +constants { + #C1 = 0 + #C2 = "" +} diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.outline.expect b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.outline.expect new file mode 100644 index 00000000000..4da11cc325e --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.outline.expect @@ -0,0 +1,41 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:5:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f1({int _ = 0}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: Duplicated parameter name '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Context: Other parameter named '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:10:11: Error: A private named parameter must have a corresponding public name. +// C({this._ = 0}); +// ^ +// +import self as self; +import "dart:core" as core; + +class C extends core::Object { + field core::int _; + constructor •({initializing-formal core::int _ = 0}) → self::C + ; +} +static method f1({has-declared-initializer core::int _}) → void + ; +static method f2({has-declared-initializer core::int _, has-declared-initializer core::String _}) → void + ; +static method test() → dynamic + ; diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.transformed.expect new file mode 100644 index 00000000000..bba1340c50f --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.strong.transformed.expect @@ -0,0 +1,48 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:5:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f1({int _ = 0}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: A named parameter that doesn't refer to an instance variable can't start with an underscore ('_'). +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:28: Error: Duplicated parameter name '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:6:14: Context: Other parameter named '_'. +// void f2({int _ = 0, String _ = ''}) {} +// ^ +// +// pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart:10:11: Error: A private named parameter must have a corresponding public name. +// C({this._ = 0}); +// ^ +// +import self as self; +import "dart:core" as core; + +class C extends core::Object { + field core::int _; + constructor •({initializing-formal core::int _ = #C1}) → self::C + : self::C::_ = _, super core::Object::•() + ; +} +static method f1({core::int _ = #C1}) → void {} +static method f2({core::int _ = #C1, core::String _ = #C2}) → void {} +static method test() → dynamic { + self::f1(_: 1); + self::f2(_: 2); + new self::C::•(_: 3); +} + +constants { + #C1 = 0 + #C2 = "" +} diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline.expect new file mode 100644 index 00000000000..15b8dd0109d --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline.expect @@ -0,0 +1,10 @@ +void f1({int _ = 0}) {} + +void f2({int _ = 0, String _ = ''}) {} + +class C { + int _; + C({this._ = 0}); +} + +test() {} diff --git a/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..65ec4727541 --- /dev/null +++ b/pkg/front_end/testcases/private_named_parameters/wildcard_named_parameters.dart.textual_outline_modelled.expect @@ -0,0 +1,10 @@ +class C { + C({this._ = 0}); + int _; +} + +test() {} + +void f1({int _ = 0}) {} + +void f2({int _ = 0, String _ = ''}) {}