mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Simplify representation of vararg forwarding
VarargExpansionExpr shows up in call argument lists in synthesized initializers and modify accessors when we need to forward arguments to a call taking varargs. Previously we would say that the type of VarargExpansionExpr is $T when its subexpression type is [$T]. matchCallArguments() would then 'collect' the single VarargExpansionExpr into a variadic argument list with a single element, and build an ArgumentShuffleExpr for the argument list. In turn, SILGen would peephole vararg emission of a variadic argument list with a single entry that happens to be a VarargExpansionExpr, by returning the subexpression's value, which happened to be an array of the right element type, instead of building a new array containing the elements of the variadic argument list. This was all too complicated. Instead, let's say that the type of a VarargExpansionExpr is [$T], except that when it appears in a TupleExpr, the variadic bit of the corresponding element is set. Then, matchCallArguments() needs to support a case where both the parameter and argument list have a matching vararg element. In this case, instead of collecting multiple arguments into a single variadic argument list, we treat the variadic argument like an ordinary parameter, bypassing construction of the ArgumentShuffleExpr altogether. Finally, SILGen now needs to be able to emit a VarargExpansionExpr in ordinary rvalue position, since it now appears as a child of a TupleExpr; it can do this by simply emitting the sub-expression to produce an array value.
This commit is contained in:
@@ -457,7 +457,8 @@ static Expr *buildArgumentForwardingExpr(ArrayRef<ParamDecl*> params,
|
||||
}
|
||||
|
||||
// A single unlabeled value is not a tuple.
|
||||
if (args.size() == 1 && labels[0].empty()) {
|
||||
if (args.size() == 1 && labels[0].empty() &&
|
||||
!isa<VarargExpansionExpr>(args[0])) {
|
||||
return new (ctx) ParenExpr(SourceLoc(), args[0], SourceLoc(),
|
||||
/*hasTrailingClosure=*/false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user