@@ -3569,15 +3569,14 @@ bool FailureDiagnosis::diagnoseCalleeResultContextualConversionError() {
3569
3569
3570
3570
3571
3571
// / Return true if the given type conforms to a known protocol type.
3572
- static bool isExpressibleByLiteralType (Type fromType,
3573
- KnownProtocolKind kind,
3574
- ConstraintSystem *CS) {
3575
- auto integerType =
3576
- CS->TC .getProtocol (SourceLoc (), kind);
3577
- if (!integerType)
3572
+ static bool conformsToKnownProtocol (Type fromType,
3573
+ KnownProtocolKind kind,
3574
+ ConstraintSystem *CS) {
3575
+ auto proto = CS->TC .getProtocol (SourceLoc (), kind);
3576
+ if (!proto)
3578
3577
return false ;
3579
3578
3580
- if (CS->TC .conformsToProtocol (fromType, integerType , CS->DC ,
3579
+ if (CS->TC .conformsToProtocol (fromType, proto , CS->DC ,
3581
3580
ConformanceCheckFlags::InExpression)) {
3582
3581
return true ;
3583
3582
}
@@ -3586,9 +3585,9 @@ static bool isExpressibleByLiteralType(Type fromType,
3586
3585
}
3587
3586
3588
3587
static bool isIntegerType (Type fromType, ConstraintSystem *CS) {
3589
- return isExpressibleByLiteralType (fromType,
3590
- KnownProtocolKind::ExpressibleByIntegerLiteral,
3591
- CS);
3588
+ return conformsToKnownProtocol (fromType,
3589
+ KnownProtocolKind::ExpressibleByIntegerLiteral,
3590
+ CS);
3592
3591
}
3593
3592
3594
3593
// / Return true if the given type conforms to RawRepresentable.
@@ -3618,7 +3617,7 @@ static Type isRawRepresentable(Type fromType,
3618
3617
KnownProtocolKind kind,
3619
3618
ConstraintSystem *CS) {
3620
3619
Type rawTy = isRawRepresentable (fromType, CS);
3621
- if (!rawTy || !isExpressibleByLiteralType (rawTy, kind, CS))
3620
+ if (!rawTy || !conformsToKnownProtocol (rawTy, kind, CS))
3622
3621
return Type ();
3623
3622
3624
3623
return rawTy;
@@ -3629,7 +3628,7 @@ static Type isRawRepresentable(Type fromType,
3629
3628
static bool isIntegerToStringIndexConversion (Type fromType, Type toType,
3630
3629
ConstraintSystem *CS) {
3631
3630
auto kind = KnownProtocolKind::ExpressibleByIntegerLiteral;
3632
- return (isExpressibleByLiteralType (fromType, kind, CS) &&
3631
+ return (conformsToKnownProtocol (fromType, kind, CS) &&
3633
3632
toType->getCanonicalType ().getString () == " String.CharacterView.Index" );
3634
3633
}
3635
3634
@@ -3684,14 +3683,23 @@ static bool tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3684
3683
}
3685
3684
};
3686
3685
3687
- if (isExpressibleByLiteralType (fromType, kind, CS)) {
3686
+ if (conformsToKnownProtocol (fromType, kind, CS)) {
3688
3687
if (auto rawTy = isRawRepresentable (toType, kind, CS)) {
3689
3688
// Produce before/after strings like 'Result(rawValue: RawType(<expr>))'
3690
3689
// or just 'Result(rawValue: <expr>)'.
3691
3690
std::string convWrapBefore = toType.getString ();
3692
3691
convWrapBefore += " (rawValue: " ;
3693
3692
std::string convWrapAfter = " )" ;
3694
- if (rawTy->getCanonicalType () != fromType->getCanonicalType ()) {
3693
+ if (!CS->TC .isConvertibleTo (fromType, rawTy, CS->DC )) {
3694
+ // Only try to insert a converting construction if the protocol is a
3695
+ // literal protocol and not some other known protocol.
3696
+ switch (kind) {
3697
+ #define EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME (name, _ ) \
3698
+ case KnownProtocolKind::name: break ;
3699
+ #define PROTOCOL_WITH_NAME (name, _ ) \
3700
+ case KnownProtocolKind::name: return false ;
3701
+ #include " swift/AST/KnownProtocols.def"
3702
+ }
3695
3703
convWrapBefore += rawTy->getString ();
3696
3704
convWrapBefore += " (" ;
3697
3705
convWrapAfter += " )" ;
@@ -3702,11 +3710,20 @@ static bool tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3702
3710
}
3703
3711
3704
3712
if (auto rawTy = isRawRepresentable (fromType, kind, CS)) {
3705
- if (isExpressibleByLiteralType (toType, kind, CS)) {
3713
+ if (conformsToKnownProtocol (toType, kind, CS)) {
3706
3714
std::string convWrapBefore;
3707
3715
std::string convWrapAfter = " .rawValue" ;
3708
- if (rawTy->getCanonicalType () != toType->getCanonicalType ()) {
3709
- convWrapBefore += rawTy->getString ();
3716
+ if (!CS->TC .isConvertibleTo (rawTy, toType, CS->DC )) {
3717
+ // Only try to insert a converting construction if the protocol is a
3718
+ // literal protocol and not some other known protocol.
3719
+ switch (kind) {
3720
+ #define EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME (name, _ ) \
3721
+ case KnownProtocolKind::name: break ;
3722
+ #define PROTOCOL_WITH_NAME (name, _ ) \
3723
+ case KnownProtocolKind::name: return false ;
3724
+ #include " swift/AST/KnownProtocols.def"
3725
+ }
3726
+ convWrapBefore += toType->getString ();
3710
3727
convWrapBefore += " (" ;
3711
3728
convWrapAfter += " )" ;
3712
3729
}
@@ -4167,6 +4184,9 @@ bool FailureDiagnosis::diagnoseContextualConversionError() {
4167
4184
tryRawRepresentableFixIts (diag, CS, exprType, contextualType,
4168
4185
KnownProtocolKind::ExpressibleByStringLiteral,
4169
4186
expr) ||
4187
+ tryRawRepresentableFixIts (diag, CS, exprType, contextualType,
4188
+ KnownProtocolKind::AnyObject,
4189
+ expr) ||
4170
4190
tryIntegerCastFixIts (diag, CS, exprType, contextualType, expr) ||
4171
4191
addTypeCoerceFixit (diag, CS, exprType, contextualType, expr);
4172
4192
break ;
0 commit comments