Skip to content

Commit 568b949

Browse files
[Sema] Fix dictionary duplicate keys false positives for #line and #column magic literal
1 parent b1a939f commit 568b949

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
@@ -5038,15 +5038,46 @@ diagnoseDictionaryLiteralDuplicateKeyEntries(const Expr *E,
50385038

50395039
private:
50405040
std::string getKeyStringValue(const LiteralExpr *keyExpr) {
5041-
if (isa<MagicIdentifierLiteralExpr>(keyExpr)) {
5042-
return keyExpr->getLiteralKindDescription().str();
5041+
if (auto *MLE = dyn_cast<MagicIdentifierLiteralExpr>(keyExpr)) {
5042+
return getMagicLiteralKeyValue(MLE);
50435043
}
50445044
std::string out;
50455045
llvm::raw_string_ostream OS(out);
50465046
keyExpr->printConstExprValue(&OS, /*additionalCheck=*/nullptr);
50475047
return out;
50485048
}
50495049

5050+
std::string getMagicLiteralKeyValue(const MagicIdentifierLiteralExpr *MLE) {
5051+
auto magicLiteralValue = MLE->getLiteralKindDescription().str();
5052+
switch (MLE->getKind()) {
5053+
case MagicIdentifierLiteralExpr::DSOHandle:
5054+
case MagicIdentifierLiteralExpr::FileID:
5055+
case MagicIdentifierLiteralExpr::FileIDSpelledAsFile:
5056+
case MagicIdentifierLiteralExpr::FilePath:
5057+
case MagicIdentifierLiteralExpr::FilePathSpelledAsFile:
5058+
case MagicIdentifierLiteralExpr::Function:
5059+
break;
5060+
// Those are literals that can evaluate to different values in a
5061+
// dictionary literal declaration context based on source position
5062+
// so we need to consider that position as part of the literal value.
5063+
case MagicIdentifierLiteralExpr::Column: {
5064+
unsigned int column;
5065+
std::tie(std::ignore, column) =
5066+
Ctx.SourceMgr.getPresumedLineAndColumnForLoc(MLE->getStartLoc());
5067+
magicLiteralValue += ":" + std::to_string(column);
5068+
break;
5069+
}
5070+
case MagicIdentifierLiteralExpr::Line: {
5071+
unsigned int line;
5072+
std::tie(line, std::ignore) =
5073+
Ctx.SourceMgr.getPresumedLineAndColumnForLoc(MLE->getStartLoc());
5074+
magicLiteralValue += ":" + std::to_string(line);
5075+
break;
5076+
}
5077+
}
5078+
return magicLiteralValue;
5079+
}
5080+
50505081
std::string getKeyStringValueForDiagnostic(const LiteralExpr *keyExpr) {
50515082
std::string out;
50525083
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)