mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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>.
51 lines
1.3 KiB
Swift
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)
|