@@ -1975,12 +1975,17 @@ bool TypeBase::isBridgeableObjectType() {
1975
1975
}
1976
1976
1977
1977
bool TypeBase::isPotentiallyBridgedValueType () {
1978
+ // struct and enum types
1978
1979
if (auto nominal = getAnyNominal ()) {
1979
1980
if (isa<StructDecl>(nominal) || isa<EnumDecl>(nominal))
1980
1981
return true ;
1981
1982
}
1982
1983
1983
- return isExistentialWithError ();
1984
+ // Error existentials.
1985
+ if (isExistentialWithError ()) return true ;
1986
+
1987
+ // Archetypes.
1988
+ return is<ArchetypeType>();
1984
1989
}
1985
1990
1986
1991
// / Determine whether this is a representable Objective-C object type.
@@ -2150,9 +2155,33 @@ getForeignRepresentable(Type type, ForeignLanguage language,
2150
2155
if (type->isTypeParameter () && language == ForeignLanguage::ObjectiveC)
2151
2156
return { ForeignRepresentableKind::Object, nullptr };
2152
2157
2158
+ // In Objective-C, existentials involving Error are bridged
2159
+ // to NSError.
2160
+ if (language == ForeignLanguage::ObjectiveC &&
2161
+ type->isExistentialWithError ()) {
2162
+ return { ForeignRepresentableKind::BridgedError, nullptr };
2163
+ }
2164
+
2165
+ // / Determine whether the given type is a type that is bridged to NSError
2166
+ // / because it conforms to the Error protocol.
2167
+ auto isBridgedErrorViaConformance = [dc](Type type) -> bool {
2168
+ ASTContext &ctx = type->getASTContext ();
2169
+ auto errorProto = ctx.getProtocol (KnownProtocolKind::Error);
2170
+ if (!errorProto) return false ;
2171
+
2172
+ return dc->getParentModule ()->lookupConformance (type, errorProto,
2173
+ ctx.getLazyResolver ())
2174
+ .hasValue ();
2175
+ };
2176
+
2153
2177
auto nominal = type->getAnyNominal ();
2154
- if (!nominal)
2178
+ if (!nominal) {
2179
+ // / It might still be a bridged Error via conformance to Error.
2180
+ if (isBridgedErrorViaConformance (type))
2181
+ return { ForeignRepresentableKind::BridgedError, nullptr };
2182
+
2155
2183
return failure ();
2184
+ }
2156
2185
2157
2186
ASTContext &ctx = nominal->getASTContext ();
2158
2187
@@ -2232,18 +2261,16 @@ getForeignRepresentable(Type type, ForeignLanguage language,
2232
2261
}
2233
2262
}
2234
2263
2235
- // In Objective-C, existentials involving Error are bridged
2236
- // to NSError.
2237
- if (language == ForeignLanguage::ObjectiveC &&
2238
- type->isExistentialWithError ()) {
2239
- return { ForeignRepresentableKind::BridgedError, nullptr };
2240
- }
2241
-
2242
2264
// Determine whether this nominal type is known to be representable
2243
2265
// in this foreign language.
2244
2266
auto result = ctx.getForeignRepresentationInfo (nominal, language, dc);
2245
- if (result.getKind () == ForeignRepresentableKind::None)
2267
+ if (result.getKind () == ForeignRepresentableKind::None) {
2268
+ // / It might still be a bridged Error via conformance to Error.
2269
+ if (isBridgedErrorViaConformance (type))
2270
+ return { ForeignRepresentableKind::BridgedError, nullptr };
2271
+
2246
2272
return failure ();
2273
+ }
2247
2274
2248
2275
if (wasOptional && !result.isRepresentableAsOptional ())
2249
2276
return failure ();
0 commit comments