Skip to content

Commit c9ce9bd

Browse files
committed
---
yaml --- r: 343935 b: refs/heads/master-rebranch c: 973d58d h: refs/heads/master i: 343933: ac29a26 343931: ed5e8b1 343927: 4b9369e 343919: 7966c5c 343903: 336221e 343871: 5bc2e8e 343807: aefcb24
1 parent 904bf66 commit c9ce9bd

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14551455
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14561456
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14571457
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1458-
refs/heads/master-rebranch: 25d7a0732397d0f39581bdbd48df0292878f3519
1458+
refs/heads/master-rebranch: 973d58d56fb0614302059794bb182418d88ea216
14591459
refs/heads/rdar-53901732: 9bd06af3284e18a109cdbf9aa59d833b24eeca7b
14601460
refs/heads/revert-26776-subst-always-returns-a-type: 1b8e18fdd391903a348970a4c848995d4cdd789c
14611461
refs/heads/tensorflow-merge: 8b854f62f80d4476cb383d43c4aac2001dde3cec

branches/master-rebranch/lib/Sema/CSDiagnostics.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,9 @@ bool MissingConformanceFailure::diagnoseAsError() {
573573
}
574574
}
575575

576+
if (diagnoseAsAmbiguousOperatorRef())
577+
return true;
578+
576579
Optional<unsigned> atParameterPos;
577580
// Sometimes fix is recorded by type-checking sub-expression
578581
// during normal diagnostics, in such case call expression
@@ -614,6 +617,52 @@ bool MissingConformanceFailure::diagnoseAsError() {
614617
return RequirementFailure::diagnoseAsError();
615618
}
616619

620+
bool MissingConformanceFailure::diagnoseAsAmbiguousOperatorRef() {
621+
auto *anchor = getRawAnchor();
622+
auto *ODRE = dyn_cast<OverloadedDeclRefExpr>(anchor);
623+
if (!ODRE)
624+
return false;
625+
626+
auto isStdlibType = [](Type type) {
627+
if (auto *NTD = type->getAnyNominal()) {
628+
auto *DC = NTD->getDeclContext();
629+
return DC->isModuleScopeContext() &&
630+
DC->getParentModule()->isStdlibModule();
631+
}
632+
633+
return false;
634+
};
635+
636+
auto name = ODRE->getDecls().front()->getBaseName();
637+
if (!(name.isOperator() && isStdlibType(getLHS()) && isStdlibType(getRHS())))
638+
return false;
639+
640+
// If this is an operator reference and both types are from stdlib,
641+
// let's produce a generic diagnostic about invocation and a note
642+
// about missing conformance just in case.
643+
auto operatorID = name.getIdentifier();
644+
645+
auto *applyExpr = cast<ApplyExpr>(findParentExpr(anchor));
646+
if (auto *binaryOp = dyn_cast<BinaryExpr>(applyExpr)) {
647+
auto lhsType = getType(binaryOp->getArg()->getElement(0));
648+
auto rhsType = getType(binaryOp->getArg()->getElement(1));
649+
650+
if (lhsType->isEqual(rhsType)) {
651+
emitDiagnostic(anchor->getLoc(), diag::cannot_apply_binop_to_same_args,
652+
operatorID.str(), lhsType);
653+
} else {
654+
emitDiagnostic(anchor->getLoc(), diag::cannot_apply_binop_to_args,
655+
operatorID.str(), lhsType, rhsType);
656+
}
657+
} else {
658+
emitDiagnostic(anchor->getLoc(), diag::cannot_apply_unop_to_arg,
659+
operatorID.str(), getType(applyExpr->getArg()));
660+
}
661+
662+
diagnoseAsNote();
663+
return true;
664+
}
665+
617666
Optional<Diag<Type, Type>> GenericArgumentsMismatchFailure::getDiagnosticFor(
618667
ContextualTypePurpose context) {
619668
switch (context) {

branches/master-rebranch/lib/Sema/CSDiagnostics.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ class MissingConformanceFailure final : public RequirementFailure {
327327
bool diagnoseAsError() override;
328328

329329
protected:
330+
/// Check whether this requirement is associated with one of the
331+
/// operator overloads, in cases like that sometimes it makes more
332+
/// sense to produce a generic diagnostic about operator reference
333+
/// instead of conformance, because it could be something like
334+
/// `true + true`, and it doesn't make much sense to suggest to
335+
/// add a conformance from one library type to another.
336+
bool diagnoseAsAmbiguousOperatorRef();
337+
330338
DiagOnDecl getDiagnosticOnDecl() const override {
331339
return diag::type_does_not_conform_decl_owner;
332340
}

0 commit comments

Comments
 (0)