mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #39492 from AnthonyLatsis/se-309-2
SE-309: Covariant erasure for dependent member types
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user