Merge pull request #66513 from xedin/init-accessor-diagnostics

[Sema/SIL] Improve diagnostics related to init accessors
This commit is contained in:
Pavel Yaskevich
2023-06-14 09:57:08 -07:00
committed by GitHub
17 changed files with 738 additions and 49 deletions

View File

@@ -9635,6 +9635,44 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
}
}
if (auto *UDE =
getAsExpr<UnresolvedDotExpr>(memberLocator->getAnchor())) {
auto *base = UDE->getBase();
if (auto *accessor = DC->getInnermostPropertyAccessorContext()) {
if (accessor->isInitAccessor() && isa<DeclRefExpr>(base) &&
accessor->getImplicitSelfDecl() ==
cast<DeclRefExpr>(base)->getDecl()) {
bool isValidReference = false;
// If name doesn't appear in either `initializes` or `accesses`
// then it's invalid instance member.
if (auto *initializesAttr =
accessor->getAttrs().getAttribute<InitializesAttr>()) {
isValidReference |= llvm::any_of(
initializesAttr->getProperties(), [&](Identifier name) {
return DeclNameRef(name) == memberName;
});
}
if (auto *accessesAttr =
accessor->getAttrs().getAttribute<AccessesAttr>()) {
isValidReference |= llvm::any_of(
accessesAttr->getProperties(), [&](Identifier name) {
return DeclNameRef(name) == memberName;
});
}
if (!isValidReference) {
result.addUnviable(
candidate,
MemberLookupResult::UR_UnavailableWithinInitAccessor);
return;
}
}
}
}
// If the underlying type of a typealias is fully concrete, it is legal
// to access the type with a protocol metatype base.
} else if (instanceTy->isExistentialType() &&
@@ -10215,6 +10253,10 @@ fixMemberRef(ConstraintSystem &cs, Type baseTy,
case MemberLookupResult::UR_InvalidStaticMemberOnProtocolMetatype:
return AllowInvalidStaticMemberRefOnProtocolMetatype::create(cs, locator);
case MemberLookupResult::UR_UnavailableWithinInitAccessor:
return AllowInvalidMemberReferenceInInitAccessor::create(cs, memberName,
locator);
}
}
@@ -14640,6 +14682,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
return recordFix(fix, 100) ? SolutionKind::Error : SolutionKind::Solved;
}
case FixKind::AllowInvalidMemberReferenceInInitAccessor: {
return recordFix(fix, 5) ? SolutionKind::Error : SolutionKind::Solved;
}
case FixKind::ExplicitlyConstructRawRepresentable: {
// Let's increase impact of this fix for binary operators because
// it's possible to get both `.rawValue` and construction fixes for