Skip to content

Commit 2164476

Browse files
committed
[Diagnostics] Port diagnostics related to dictionary literal use
1 parent f2942eb commit 2164476

File tree

3 files changed

+17
-66
lines changed

3 files changed

+17
-66
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
239239
bool visitTryExpr(TryExpr *E);
240240

241241
bool visitUnresolvedDotExpr(UnresolvedDotExpr *UDE);
242-
bool visitDictionaryExpr(DictionaryExpr *E);
243242
bool visitObjectLiteralExpr(ObjectLiteralExpr *E);
244243

245244
bool visitApplyExpr(ApplyExpr *AE);
@@ -1723,71 +1722,6 @@ visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E) {
17231722
return false;
17241723
}
17251724

1726-
bool FailureDiagnosis::visitDictionaryExpr(DictionaryExpr *E) {
1727-
Type contextualKeyType, contextualValueType;
1728-
auto keyTypePurpose = CTP_Unused, valueTypePurpose = CTP_Unused;
1729-
1730-
// If we had a contextual type, then it either conforms to
1731-
// ExpressibleByDictionaryLiteral or it is an invalid contextual type.
1732-
if (auto contextualType = CS.getContextualType()) {
1733-
// If our contextual type is an optional, look through them, because we're
1734-
// surely initializing whatever is inside.
1735-
contextualType = contextualType->lookThroughAllOptionalTypes();
1736-
1737-
auto DLC = TypeChecker::getProtocol(
1738-
CS.getASTContext(), E->getLoc(),
1739-
KnownProtocolKind::ExpressibleByDictionaryLiteral);
1740-
if (!DLC) return visitExpr(E);
1741-
1742-
// Validate the contextual type conforms to ExpressibleByDictionaryLiteral
1743-
// and figure out what the contextual Key/Value types are in place.
1744-
auto Conformance = TypeChecker::conformsToProtocol(
1745-
contextualType, DLC, CS.DC, ConformanceCheckFlags::InExpression);
1746-
if (Conformance.isInvalid()) {
1747-
diagnose(E->getStartLoc(), diag::type_is_not_dictionary, contextualType)
1748-
.highlight(E->getSourceRange());
1749-
return true;
1750-
}
1751-
1752-
contextualKeyType =
1753-
Conformance
1754-
.getTypeWitnessByName(contextualType, CS.getASTContext().Id_Key)
1755-
->getDesugaredType();
1756-
1757-
contextualValueType =
1758-
Conformance
1759-
.getTypeWitnessByName(contextualType, CS.getASTContext().Id_Value)
1760-
->getDesugaredType();
1761-
1762-
assert(contextualKeyType && contextualValueType &&
1763-
"Could not find Key/Value DictionaryLiteral associated types from"
1764-
" contextual type conformance");
1765-
1766-
keyTypePurpose = CTP_DictionaryKey;
1767-
valueTypePurpose = CTP_DictionaryValue;
1768-
}
1769-
1770-
// Type check each of the subexpressions in place, passing down the contextual
1771-
// type information if we have it.
1772-
for (auto elt : E->getElements()) {
1773-
auto TE = dyn_cast<TupleExpr>(elt);
1774-
if (!TE || TE->getNumElements() != 2) continue;
1775-
1776-
if (!typeCheckChildIndependently(TE->getElement(0),
1777-
contextualKeyType, keyTypePurpose))
1778-
return true;
1779-
if (!typeCheckChildIndependently(TE->getElement(1),
1780-
contextualValueType, valueTypePurpose))
1781-
return true;
1782-
}
1783-
1784-
// If that didn't turn up an issue, then we don't know what to do.
1785-
// TODO: When a contextual type is missing, we could try to diagnose cases
1786-
// where the element types mismatch. There is no Any equivalent since they
1787-
// keys need to be hashable.
1788-
return false;
1789-
}
1790-
17911725
/// When an object literal fails to typecheck because its protocol's
17921726
/// corresponding default type has not been set in the global namespace (e.g.
17931727
/// _ColorLiteralType), suggest that the user import the appropriate module for

lib/Sema/CSDiagnostics.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,12 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
673673
case ConstraintLocator::TupleElement: {
674674
if (auto *array = dyn_cast<ArrayExpr>(getRawAnchor()))
675675
diagnostic = getDiagnosticFor(CTP_ArrayElement);
676+
677+
if (auto *dict = dyn_cast<DictionaryExpr>(getRawAnchor())) {
678+
auto eltLoc = last.castTo<LocatorPathElt::TupleElement>();
679+
diagnostic = getDiagnosticFor(
680+
eltLoc.getIndex() == 0 ? CTP_DictionaryKey : CTP_DictionaryValue);
681+
}
676682
break;
677683
}
678684

test/Constraints/generics.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,3 +835,14 @@ func sr_11491(_ value: [String]) {
835835
arr.insert(value)
836836
// expected-error@-1 {{cannot convert value of type '[String]' to expected argument type 'String'}}
837837
}
838+
839+
func test_dictionary_with_generic_mismatch_in_key_or_value() {
840+
struct S<T> : Hashable {}
841+
// expected-note@-1 2 {{arguments to generic parameter 'T' ('Int' and 'Bool') are expected to be equal}}
842+
843+
let _: [Int: S<Bool>] = [0: S<Bool>(), 1: S<Int>()]
844+
// expected-error@-1 {{cannot convert value of type 'S<Int>' to expected dictionary value type 'S<Bool>'}}
845+
846+
let _: [S<Bool>: Int] = [S<Int>(): 42]
847+
// expected-error@-1 {{cannot convert value of type 'S<Int>' to expected dictionary key type 'S<Bool>'}}
848+
}

0 commit comments

Comments
 (0)