Skip to content

[5.9][SE-0393] Enable parameter packs for generic functions. #65215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/swift/AST/DiagnosticsCommon.def
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ ERROR(macro_experimental,none,
ERROR(ambiguous_macro_reference,none,
"ambiguous reference to macro %0", (DeclName))

//------------------------------------------------------------------------------
// MARK: tuple conformances
//------------------------------------------------------------------------------
ERROR(experimental_tuple_extension,none,
"tuple extensions are experimental",
())

//------------------------------------------------------------------------------
// MARK: bridged diagnostics
//------------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5370,6 +5370,10 @@ ERROR(tuple_pack_element_label,none,
ERROR(vararg_not_allowed,none,
"variadic parameter cannot appear outside of a function parameter list",
())

ERROR(experimental_type_with_parameter_pack,none,
"generic types with parameter packs are experimental",
())
ERROR(expansion_not_allowed,none,
"pack expansion %0 can only appear in a function parameter list, "
"tuple element, or generic argument list", (Type))
Expand Down
1 change: 1 addition & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ EXPERIMENTAL_FEATURE(NamedOpaqueTypes, false)
EXPERIMENTAL_FEATURE(FlowSensitiveConcurrencyCaptures, false)
EXPERIMENTAL_FEATURE(FreestandingMacros, true)
EXPERIMENTAL_FEATURE(CodeItemMacros, true)
EXPERIMENTAL_FEATURE(TupleConformances, false)

// FIXME: MoveOnlyClasses is not intended to be in production,
// but our tests currently rely on it, and we want to run those
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3208,6 +3208,10 @@ static bool usesFeatureVariadicGenerics(Decl *decl) {
return false;
}

static bool usesFeatureTupleConformances(Decl *decl) {
return false;
}

static bool usesFeatureLayoutPrespecialization(Decl *decl) {
auto &attrs = decl->getAttrs();
return std::any_of(attrs.begin(), attrs.end(), [](auto *attr) {
Expand Down
11 changes: 10 additions & 1 deletion lib/AST/NameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2981,7 +2981,16 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,

// If there is more than 1 element, we will emit a warning or an error
// elsewhere, so don't handle that case here.
return nominalTypes.empty() ? nullptr : nominalTypes[0];
if (nominalTypes.empty())
return nullptr;

// Diagnose experimental tuple extensions.
if (isa<BuiltinTupleDecl>(nominalTypes[0]) &&
!ctx.LangOpts.hasFeature(Feature::TupleConformances)) {
ext->diagnose(diag::experimental_tuple_extension);
}

return nominalTypes[0];
}

/// Whether there are only associated types in the set of declarations.
Expand Down
6 changes: 2 additions & 4 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6459,8 +6459,7 @@ ParserResult<TypeDecl> Parser::parseDeclAssociatedType(Parser::ParseDeclOptions
}

// Reject variadic associated types with a specific error.
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
Tok.isContextualKeyword("each")) {
if (Tok.isContextualKeyword("each")) {
const auto EachLoc = consumeToken();
diagnose(EachLoc, diag::associatedtype_cannot_be_variadic)
.fixItRemoveChars(EachLoc, Tok.getLoc());
Expand All @@ -6484,8 +6483,7 @@ ParserResult<TypeDecl> Parser::parseDeclAssociatedType(Parser::ParseDeclOptions
}

// Reject (early syntax) variadic associated types with a specific error.
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
startsWithEllipsis(Tok)) {
if (startsWithEllipsis(Tok)) {
const auto EllipsisLoc = consumeStartingEllipsis();
const auto EllipsisEnd = Lexer::getLocForEndOfToken(SourceMgr, EllipsisLoc);
diagnose(EllipsisLoc, diag::associatedtype_cannot_be_variadic)
Expand Down
18 changes: 5 additions & 13 deletions lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,7 @@ ParserResult<Expr> Parser::parseExprUnary(Diag<> Message, bool isExprBasic) {
tryLexRegexLiteral(/*forUnappliedOperator*/ false);

// 'repeat' as an expression prefix is a pack expansion expression.
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
Tok.is(tok::kw_repeat)) {
if (Tok.is(tok::kw_repeat)) {
SourceLoc repeatLoc = consumeToken();
auto patternExpr = parseExpr(Message);
if (patternExpr.isNull())
Expand Down Expand Up @@ -3024,17 +3023,10 @@ ParserResult<Expr> Parser::parseTupleOrParenExpr(tok leftTok, tok rightTok) {
rightLoc);

// A tuple with a single, unlabeled element is just parentheses.
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics)) {
if (elts.size() == 1 && !isa<PackExpansionExpr>(elts[0].E) &&
elts[0].LabelLoc.isInvalid()) {
return makeParserResult(
status, new (Context) ParenExpr(leftLoc, elts[0].E, rightLoc));
}
} else {
if (elts.size() == 1 && elts[0].Label.empty()) {
return makeParserResult(
status, new (Context) ParenExpr(leftLoc, elts[0].E, rightLoc));
}
if (elts.size() == 1 && !isa<PackExpansionExpr>(elts[0].E) &&
elts[0].Label.empty()) {
return makeParserResult(
status, new (Context) ParenExpr(leftLoc, elts[0].E, rightLoc));
}

SmallVector<Expr *, 8> exprs;
Expand Down
6 changes: 2 additions & 4 deletions lib/Parse/ParseGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ Parser::parseGenericParametersBeforeWhere(SourceLoc LAngleLoc,

// Parse the 'each' keyword for a type parameter pack 'each T'.
SourceLoc EachLoc;
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
Tok.isContextualKeyword("each")) {
if (Tok.isContextualKeyword("each")) {
TokReceiver->registerTokenKindChange(Tok.getLoc(),
tok::contextual_keyword);
EachLoc = consumeToken();
Expand All @@ -78,8 +77,7 @@ Parser::parseGenericParametersBeforeWhere(SourceLoc LAngleLoc,

// Parse and diagnose the unsupported ellipsis for a type parameter pack
// 'T...'.
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics) &&
startsWithEllipsis(Tok)) {
if (startsWithEllipsis(Tok)) {
const auto EllipsisLoc = consumeStartingEllipsis();
// TODO: token length hardcoded because calculation for ellipsis
// incorrectly includes '>' if one follows (as can occur in this parse).
Expand Down
3 changes: 1 addition & 2 deletions lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ bool Parser::isStartOfStmt() {
// is a pack expansion expression.
// FIXME: 'repeat' followed by '{' could be a pack expansion
// with a closure pattern.
return !Context.LangOpts.hasFeature(Feature::VariadicGenerics) ||
peekToken().is(tok::l_brace);
return peekToken().is(tok::l_brace);

case tok::pound_line:
// #line at the start of a line is a directive, when within, it is an expr.
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,8 +1755,7 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
// We pull these out special because variadic parameters ban lots of
// the more interesting typing constructs called out below like
// inout and @autoclosure.
if (cs.getASTContext().LangOpts.hasFeature(Feature::VariadicGenerics) &&
paramInfo.isVariadicGenericParameter(paramIdx)) {
if (paramInfo.isVariadicGenericParameter(paramIdx)) {
// If generic parameter comes from a variadic type declaration it's
// possible that it got specialized early and is no longer represented
// by a pack expansion type. For example, consider expression -
Expand Down
17 changes: 8 additions & 9 deletions lib/Sema/MiscDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,15 +293,14 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
}
}

if (!Ctx.LangOpts.hasFeature(Feature::VariadicGenerics)) {
// Diagnose single-element tuple expressions.
if (auto *tupleExpr = dyn_cast<TupleExpr>(E)) {
if (tupleExpr->getNumElements() == 1) {
Ctx.Diags.diagnose(tupleExpr->getElementNameLoc(0),
diag::tuple_single_element)
.fixItRemoveChars(tupleExpr->getElementNameLoc(0),
tupleExpr->getElement(0)->getStartLoc());
}
// Diagnose single-element tuple expressions.
if (auto *tupleExpr = dyn_cast<TupleExpr>(E)) {
if (tupleExpr->getNumElements() == 1 &&
!isa<PackExpansionExpr>(tupleExpr->getElement(0))) {
Ctx.Diags.diagnose(tupleExpr->getElementNameLoc(0),
diag::tuple_single_element)
.fixItRemoveChars(tupleExpr->getElementNameLoc(0),
tupleExpr->getElement(0)->getStartLoc());
}
}

Expand Down
9 changes: 9 additions & 0 deletions lib/Sema/TypeCheckDeclPrimary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,15 @@ static void checkGenericParams(GenericContext *ownerCtx) {
return;

for (auto gp : *genericParams) {
// Diagnose generic types with a parameter packs if VariadicGenerics
// is not enabled.
auto *decl = ownerCtx->getAsDecl();
auto &ctx = decl->getASTContext();
if (gp->isParameterPack() && isa<GenericTypeDecl>(decl) &&
!ctx.LangOpts.hasFeature(Feature::VariadicGenerics)) {
decl->diagnose(diag::experimental_type_with_parameter_pack);
}

TypeChecker::checkDeclAttributes(gp);
checkInheritanceClause(gp);
}
Expand Down
4 changes: 1 addition & 3 deletions test/Constraints/pack_expansion_types.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature VariadicGenerics

// REQUIRES: asserts
// RUN: %target-typecheck-verify-swift

func returnTuple1<each T>() -> (repeat each T) { fatalError() }
// expected-note@-1 3 {{in call to function 'returnTuple1()'}}
Expand Down
4 changes: 1 addition & 3 deletions test/Constraints/variadic_generic_constraints.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature VariadicGenerics

// REQUIRES: asserts
// RUN: %target-typecheck-verify-swift

// Test instantiation of constraint solver constraints from generic requirements
// involving type pack parameters
Expand Down
4 changes: 1 addition & 3 deletions test/Constraints/variadic_generic_functions.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature VariadicGenerics

// REQUIRES: asserts
// RUN: %target-typecheck-verify-swift

func debugPrint<each T>(_ items: repeat each T)
where repeat each T: CustomDebugStringConvertible
Expand Down
4 changes: 0 additions & 4 deletions test/DebugInfo/variadic-generics-count.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// RUN: %target-swift-frontend -emit-ir %s -g -o - \
// RUN: -enable-experimental-feature VariadicGenerics \
// RUN: -parse-as-library -module-name a | %FileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts

public func f1<each T>(ts: repeat each T) {
// CHECK: define {{.*}} @"$s1a2f12tsyxxQp_tRvzlF"(%swift.opaque** {{.*}}, i{{32|64}} [[COUNT1_1:.*]], %swift.type** {{.*}})
// CHECK-DAG: store i{{32|64}} [[COUNT1_1]], i{{32|64}}* %[[COUNT1_1_A:.*]], align
Expand Down
4 changes: 0 additions & 4 deletions test/DebugInfo/variadic-generics.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// RUN: %target-swift-frontend -emit-ir %s -g -o - \
// RUN: -enable-experimental-feature VariadicGenerics \
// RUN: -parse-as-library -module-name a | %FileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts

public func foo<each T>(args: repeat each T) {
// CHECK: define {{.*}} @"$s1a3foo4argsyxxQp_tRvzlF"
// CHECK-SAME: %swift.type** %[[TYPE_PACK_ARG:.*]])
Expand Down
2 changes: 1 addition & 1 deletion test/Generics/tuple-conformances.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature VariadicGenerics -parse-stdlib
// RUN: %target-typecheck-verify-swift -enable-experimental-feature TupleConformances -parse-stdlib

// REQUIRES: asserts

Expand Down
20 changes: 12 additions & 8 deletions test/IDE/complete_repeat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,23 @@ func enclosingFunc1() {
// REPEAT_4: Decl[LocalVar]/Local: local0[#Int#];
// REPEAT_4-NOT: LocalVar

repeat {
let local1 = 1
#^REPEAT_5^#
} while
do {
repeat {
let local1 = 1
#^REPEAT_5^#
} while
}
// REPEAT_5-NOT: LocalVar
// REPEAT_5: Decl[LocalVar]/Local: local1[#Int#];
// REPEAT_5-NOT: LocalVar

repeat {
let local1 = 1
do {
repeat {
let local2 = 1
} while #^REPEAT_COND_1^#
let local1 = 1
repeat {
let local2 = 1
} while #^REPEAT_COND_1^#
}
}
// REPEAT_COND_1-NOT: LocalVar
// REPEAT_COND_1: Decl[LocalVar]/Local: local1[#Int#];
Expand Down
7 changes: 2 additions & 5 deletions test/IRGen/run_variadic_generics.sil
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift-dylib(%t/%target-library-name(PrintShims)) -parse-stdlib %S/../Inputs/print-shims-stdlib.swift -module-name PrintShims -emit-module -emit-module-path %t/PrintShims.swiftmodule
// RUN: %target-codesign %t/%target-library-name(PrintShims)
// RUN: %target-build-swift -enable-experimental-feature VariadicGenerics -g -parse-sil %s -emit-ir -I %t -L %t -lPrintShim | %FileCheck %s --check-prefix=CHECK-LL
// RUN: %target-build-swift -enable-experimental-feature VariadicGenerics -g -parse-sil %s -module-name main -o %t/main -I %t -L %t -lPrintShims %target-rpath(%t)
// RUN: %target-build-swift -g -parse-sil %s -emit-ir -I %t -L %t -lPrintShim | %FileCheck %s --check-prefix=CHECK-LL
// RUN: %target-build-swift -g -parse-sil %s -module-name main -o %t/main -I %t -L %t -lPrintShims %target-rpath(%t)
// RUN: %target-codesign %t/main
// RUN: %target-run %t/main %t/%target-library-name(PrintShims) | %FileCheck %s

// REQUIRES: executable_test

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts

import Builtin
import Swift
import PrintShims
Expand Down
5 changes: 1 addition & 4 deletions test/IRGen/variadic_generic_captures.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
// REQUIRES: rdar107424494
// RUN: %target-swift-frontend -emit-ir %s -enable-experimental-feature VariadicGenerics | %FileCheck %s -DINT=i%target-ptrsize

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s -DINT=i%target-ptrsize

public func takesNoEscape(_: () -> ()) {}

Expand Down
5 changes: 1 addition & 4 deletions test/IRGen/variadic_generic_functions.sil
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// RUN: %target-swift-frontend -parse-sil -emit-ir -primary-file %s -enable-experimental-feature VariadicGenerics | %IRGenFileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts
// RUN: %target-swift-frontend -parse-sil -emit-ir -primary-file %s | %IRGenFileCheck %s

import Builtin
import Swift
Expand Down
5 changes: 1 addition & 4 deletions test/IRGen/variadic_generic_functions.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// RUN: %target-swift-frontend -emit-ir -primary-file %s -enable-experimental-feature VariadicGenerics | %FileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts
// RUN: %target-swift-frontend -emit-ir -primary-file %s | %FileCheck %s

// REQUIRES: PTRSIZE=64

Expand Down
5 changes: 1 addition & 4 deletions test/IRGen/variadic_generic_outlining.sil
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// RUN: %target-swift-frontend -emit-ir -primary-file %s -enable-experimental-feature VariadicGenerics | %IRGenFileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts
// RUN: %target-swift-frontend -emit-ir -primary-file %s | %IRGenFileCheck %s

import Builtin
import Swift
Expand Down
5 changes: 1 addition & 4 deletions test/IRGen/variadic_generics.sil
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// RUN: %target-swift-frontend -emit-ir -primary-file %s -enable-experimental-feature VariadicGenerics | %IRGenFileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts
// RUN: %target-swift-frontend -emit-ir -primary-file %s | %IRGenFileCheck %s

import Builtin
import Swift
Expand Down
7 changes: 2 additions & 5 deletions test/Interpreter/variadic_generic_captures.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// RUN: %target-run-simple-swift(-enable-experimental-feature VariadicGenerics -Xfrontend -disable-concrete-type-metadata-mangled-name-accessors)
// RUN: %target-run-simple-swift(-enable-experimental-feature VariadicGenerics)
// RUN: %target-run-simple-swift(-Xfrontend -disable-concrete-type-metadata-mangled-name-accessors)
// RUN: %target-run-simple-swift

// REQUIRES: executable_test

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts

// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime

Expand Down
5 changes: 1 addition & 4 deletions test/Interpreter/variadic_generic_tuples.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// RUN: %target-run-simple-swift(-enable-experimental-feature VariadicGenerics)
// RUN: %target-run-simple-swift

// FIXME: Fix the optimizer
// REQUIRES: swift_test_mode_optimize_none

// REQUIRES: executable_test

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts

import StdlibUnittest

var tuples = TestSuite("VariadicGenericTuples")
Expand Down
4 changes: 2 additions & 2 deletions test/Macros/macro_expand_variadic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

// RUN: %empty-directory(%t)
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/variadic_macros.swift -g -no-toolchain-stdlib-rpath
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature VariadicGenerics -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5
// RUN: %target-build-swift -swift-version 5 -enable-experimental-feature VariadicGenerics -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5
// RUN: %target-build-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5
// RUN: %target-codesign %t/main
// RUN: %target-run %t/main | %FileCheck %s

Expand Down
2 changes: 1 addition & 1 deletion test/SIL/Parser/variadic_generics.sil
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-sil-opt -enable-experimental-feature VariadicGenerics -enable-sil-verify-all=true %s | %target-sil-opt -enable-experimental-feature VariadicGenerics -enable-sil-verify-all=true | %FileCheck %s
// RUN: %target-sil-opt -enable-sil-verify-all=true %s | %target-sil-opt -enable-sil-verify-all=true | %FileCheck %s

import Builtin
import Swift
Expand Down
5 changes: 1 addition & 4 deletions test/SILGen/variadic-generic-arguments.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// RUN: %target-swift-emit-silgen -enable-experimental-feature VariadicGenerics %s | %FileCheck %s

// Because of -enable-experimental-feature VariadicGenerics
// REQUIRES: asserts
// RUN: %target-swift-emit-silgen %s | %FileCheck %s

// CHECK-LABEL: @$s4main14receive_simpleyyxxQpRvzlF : $@convention(thin) <each T> (@pack_guaranteed Pack{repeat each T}) -> () {
// CHECK: bb0(%0 : $*Pack{repeat each T}):
Expand Down
Loading