[cfe] Allow unnamed optional wildcard parameters to have no default value.

Wildcard optional parameters aren't used anyways, so it doesn't matter if they have a default value.
This CL removes the error that's typically there.

Bug: https://github.com/dart-lang/sdk/issues/55655
Change-Id: Ie7286e1c3650fa347b1c28f1cc4ebd657cca33de
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371560
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Kallen Tu 2024-06-14 21:30:05 +00:00 committed by Commit Queue
parent 9d642f43fe
commit d15a3963e7
10 changed files with 97 additions and 4 deletions

View file

@ -2109,7 +2109,8 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
FormalParameterBuilder formal = new FormalParameterBuilder(
kind, modifiers, type, name, _sourceLibraryBuilder, charOffset,
fileUri: fileUri,
hasImmediatelyDeclaredInitializer: initializerToken != null)
hasImmediatelyDeclaredInitializer: initializerToken != null,
isWildcard: libraryFeatures.wildcardVariables.isEnabled && name == '_')
..initializerToken = initializerToken;
return formal;
}
@ -5242,6 +5243,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
if (isOptional &&
formal.variable!.type.isPotentiallyNonNullable &&
!formal.hasDeclaredInitializer) {
// Wildcard optional parameters can't be used so we allow having no
// initializer.
if (libraryFeatures.wildcardVariables.isEnabled &&
formal.isWildcard &&
!formal.isSuperInitializingFormal &&
!formal.isInitializingFormal) {
continue;
}
addProblem(
templateOptionalNonNullableWithoutInitializerError.withArguments(
formal.name, formal.variable!.type),

View file

@ -2120,6 +2120,13 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
if ((isOptionalPositional || isOptionalNamed) &&
formal.type.isPotentiallyNonNullable &&
!formal.hasDeclaredInitializer) {
// Wildcard optional parameters can't be used so we allow having no
// initializer.
if (libraryFeatures.wildcardVariables.isEnabled &&
formal.isWildcard &&
!formal.isInitializingFormal) {
continue;
}
libraryBuilder.addProblem(
templateOptionalNonNullableWithoutInitializerError.withArguments(
formal.name!, formal.type),

View file

@ -0,0 +1,13 @@
// Copyright (c) 2024, 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 foo([int _]) {}
void main() {
void bar([int _]) {}
void bar1([int _, int _]) {}
void bar2([int _, int _ = 2]) {}
void bar3([int _ = 2, int _]) {}
void bar4([int x = 2, int? _, int _]) {}
}

View file

@ -0,0 +1,17 @@
library;
import self as self;
import "dart:core" as core;
static method foo([wildcard core::int _ = #C1]) → void {}
static method main() → void {
function bar([wildcard core::int _ = #C1]) → void {}
function bar1([wildcard core::int _ = #C1, wildcard core::int _ = #C1]) → void {}
function bar2([wildcard core::int _ = #C1, wildcard core::int _ = #C2]) → void {}
function bar3([wildcard core::int _ = #C2, wildcard core::int _ = #C1]) → void {}
function bar4([core::int x = #C2, wildcard core::int? _ = #C1, wildcard core::int _ = #C1]) → void {}
}
constants {
#C1 = null
#C2 = 2
}

View file

@ -0,0 +1,17 @@
library;
import self as self;
import "dart:core" as core;
static method foo([wildcard core::int _ = #C1]) → void {}
static method main() → void {
function bar([wildcard core::int _ = #C1]) → void {}
function bar1([wildcard core::int _ = #C1, wildcard core::int _ = #C1]) → void {}
function bar2([wildcard core::int _ = #C1, wildcard core::int _ = #C2]) → void {}
function bar3([wildcard core::int _ = #C2, wildcard core::int _ = #C1]) → void {}
function bar4([core::int x = #C2, wildcard core::int? _ = #C1, wildcard core::int _ = #C1]) → void {}
}
constants {
#C1 = null
#C2 = 2
}

View file

@ -0,0 +1,8 @@
library;
import self as self;
import "dart:core" as core;
static method foo([wildcard core::int _]) → void
;
static method main() → void
;

View file

@ -0,0 +1,17 @@
library;
import self as self;
import "dart:core" as core;
static method foo([wildcard core::int _ = #C1]) → void {}
static method main() → void {
function bar([wildcard core::int _ = #C1]) → void {}
function bar1([wildcard core::int _ = #C1, wildcard core::int _ = #C1]) → void {}
function bar2([wildcard core::int _ = #C1, wildcard core::int _ = #C2]) → void {}
function bar3([wildcard core::int _ = #C2, wildcard core::int _ = #C1]) → void {}
function bar4([core::int x = #C2, wildcard core::int? _ = #C1, wildcard core::int _ = #C1]) → void {}
}
constants {
#C1 = null
#C2 = 2
}

View file

@ -0,0 +1,3 @@
void foo([int _]) {}
void main() {}

View file

@ -0,0 +1,3 @@
void foo([int _]) {}
void main() {}

View file

@ -10,11 +10,9 @@
class SuperClass {
SuperClass([int _]);
// ^
// [analyzer] COMPILE_TIME_ERROR.MISSING_DEFAULT_VALUE_FOR_PARAMETER
// [cfe] The parameter '_' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
SuperClass.nullable([int? _]);
}
class SubClass extends SuperClass {
final int _;
SubClass([
@ -31,6 +29,7 @@ class SubClass extends SuperClass {
// [cfe] Type 'int' of the optional super-initializer parameter '_' doesn't allow 'null', but the parameter doesn't have a default value, and the default value can't be copied from the corresponding parameter of the super constructor.
]);
}
class TypedSubClass extends SuperClass {
final int? _;
TypedSubClass([