Skip to content

Commit 86e6331

Browse files
authored
Merge pull request #60895 from LucianoPAlmeida/fix-magic-literal
[Sema] Fix dictionary duplicate keys false positives for #line and #column magic literal
2 parents 40f2f1b + 568b949 commit 86e6331

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,15 +5058,46 @@ diagnoseDictionaryLiteralDuplicateKeyEntries(const Expr *E,
50585058

50595059
private:
50605060
std::string getKeyStringValue(const LiteralExpr *keyExpr) {
5061-
if (isa<MagicIdentifierLiteralExpr>(keyExpr)) {
5062-
return keyExpr->getLiteralKindDescription().str();
5061+
if (auto *MLE = dyn_cast<MagicIdentifierLiteralExpr>(keyExpr)) {
5062+
return getMagicLiteralKeyValue(MLE);
50635063
}
50645064
std::string out;
50655065
llvm::raw_string_ostream OS(out);
50665066
keyExpr->printConstExprValue(&OS, /*additionalCheck=*/nullptr);
50675067
return out;
50685068
}
50695069

5070+
std::string getMagicLiteralKeyValue(const MagicIdentifierLiteralExpr *MLE) {
5071+
auto magicLiteralValue = MLE->getLiteralKindDescription().str();
5072+
switch (MLE->getKind()) {
5073+
case MagicIdentifierLiteralExpr::DSOHandle:
5074+
case MagicIdentifierLiteralExpr::FileID:
5075+
case MagicIdentifierLiteralExpr::FileIDSpelledAsFile:
5076+
case MagicIdentifierLiteralExpr::FilePath:
5077+
case MagicIdentifierLiteralExpr::FilePathSpelledAsFile:
5078+
case MagicIdentifierLiteralExpr::Function:
5079+
break;
5080+
// Those are literals that can evaluate to different values in a
5081+
// dictionary literal declaration context based on source position
5082+
// so we need to consider that position as part of the literal value.
5083+
case MagicIdentifierLiteralExpr::Column: {
5084+
unsigned int column;
5085+
std::tie(std::ignore, column) =
5086+
Ctx.SourceMgr.getPresumedLineAndColumnForLoc(MLE->getStartLoc());
5087+
magicLiteralValue += ":" + std::to_string(column);
5088+
break;
5089+
}
5090+
case MagicIdentifierLiteralExpr::Line: {
5091+
unsigned int line;
5092+
std::tie(line, std::ignore) =
5093+
Ctx.SourceMgr.getPresumedLineAndColumnForLoc(MLE->getStartLoc());
5094+
magicLiteralValue += ":" + std::to_string(line);
5095+
break;
5096+
}
5097+
}
5098+
return magicLiteralValue;
5099+
}
5100+
50705101
std::string getKeyStringValueForDiagnostic(const LiteralExpr *keyExpr) {
50715102
std::string out;
50725103
switch (keyExpr->getKind()) {

test/Sema/diag_dictionary_keys_duplicated.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,21 @@ let _: [String: String] = [
209209
"\(a)": "B",
210210
"\(1)": "C"
211211
]
212+
213+
// https://github.com/apple/swift/issues/60873
214+
let _: [Int: String] = [
215+
#line: "A",
216+
#line: "B"
217+
]
218+
219+
let _: [Int: String] = [#line: "A", #line: "B"] // expected-warning{{dictionary literal of type '[Int : String]' has duplicate entries for #line literal key}}
220+
// expected-note@-1{{duplicate key declared here}} {{25-35=}} {{35-36=}}
221+
// expected-note@-2{{duplicate key declared here}} {{37-47=}} {{35-36=}}
222+
223+
let _: [Int: String] = [#column: "A", #column: "B"] // OK
224+
225+
let _: [Int: String] = [
226+
// expected-note@+1{{duplicate key declared here}} {{3-15=}} {{15-16=}}
227+
#column: "A", // expected-warning{{dictionary literal of type '[Int : String]' has duplicate entries for #column literal key}}
228+
#column: "B" // expected-note{{duplicate key declared here}} {{3-16=}} {{227:15-16=}}
229+
]

0 commit comments

Comments
 (0)