Skip to content

Commit 7937406

Browse files
authored
Merge pull request #17210 from mdiep/SR-7177
2 parents b577296 + 87aaf10 commit 7937406

File tree

5 files changed

+79
-13
lines changed

5 files changed

+79
-13
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,9 +1429,6 @@ NOTE(type_does_not_inherit_or_conform_requirement,none,
14291429
ERROR(types_not_equal,none,
14301430
"%0 requires the types %1 and %2 be equivalent",
14311431
(Type, Type, Type))
1432-
ERROR(types_not_equal_in_call,none,
1433-
"%0 requires the types %1 and %2 be equivalent to use %3",
1434-
(Type, Type, Type, DeclName))
14351432
ERROR(type_does_not_conform_owner,none,
14361433
"%0 requires that %1 conform to %2", (Type, Type, Type))
14371434
NOTE(requirement_implied_by_conditional_conformance,none,

lib/Sema/CSDiag.cpp

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,77 @@ bool FailureDiagnosis::diagnoseConversionToBool(Expr *expr, Type exprType) {
17041704
return false;
17051705
}
17061706

1707+
static bool
1708+
diagnoseUnresolvedDotExprTypeRequirementFailure(ConstraintSystem &cs,
1709+
Constraint *constraint) {
1710+
auto &TC = cs.TC;
1711+
1712+
auto *locator = constraint->getLocator();
1713+
if (!locator)
1714+
return false;
1715+
1716+
auto path = locator->getPath();
1717+
if (path.empty())
1718+
return false;
1719+
1720+
auto &last = path.back();
1721+
if (last.getKind() != ConstraintLocator::TypeParameterRequirement)
1722+
return false;
1723+
1724+
auto *anchor = locator->getAnchor();
1725+
if (!anchor)
1726+
return false;
1727+
1728+
auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor);
1729+
if (!UDE)
1730+
return false;
1731+
1732+
auto ownerType = cs.getType(UDE->getBase());
1733+
if (!ownerType)
1734+
return false;
1735+
1736+
ownerType = cs.simplifyType(ownerType)->getWithoutSpecifierType();
1737+
if (ownerType->hasTypeVariable() || ownerType->hasUnresolvedType())
1738+
return false;
1739+
1740+
// If we actually resolved the member to use, use it.
1741+
auto loc = cs.getConstraintLocator(UDE, ConstraintLocator::Member);
1742+
auto *member = cs.findResolvedMemberRef(loc);
1743+
if (!member)
1744+
return false;
1745+
1746+
auto req = member->getAsGenericContext()
1747+
->getGenericSignature()
1748+
->getRequirements()[last.getValue()];
1749+
1750+
Diag<Type, Type, Type, Type, StringRef> note;
1751+
switch (req.getKind()) {
1752+
case RequirementKind::Conformance:
1753+
case RequirementKind::Layout:
1754+
return false;
1755+
1756+
case RequirementKind::Superclass:
1757+
note = diag::candidate_types_inheritance_requirement;
1758+
break;
1759+
1760+
case RequirementKind::SameType:
1761+
note = diag::candidate_types_equal_requirement;
1762+
break;
1763+
}
1764+
1765+
TC.diagnose(UDE->getLoc(), diag::could_not_find_value_member, ownerType,
1766+
UDE->getName());
1767+
1768+
auto first = cs.simplifyType(constraint->getFirstType());
1769+
auto second = cs.simplifyType(constraint->getSecondType());
1770+
auto rawFirstType = req.getFirstType();
1771+
auto rawSecondType = req.getSecondType();
1772+
1773+
TC.diagnose(member, note, first, second, rawFirstType, rawSecondType, "");
1774+
1775+
return true;
1776+
}
1777+
17071778
/// Diagnose problems related to failures in constraints
17081779
/// generated by `openGeneric` which represent different
17091780
/// kinds of type parameter requirements.
@@ -1741,6 +1812,9 @@ static bool diagnoseTypeRequirementFailure(ConstraintSystem &cs,
17411812
if (ownerType->hasTypeVariable() || ownerType->hasUnresolvedType())
17421813
return false;
17431814

1815+
if (diagnoseUnresolvedDotExprTypeRequirementFailure(cs, constraint))
1816+
return true;
1817+
17441818
auto lhs = cs.simplifyType(constraint->getFirstType());
17451819
auto rhs = cs.simplifyType(constraint->getSecondType());
17461820

@@ -1756,12 +1830,7 @@ static bool diagnoseTypeRequirementFailure(ConstraintSystem &cs,
17561830
return true;
17571831

17581832
case ConstraintKind::Equal: { // same type
1759-
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor)) {
1760-
TC.diagnose(UDE->getLoc(), diag::types_not_equal_in_call, ownerType, lhs,
1761-
rhs, UDE->getName());
1762-
} else {
1763-
TC.diagnose(anchor->getLoc(), diag::types_not_equal, ownerType, lhs, rhs);
1764-
}
1833+
TC.diagnose(anchor->getLoc(), diag::types_not_equal, ownerType, lhs, rhs);
17651834
return true;
17661835
}
17671836

test/Constraints/generics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ do {
559559
}
560560

561561
func rdar35890334(_ arr: inout [Int]) {
562-
_ = arr.popFirst() // expected-error {{'[Int]' requires the types '[Int]' and 'ArraySlice<Int>' be equivalent to use 'popFirst'}}
562+
_ = arr.popFirst() // expected-error {{value of type '[Int]' has no member 'popFirst'}}
563563
}
564564

565565
// rdar://problem/39616039

test/decl/ext/protocol.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ struct S4d : P4 {
207207
}
208208

209209
extension P4 where Self.AssocP4 == Int {
210-
func extP4Int() { }
210+
func extP4Int() { } // expected-note {{candidate requires that the types 'Bool' and 'Int' be equivalent (requirement specified as 'Self.AssocP4' == 'Int')}}
211211
}
212212

213213
extension P4 where Self.AssocP4 == Bool {
@@ -221,7 +221,7 @@ func testP4(_ s4a: S4a, s4b: S4b, s4c: S4c, s4d: S4d) {
221221
s4c.extP4Int() // okay
222222
var b1 = s4d.extP4a() // okay, "Bool" version
223223
b1 = true // checks type above
224-
s4d.extP4Int() // expected-error{{'S4d' requires the types 'Bool' and 'Int' be equivalent to use 'extP4Int'}}
224+
s4d.extP4Int() // expected-error{{value of type 'S4d' has no member 'extP4Int'}}
225225
_ = b1
226226
}
227227

test/decl/protocol/protocols.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ struct WrongIsEqual : IsEqualComparable { // expected-error{{type 'WrongIsEqual'
266266
//===----------------------------------------------------------------------===//
267267

268268
func existentialSequence(_ e: Sequence) { // expected-error{{has Self or associated type requirements}}
269-
var x = e.makeIterator() // expected-error{{'Sequence' requires the types 'Sequence' and 'Sequence.Iterator' be equivalent to use 'makeIterator'}}
269+
var x = e.makeIterator() // expected-error{{value of type 'Sequence' has no member 'makeIterator'}}
270270
x.next()
271271
x.nonexistent()
272272
}

0 commit comments

Comments
 (0)