Merge pull request #39492 from AnthonyLatsis/se-309-2

SE-309: Covariant erasure for dependent member types
This commit is contained in:
Anthony Latsis
2022-02-02 07:07:17 +03:00
committed by GitHub
37 changed files with 2538 additions and 956 deletions

View File

@@ -359,8 +359,25 @@ bool RequirementFailure::diagnoseAsError() {
const auto *reqDC = getRequirementDC();
auto *genericCtx = getGenericContext();
auto lhs = getLHS();
auto rhs = getRHS();
// Instead of printing archetypes rooted on an opened existential, which
// are currently an implementation detail, have a weird textual
// representation, and may be misleading (a root opened archetype prints like
// an existential type), use the corresponding 'Self'-rooted interface types
// from the requirement, which are more familiar.
const auto lhs = [&] {
if (getLHS()->hasOpenedExistential()) {
return getRequirement().getFirstType();
}
return getLHS();
}();
const auto rhs = [&] {
if (getRHS()->hasOpenedExistential()) {
return getRequirement().getSecondType();
}
return getRHS();
}();
if (auto *OTD = dyn_cast<OpaqueTypeDecl>(AffectedDecl)) {
auto *namingDecl = OTD->getNamingDecl();
@@ -387,7 +404,8 @@ bool RequirementFailure::diagnoseAsError() {
AffectedDecl->getName(), lhs, rhs);
}
emitRequirementNote(reqDC->getAsDecl(), lhs, rhs);
maybeEmitRequirementNote(reqDC->getAsDecl(), lhs, rhs);
return true;
}
@@ -406,8 +424,8 @@ bool RequirementFailure::diagnoseAsNote() {
return true;
}
void RequirementFailure::emitRequirementNote(const Decl *anchor, Type lhs,
Type rhs) const {
void RequirementFailure::maybeEmitRequirementNote(const Decl *anchor, Type lhs,
Type rhs) const {
auto &req = getRequirement();
if (req.getKind() != RequirementKind::SameType) {
@@ -431,6 +449,11 @@ void RequirementFailure::emitRequirementNote(const Decl *anchor, Type lhs,
if (req.getKind() == RequirementKind::Layout ||
rhs->isEqual(req.getSecondType())) {
// If the note is tautological, bail out.
if (lhs->isEqual(req.getFirstType())) {
return;
}
emitDiagnosticAt(anchor, diag::where_requirement_failure_one_subst,
req.getFirstType(), lhs);
return;
@@ -6269,6 +6292,16 @@ void InOutConversionFailure::fixItChangeArgumentType() const {
}
bool ArgumentMismatchFailure::diagnoseAsError() {
const auto paramType = getToType();
// If the parameter type contains an opened archetype, it's an unsupported
// existential member access; refrain from exposing type system implementation
// details in diagnostics and complaining about a parameter the user cannot
// fulfill, and let the member access failure prevail.
if (paramType->hasOpenedExistential()) {
return false;
}
if (diagnoseMisplacedMissingArgument())
return true;
@@ -6294,7 +6327,6 @@ bool ArgumentMismatchFailure::diagnoseAsError() {
return true;
auto argType = getFromType();
auto paramType = getToType();
if (paramType->isAnyObject()) {
emitDiagnostic(diag::cannot_convert_argument_value_anyobject, argType,