@@ -573,6 +573,9 @@ bool MissingConformanceFailure::diagnoseAsError() {
573
573
}
574
574
}
575
575
576
+ if (diagnoseAsAmbiguousOperatorRef ())
577
+ return true ;
578
+
576
579
Optional<unsigned > atParameterPos;
577
580
// Sometimes fix is recorded by type-checking sub-expression
578
581
// during normal diagnostics, in such case call expression
@@ -614,6 +617,52 @@ bool MissingConformanceFailure::diagnoseAsError() {
614
617
return RequirementFailure::diagnoseAsError ();
615
618
}
616
619
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
+
617
666
Optional<Diag<Type, Type>> GenericArgumentsMismatchFailure::getDiagnosticFor (
618
667
ContextualTypePurpose context) {
619
668
switch (context) {
0 commit comments