Files
swift-mirror/test/SILGen/argument_shuffle.swift
Slava Pestov 9f8ccd41f3 SILGen: Fix for tuple conversions in function argument position
Swift admits implicit conversions between tuple types to
introduce and eliminate argument labels, and re-order
argument labels. These are expressed as TupleShuffleExpr
in the AST.

SILGen has two different code paths for lowering TupleShuffleExpr,
which is also used for varargs and default arguments in call
argument emission.

These two code paths support different subsets of TupleShuffleExpr;
neither one supports the full generality of the other, but there
is some overlap.

Work around the damage by routing the two different "kinds" of
TupleShuffleExprs to the correct place in argument emission.

The next incremental step here would be to refactor ArgEmitter to
make it usable when lowering SubscriptExpr; then the RValueEmitter's
support for varargs in TupleShuffleExpr can go away. Once that's
done we can split off an ArgumentExpr from TupleShuffleExpr, and
in the fullness of time, fold ArgumentExpr into ApplyExpr.

At that point this dark corner of the AST will start to be sane...

Fixes <https://bugs.swift.org/browse/SR-2887>.
2017-01-03 19:05:40 -08:00

51 lines
1.3 KiB
Swift

// RUN: %target-swift-frontend -emit-silgen %s
struct Horse<T> {
func walk(_: (String, Int), reverse: Bool) {}
func trot(_: (x: String, y: Int), halfhalt: Bool) {}
func canter(_: T, counter: Bool) {}
}
var kevin = Horse<(x: String, y: Int)>()
var loki = Horse<(String, Int)>()
//
// No conversion
let noLabelsTuple = ("x", 1)
kevin.walk(("x", 1), reverse: false)
kevin.walk(noLabelsTuple, reverse: false)
loki.canter(("x", 1), counter: false)
loki.canter(noLabelsTuple, counter: false)
// Introducing labels
kevin.trot(("x", 1), halfhalt: false)
kevin.trot(noLabelsTuple, halfhalt: false)
kevin.canter(("x", 1), counter: false)
kevin.canter(noLabelsTuple, counter: false)
// Eliminating labels
let labelsTuple = (x: "x", y: 1)
kevin.walk((x: "x", y: 1), reverse: false)
kevin.walk(labelsTuple, reverse: false)
loki.canter((x: "x", y: 1), counter: false)
loki.canter(labelsTuple, counter: false)
// No conversion
kevin.trot((x: "x", y: 1), halfhalt: false)
kevin.trot(labelsTuple, halfhalt: false)
kevin.canter((x: "x", y: 1), counter: false)
kevin.canter(labelsTuple, counter: false)
// Shuffling labels
let shuffledLabelsTuple = (y: 1, x: "x")
kevin.trot((y: 1, x: "x"), halfhalt: false)
kevin.trot(shuffledLabelsTuple, halfhalt: false)
kevin.canter((y: 1, x: "x"), counter: false)
kevin.canter(shuffledLabelsTuple, counter: false)