mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CSFix] Use fully qualified locators for requirement failures
Would help to diagnose failures where requirement comes from contextual type, also simplifies logic around requirement fixes to some degree.
This commit is contained in:
@@ -1612,29 +1612,22 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
|
||||
if (type1->hasDependentMember() || type2->hasDependentMember())
|
||||
return nullptr;
|
||||
|
||||
auto reqPath = path.take_back(2);
|
||||
auto req = reqPath.back();
|
||||
|
||||
ConstraintLocator *reqLoc = nullptr;
|
||||
auto req = path.back();
|
||||
if (req.isConditionalRequirement()) {
|
||||
// path is - ... -> open generic -> type req # -> cond req #,
|
||||
// to identify type requirement we only need `open generic -> type req #`
|
||||
// part, because that's how fixes for type requirements are recorded.
|
||||
reqPath = path.drop_back().take_back(2);
|
||||
auto reqPath = path.drop_back();
|
||||
// If underlying conformance requirement has been fixed,
|
||||
// then there is no reason to fix up conditional requirements.
|
||||
if (cs.hasFixFor(cs.getConstraintLocator(anchor, reqPath,
|
||||
/*summaryFlags=*/0)))
|
||||
return nullptr;
|
||||
|
||||
// For conditional requirements we need a full path.
|
||||
reqLoc = cs.getConstraintLocator(anchor, path, /*summaryFlags=*/0);
|
||||
} else {
|
||||
// Build simplified locator which only contains anchor and requirement info.
|
||||
reqLoc = cs.getConstraintLocator(anchor, reqPath,
|
||||
/*summaryFlags=*/0);
|
||||
}
|
||||
|
||||
auto *reqLoc = cs.getConstraintLocator(anchor, path,
|
||||
/*summaryFlags=*/0);
|
||||
|
||||
auto reqKind = static_cast<RequirementKind>(req.getValue2());
|
||||
switch (reqKind) {
|
||||
case RequirementKind::SameType: {
|
||||
@@ -2789,32 +2782,20 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
|
||||
|
||||
if (path.back().isTypeParameterRequirement() ||
|
||||
path.back().isConditionalRequirement()) {
|
||||
ConstraintLocator *reqLoc = nullptr;
|
||||
if (path.back().isConditionalRequirement()) {
|
||||
// Drop 'conditional requirement' element remainder
|
||||
// Drop 'conditional requirement' element, remainder
|
||||
// of the path is going to point to type requirement
|
||||
// this conditional comes from.
|
||||
auto reqPath = ArrayRef<LocatorPathElt>(path).drop_back();
|
||||
// Underlying conformance requirement is itself fixed,
|
||||
// this wouldn't lead to a right solution.
|
||||
if (hasFixFor(getConstraintLocator(anchor, reqPath.take_back(2),
|
||||
if (hasFixFor(getConstraintLocator(anchor, reqPath,
|
||||
/*summaryFlags=*/0)))
|
||||
return SolutionKind::Error;
|
||||
|
||||
// For conditional requirements we need complete path, which includes
|
||||
// type requirement position, to be able to fetch conformance later.
|
||||
reqLoc = getConstraintLocator(locator);
|
||||
} else {
|
||||
// Let's strip all of the unnecessary information from locator,
|
||||
// diagnostics only care about anchor - to lookup type,
|
||||
// generic signature where requirement comes from, and
|
||||
// what was the requirement# which is not satisfied.
|
||||
auto reqPath = ArrayRef<LocatorPathElt>(path).take_back(2);
|
||||
reqLoc = getConstraintLocator(anchor, reqPath,
|
||||
/*summaryFlags=*/0);
|
||||
}
|
||||
|
||||
auto *fix = MissingConformance::create(*this, type, protocol, reqLoc);
|
||||
auto *fix = MissingConformance::create(*this, type, protocol,
|
||||
getConstraintLocator(locator));
|
||||
if (!recordFix(fix))
|
||||
return SolutionKind::Solved;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user