[Diag] Reword the tuple shuffle diagnostic

"reorder" seems a bit less jargony than "shuffle", and include the 
labels that are being reordered.
This commit is contained in:
Hamish Knight
2025-10-29 15:14:23 +00:00
parent 6510eb024a
commit 24347812f5
9 changed files with 42 additions and 21 deletions

View File

@@ -7833,9 +7833,9 @@ ERROR(result_builder_buildpartialblock_accumulated_not_accessible,none,
// MARK: Tuple Shuffle Diagnostics
//------------------------------------------------------------------------------
WARNING(warn_reordering_tuple_shuffle_deprecated,Deprecation,
"expression shuffles the elements of this tuple; "
"this behavior is deprecated", ())
WARNING(warn_reordering_tuple_shuffle_deprecated,Deprecation,
"implicit reordering of tuple elements from '%0' to '%1' is deprecated",
(StringRef, StringRef))
//------------------------------------------------------------------------------
// MARK: Implicit conversion diagnostics

View File

@@ -5818,6 +5818,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
// Convert each OpaqueValueExpr to the correct type.
SmallVector<Expr *, 4> converted;
SmallVector<Identifier, 4> origLabels;
SmallVector<Identifier, 4> labels;
SmallVector<TupleTypeElt, 4> convertedElts;
@@ -5825,6 +5826,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
for (unsigned i = 0, e = sources.size(); i != e; ++i) {
unsigned source = sources[i];
auto *fromElt = destructured[source];
auto fromLabel = fromTuple->getElement(i).getName();
// Actually convert the source element.
auto toEltType = toTuple->getElementType(i);
@@ -5832,8 +5834,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
// If we're shuffling positions and labels, we have to warn about this
// conversion.
if (i != sources[i] &&
fromTuple->getElement(i).getName() != toLabel)
if (i != sources[i] && fromLabel != toLabel)
anythingShuffled = true;
auto *toElt
@@ -5845,6 +5846,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
converted.push_back(toElt);
labels.push_back(toLabel);
origLabels.push_back(fromLabel);
convertedElts.emplace_back(toEltType, toLabel);
}
@@ -5852,8 +5854,22 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr,
// will form the shuffle for now, but a future compiler should decline to
// do so and begin the process of removing them altogether.
if (anythingShuffled) {
ctx.Diags.diagnose(
expr->getLoc(), diag::warn_reordering_tuple_shuffle_deprecated);
auto concatLabels = [](SmallVectorImpl<Identifier> &labels,
SmallVectorImpl<char> &out) {
llvm::raw_svector_ostream OS(out);
for (auto label : labels) {
DeclName(label).print(OS, /*skipEmpty*/ false, /*escapeIfNeeded*/ true);
OS << ':';
}
};
SmallString<16> fromLabelStr;
concatLabels(origLabels, fromLabelStr);
SmallString<16> toLabelStr;
concatLabels(labels, toLabelStr);
ctx.Diags.diagnose(expr->getLoc(),
diag::warn_reordering_tuple_shuffle_deprecated,
fromLabelStr, toLabelStr);
}
// Create the result tuple, written in terms of the destructured

View File

@@ -5,27 +5,32 @@ func consume<T>(_ x: T) {} // Suppress unused variable warnings
func shuffle_through_initialization() {
let a = (x: 1, y: 2)
let b: (y: Int, x: Int)
b = a // expected-warning {{expression shuffles the elements of this tuple}}
b = a // expected-warning {{implicit reordering of tuple elements from 'x:y:' to 'y:x:' is deprecated}}
consume(b)
}
func shuffle_raw_label(_ t: (`a b`: Int, `c d`: Int)) {
let _: (`c d`: Int, `a b`: Int) = t
// expected-warning@-1 {{implicit reordering of tuple elements from '`a b`:`c d`:' to '`c d`:`a b`:' is deprecated}}
}
func shuffle_through_destructuring() {
let a = (x: 1, y: 2)
let (y: b, x: c) = a // expected-warning {{expression shuffles the elements of this tuple}}
let (y: b, x: c) = a // expected-warning {{implicit reordering of tuple elements from 'x:y:' to 'y:x:' is deprecated}}
consume((b, c))
}
func shuffle_through_call() {
func foo(_ : (x: Int, y: Int)) {}
foo((y: 5, x: 10)) // expected-warning {{expression shuffles the elements of this tuple}}
foo((y: 5, x: 10)) // expected-warning {{implicit reordering of tuple elements from 'y:x:' to 'x:y:' is deprecated}}
}
func shuffle_through_cast() {
let x = ((a: Int(), b: Int()) as (b: Int, a: Int)).0 // expected-warning {{expression shuffles the elements of this tuple}}
let x = ((a: Int(), b: Int()) as (b: Int, a: Int)).0 // expected-warning {{implicit reordering of tuple elements from 'a:b:' to 'b:a:' is deprecated}}
// Ah, the famous double-shuffle
let (c1, (c2, c3)): (c: Int, (b: Int, a: Int)) = ((a: Int(), b: Int()), c: Int())
// expected-warning@-1 {{expression shuffles the elements of this tuple}}
// expected-warning@-2 {{expression shuffles the elements of this tuple}}
// expected-warning@-1 {{implicit reordering of tuple elements from 'a:b:' to 'b:a:' is deprecated}}
// expected-warning@-2 {{implicit reordering of tuple elements from '_:c:' to 'c:_:' is deprecated}}
consume((x, c1, c2, c3))
}

View File

@@ -474,7 +474,7 @@ func ff_implicitInjectIntoOptionalExpr(_ int: Int) -> Int? {
}
func ff_implicitTupleShuffle(_ input: (one: Int, two: Int)) -> (two: Int, one: Int) {
input // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}}
input // expected-warning {{implicit reordering of tuple elements from 'one:two:' to 'two:one:' is deprecated}}
}
func ff_implicitCollectionUpcast(_ derived: [Derived]) -> [Base] {

View File

@@ -676,7 +676,7 @@ func ff_implicitInjectIntoOptionalExpr(_ int: Int) -> Int? {
func ff_implicitTupleShuffle(_ input: (one: Int, two: Int)) -> (two: Int, one: Int) {
#if true
input // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}}
input // expected-warning {{implicit reordering of tuple elements from 'one:two:' to 'two:one:' is deprecated}}
#endif
}

View File

@@ -452,10 +452,10 @@ func testGenericWeakClassDiag() {
// The diagnostic doesn't currently support tuple shuffles.
func testDontDiagnoseThroughTupleShuffles() {
unowned let (c1, (c2, c3)): (c: C, (b: C, a: C)) = ((a: D(), b: C()), c: D())
// expected-warning@-1 {{expression shuffles the elements of this tuple; this behavior is deprecated}}
// expected-warning@-2 {{expression shuffles the elements of this tuple; this behavior is deprecated}}
// expected-warning@-1 {{implicit reordering of tuple elements from 'a:b:' to 'b:a:' is deprecated}}
// expected-warning@-2 {{implicit reordering of tuple elements from '_:c:' to 'c:_:' is deprecated}}
unowned let c4 = ((a: C(), b: C()) as (b: C, a: C)).0
// expected-warning@-1 {{expression shuffles the elements of this tuple; this behavior is deprecated}}
// expected-warning@-1 {{implicit reordering of tuple elements from 'a:b:' to 'b:a:' is deprecated}}
_ = c1; _ = c2; _ = c3; _ = c4
}

View File

@@ -155,7 +155,7 @@ var f2 : (Int) -> Int = (+-+)
var f3 : (inout Int) -> Int = (-+-) // expected-error{{ambiguous use of operator '-+-'}}
var f4 : (inout Int, Int) -> Int = (+-+=)
var r5 : (a : (Int, Int) -> Int, b : (Int, Int) -> Int) = (+, -)
var r6 : (a : (Int, Int) -> Int, b : (Int, Int) -> Int) = (b : +, a : -) // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}}
var r6 : (a : (Int, Int) -> Int, b : (Int, Int) -> Int) = (b : +, a : -) // expected-warning {{implicit reordering of tuple elements from 'b:a:' to 'a:b:' is deprecated}}
struct f6_S {
subscript(op : (Int, Int) -> Int) -> Int {

View File

@@ -56,7 +56,7 @@ func funcdecl5(_ a: Int, _ y: Int) {
var b = a.1+a.f
// Tuple expressions with named elements.
var i : (y : Int, x : Int) = (x : 42, y : 11) // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}}
var i : (y : Int, x : Int) = (x : 42, y : 11) // expected-warning {{implicit reordering of tuple elements from 'x:y:' to 'y:x:' is deprecated}}
funcdecl1(123, 444)
// Calls.

View File

@@ -194,7 +194,7 @@ func test5() {
let c: (a: Int, b: Int) = (1,2)
let _: (b: Int, a: Int) = c // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}}
let _: (b: Int, a: Int) = c // expected-warning {{implicit reordering of tuple elements from 'a:b:' to 'b:a:' is deprecated}}
}