@@ -3582,15 +3582,14 @@ bool FailureDiagnosis::diagnoseCalleeResultContextualConversionError() {
3582
3582
3583
3583
3584
3584
// / Return true if the given type conforms to a known protocol type.
3585
- static bool isExpressibleByLiteralType (Type fromType,
3586
- KnownProtocolKind kind,
3587
- ConstraintSystem *CS) {
3588
- auto integerType =
3589
- CS->TC .getProtocol (SourceLoc (), kind);
3590
- if (!integerType)
3585
+ static bool conformsToKnownProtocol (Type fromType,
3586
+ KnownProtocolKind kind,
3587
+ ConstraintSystem *CS) {
3588
+ auto proto = CS->TC .getProtocol (SourceLoc (), kind);
3589
+ if (!proto)
3591
3590
return false ;
3592
3591
3593
- if (CS->TC .conformsToProtocol (fromType, integerType , CS->DC ,
3592
+ if (CS->TC .conformsToProtocol (fromType, proto , CS->DC ,
3594
3593
ConformanceCheckFlags::InExpression)) {
3595
3594
return true ;
3596
3595
}
@@ -3599,9 +3598,9 @@ static bool isExpressibleByLiteralType(Type fromType,
3599
3598
}
3600
3599
3601
3600
static bool isIntegerType (Type fromType, ConstraintSystem *CS) {
3602
- return isExpressibleByLiteralType (fromType,
3603
- KnownProtocolKind::ExpressibleByIntegerLiteral,
3604
- CS);
3601
+ return conformsToKnownProtocol (fromType,
3602
+ KnownProtocolKind::ExpressibleByIntegerLiteral,
3603
+ CS);
3605
3604
}
3606
3605
3607
3606
// / Return true if the given type conforms to RawRepresentable.
@@ -3631,7 +3630,7 @@ static Type isRawRepresentable(Type fromType,
3631
3630
KnownProtocolKind kind,
3632
3631
ConstraintSystem *CS) {
3633
3632
Type rawTy = isRawRepresentable (fromType, CS);
3634
- if (!rawTy || !isExpressibleByLiteralType (rawTy, kind, CS))
3633
+ if (!rawTy || !conformsToKnownProtocol (rawTy, kind, CS))
3635
3634
return Type ();
3636
3635
3637
3636
return rawTy;
@@ -3642,7 +3641,7 @@ static Type isRawRepresentable(Type fromType,
3642
3641
static bool isIntegerToStringIndexConversion (Type fromType, Type toType,
3643
3642
ConstraintSystem *CS) {
3644
3643
auto kind = KnownProtocolKind::ExpressibleByIntegerLiteral;
3645
- return (isExpressibleByLiteralType (fromType, kind, CS) &&
3644
+ return (conformsToKnownProtocol (fromType, kind, CS) &&
3646
3645
toType->getCanonicalType ().getString () == " String.CharacterView.Index" );
3647
3646
}
3648
3647
@@ -3697,14 +3696,23 @@ static bool tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3697
3696
}
3698
3697
};
3699
3698
3700
- if (isExpressibleByLiteralType (fromType, kind, CS)) {
3699
+ if (conformsToKnownProtocol (fromType, kind, CS)) {
3701
3700
if (auto rawTy = isRawRepresentable (toType, kind, CS)) {
3702
3701
// Produce before/after strings like 'Result(rawValue: RawType(<expr>))'
3703
3702
// or just 'Result(rawValue: <expr>)'.
3704
3703
std::string convWrapBefore = toType.getString ();
3705
3704
convWrapBefore += " (rawValue: " ;
3706
3705
std::string convWrapAfter = " )" ;
3707
- if (rawTy->getCanonicalType () != fromType->getCanonicalType ()) {
3706
+ if (!CS->TC .isConvertibleTo (fromType, rawTy, CS->DC )) {
3707
+ // Only try to insert a converting construction if the protocol is a
3708
+ // literal protocol and not some other known protocol.
3709
+ switch (kind) {
3710
+ #define EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME (name, _ ) \
3711
+ case KnownProtocolKind::name: break ;
3712
+ #define PROTOCOL_WITH_NAME (name, _ ) \
3713
+ case KnownProtocolKind::name: return false ;
3714
+ #include " swift/AST/KnownProtocols.def"
3715
+ }
3708
3716
convWrapBefore += rawTy->getString ();
3709
3717
convWrapBefore += " (" ;
3710
3718
convWrapAfter += " )" ;
@@ -3715,11 +3723,20 @@ static bool tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3715
3723
}
3716
3724
3717
3725
if (auto rawTy = isRawRepresentable (fromType, kind, CS)) {
3718
- if (isExpressibleByLiteralType (toType, kind, CS)) {
3726
+ if (conformsToKnownProtocol (toType, kind, CS)) {
3719
3727
std::string convWrapBefore;
3720
3728
std::string convWrapAfter = " .rawValue" ;
3721
- if (rawTy->getCanonicalType () != toType->getCanonicalType ()) {
3722
- convWrapBefore += rawTy->getString ();
3729
+ if (!CS->TC .isConvertibleTo (rawTy, toType, CS->DC )) {
3730
+ // Only try to insert a converting construction if the protocol is a
3731
+ // literal protocol and not some other known protocol.
3732
+ switch (kind) {
3733
+ #define EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME (name, _ ) \
3734
+ case KnownProtocolKind::name: break ;
3735
+ #define PROTOCOL_WITH_NAME (name, _ ) \
3736
+ case KnownProtocolKind::name: return false ;
3737
+ #include " swift/AST/KnownProtocols.def"
3738
+ }
3739
+ convWrapBefore += toType->getString ();
3723
3740
convWrapBefore += " (" ;
3724
3741
convWrapAfter += " )" ;
3725
3742
}
@@ -4180,6 +4197,9 @@ bool FailureDiagnosis::diagnoseContextualConversionError() {
4180
4197
tryRawRepresentableFixIts (diag, CS, exprType, contextualType,
4181
4198
KnownProtocolKind::ExpressibleByStringLiteral,
4182
4199
expr) ||
4200
+ tryRawRepresentableFixIts (diag, CS, exprType, contextualType,
4201
+ KnownProtocolKind::AnyObject,
4202
+ expr) ||
4183
4203
tryIntegerCastFixIts (diag, CS, exprType, contextualType, expr) ||
4184
4204
addTypeCoerceFixit (diag, CS, exprType, contextualType, expr);
4185
4205
break ;
0 commit comments