Skip to content

Commit da76e1e

Browse files
committed
Sema: Allow one-element tuples when -enable-experimental-variadic-generics is on
1 parent 9a875f8 commit da76e1e

File tree

6 files changed

+63
-40
lines changed

6 files changed

+63
-40
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,9 +3181,16 @@ ParserResult<Expr> Parser::parseTupleOrParenExpr(tok leftTok, tok rightTok) {
31813181
rightLoc, SyntaxKind::TupleExprElementList);
31823182

31833183
// A tuple with a single, unlabeled element is just parentheses.
3184-
if (elts.size() == 1 && elts[0].Label.empty()) {
3185-
return makeParserResult(
3186-
status, new (Context) ParenExpr(leftLoc, elts[0].E, rightLoc));
3184+
if (Context.LangOpts.hasFeature(Feature::VariadicGenerics)) {
3185+
if (elts.size() == 1 && elts[0].LabelLoc.isInvalid()) {
3186+
return makeParserResult(
3187+
status, new (Context) ParenExpr(leftLoc, elts[0].E, rightLoc));
3188+
}
3189+
} else {
3190+
if (elts.size() == 1 && elts[0].Label.empty()) {
3191+
return makeParserResult(
3192+
status, new (Context) ParenExpr(leftLoc, elts[0].E, rightLoc));
3193+
}
31873194
}
31883195

31893196
SmallVector<Expr *, 8> exprs;

lib/Sema/MiscDiagnostics.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,15 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
293293
}
294294
}
295295

296-
// Diagnose single-element tuple expressions.
297-
if (auto *tupleExpr = dyn_cast<TupleExpr>(E)) {
298-
if (tupleExpr->getNumElements() == 1) {
299-
Ctx.Diags.diagnose(tupleExpr->getElementNameLoc(0),
300-
diag::tuple_single_element)
301-
.fixItRemoveChars(tupleExpr->getElementNameLoc(0),
302-
tupleExpr->getElement(0)->getStartLoc());
296+
if (!Ctx.LangOpts.hasFeature(Feature::VariadicGenerics)) {
297+
// Diagnose single-element tuple expressions.
298+
if (auto *tupleExpr = dyn_cast<TupleExpr>(E)) {
299+
if (tupleExpr->getNumElements() == 1) {
300+
Ctx.Diags.diagnose(tupleExpr->getElementNameLoc(0),
301+
diag::tuple_single_element)
302+
.fixItRemoveChars(tupleExpr->getElementNameLoc(0),
303+
tupleExpr->getElement(0)->getStartLoc());
304+
}
303305
}
304306
}
305307

lib/Sema/PreCheckExpr.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,11 +1702,8 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
17021702

17031703
// If the tuple element has a label, propagate it.
17041704
elt.Type = eltTE->getTypeRepr();
1705-
Identifier name = TE->getElementName(EltNo);
1706-
if (!name.empty()) {
1707-
elt.Name = name;
1708-
elt.NameLoc = TE->getElementNameLoc(EltNo);
1709-
}
1705+
elt.Name = TE->getElementName(EltNo);
1706+
elt.NameLoc = TE->getElementNameLoc(EltNo);
17101707

17111708
Elts.push_back(elt);
17121709
++EltNo;

lib/Sema/TypeCheckType.cpp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4129,29 +4129,33 @@ TypeResolver::maybeResolvePackExpansionType(PackExpansionTypeRepr *repr,
41294129

41304130
NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr,
41314131
TypeResolutionOptions options) {
4132+
auto &ctx = getASTContext();
4133+
41324134
auto pair = maybeResolvePackExpansionType(repr, options);
41334135

41344136
if (pair.first->hasError())
4135-
return ErrorType::get(getASTContext());
4137+
return ErrorType::get(ctx);
41364138

41374139
// We might not allow variadic expansions here at all.
41384140
if (!options.isPackExpansionSupported()) {
41394141
diagnose(repr->getLoc(), diag::expansion_not_allowed, pair.first);
4140-
return ErrorType::get(getASTContext());
4142+
return ErrorType::get(ctx);
41414143
}
41424144

41434145
// The pattern type must contain at least one variadic generic parameter.
41444146
if (!pair.second) {
41454147
diagnose(repr->getLoc(), diag::expansion_not_variadic, pair.first)
41464148
.highlight(repr->getSourceRange());
4147-
return ErrorType::get(getASTContext());
4149+
return ErrorType::get(ctx);
41484150
}
41494151

41504152
return PackExpansionType::get(pair.first, pair.second);
41514153
}
41524154

41534155
NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
41544156
TypeResolutionOptions options) {
4157+
auto &ctx = getASTContext();
4158+
41554159
SmallVector<TupleTypeElt, 8> elements;
41564160
elements.reserve(repr->getNumElements());
41574161

@@ -4188,30 +4192,33 @@ NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
41884192
}
41894193

41904194
if (hadError)
4191-
return ErrorType::get(getASTContext());
4192-
4193-
// Single-element labeled tuples are not permitted outside of declarations
4194-
// or SIL, either.
4195-
if (elements.size() == 1 && elements[0].hasName()
4196-
&& !(options & TypeResolutionFlags::SILType)) {
4197-
diagnose(repr->getElementNameLoc(0), diag::tuple_single_element)
4198-
.fixItRemoveChars(repr->getElementNameLoc(0),
4199-
repr->getElementType(0)->getStartLoc());
4200-
4201-
elements[0] = TupleTypeElt(elements[0].getType());
4202-
}
4195+
return ErrorType::get(ctx);
42034196

42044197
// Tuples with duplicate element labels are not permitted
42054198
if (foundDupLabel) {
42064199
diagnose(repr->getLoc(), diag::tuple_duplicate_label);
42074200
}
42084201

4209-
// FIXME: One-element pack expansions should retain the tuple type
4210-
// wrapper
4211-
if (elements.size() == 1 && !elements[0].hasName())
4212-
return ParenType::get(getASTContext(), elements[0].getType());
4202+
if (ctx.LangOpts.hasFeature(Feature::VariadicGenerics)) {
4203+
if (repr->isParenType())
4204+
return ParenType::get(ctx, elements[0].getType());
4205+
} else {
4206+
// Single-element labeled tuples are not permitted outside of declarations
4207+
// or SIL, either.
4208+
if (elements.size() == 1 && elements[0].hasName()
4209+
&& !(options & TypeResolutionFlags::SILType)) {
4210+
diagnose(repr->getElementNameLoc(0), diag::tuple_single_element)
4211+
.fixItRemoveChars(repr->getElementNameLoc(0),
4212+
repr->getElementType(0)->getStartLoc());
4213+
4214+
elements[0] = TupleTypeElt(elements[0].getType());
4215+
}
4216+
4217+
if (elements.size() == 1 && !elements[0].hasName())
4218+
return ParenType::get(ctx, elements[0].getType());
4219+
}
42134220

4214-
return TupleType::get(elements, getASTContext());
4221+
return TupleType::get(elements, ctx);
42154222
}
42164223

42174224
NeverNullType
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-variadic-generics
2+
3+
let t1: (_: Int) = (_: 3)
4+
let t2: (x: Int) = (x: 3)
5+
6+
let i1: Int = t1.0
7+
let i2: Int = t2.x
8+
9+
let m1: (_: Int).Type = (_: Int).self
10+
let m2: (x: Int).Type = (x: Int).self

test/Constraints/type_sequence.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func badParameter<T>(_ : @_typeSequence T) {} // expected-error {{attribute does
2828
func directAliases() {
2929
typealias Tuple<@_typeSequence Ts> = (Ts...)
3030

31-
typealias Many<T, U, V, @_typeSequence Ws> = Tuple<T, U, V, Ws>
31+
typealias Many<T, U, V, @_typeSequence Ws> = Tuple<T, U, V, Ws... >
3232

3333
let _: Many<Int, String, Double, Void, Void, Void, Void> = 42 // expected-error {{cannot convert value of type 'Int' to specified type}}
3434
}
@@ -70,17 +70,17 @@ func invalidPacks() {
7070
}
7171

7272
func call() {
73-
func multipleParameters<@_typeSequence T>(xs: T..., ys: T...) -> (T...) { return xs }
73+
func multipleParameters<@_typeSequence T>(xs: T..., ys: T...) -> (T...) { return (_: xs) }
7474
// expected-note@-1 {{in call to function 'multipleParameters(xs:ys:)'}}
7575
_ = multipleParameters()
7676
// expected-error@-1 2 {{generic parameter 'T' could not be inferred}}
77-
let x: (String) = multipleParameters(xs: "", ys: "")
77+
let x: (_: String) = multipleParameters(xs: "", ys: "")
7878
let (one, two) = multipleParameters(xs: "", 5.0, ys: "", 5.0)
7979
multipleParameters(xs: "", 5.0, ys: 5.0, "") // expected-error {{type of expression is ambiguous without more context}}
8080

81-
func multipleSequences<@_typeSequence T, @_typeSequence U>(xs: T..., ys: U...) -> (T...) { return ys }
81+
func multipleSequences<@_typeSequence T, @_typeSequence U>(xs: T..., ys: U...) -> (T...) { return (_: ys) }
8282
// expected-note@-1 {{in call to function 'multipleSequences(xs:ys:)'}}
83-
// expected-error@-2 {{cannot convert return expression of type 'U' to return type 'T'}}
83+
// expected-error@-2 {{cannot convert return expression of type '(U...)' to return type '(T...)'}}
8484

8585
_ = multipleSequences()
8686
// expected-error@-1 {{generic parameter 'T' could not be inferred}}

0 commit comments

Comments
 (0)