@@ -6254,6 +6254,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyTransitivelyConformsTo(
6254
6254
[](Type type) { return type->is <ProtocolCompositionType>(); }))
6255
6255
return SolutionKind::Solved;
6256
6256
6257
+ // All bets are off for pointers, there are multiple combinations
6258
+ // to check and it doesn't see worth to do that upfront.
6259
+ {
6260
+ PointerTypeKind pointerKind;
6261
+ if (resolvedTy->getAnyPointerElementType (pointerKind))
6262
+ return SolutionKind::Solved;
6263
+ }
6264
+
6257
6265
auto *protocol = protocolTy->castTo <ProtocolType>()->getDecl ();
6258
6266
6259
6267
auto *M = DC->getParentModule ();
@@ -6277,29 +6285,51 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyTransitivelyConformsTo(
6277
6285
typesToCheck.push_back (anyHashable->getDeclaredInterfaceType ());
6278
6286
6279
6287
// Rest of the implicit conversions depend on the resolved type.
6280
- if (auto *ptrDecl = ctx.getUnsafePointerDecl ()) {
6288
+ {
6289
+ auto getPointerFor = [&ctx](PointerTypeKind ptrKind,
6290
+ Optional<Type> elementTy = None) -> Type {
6291
+ switch (ptrKind) {
6292
+ case PTK_UnsafePointer:
6293
+ assert (elementTy);
6294
+ return BoundGenericType::get (ctx.getUnsafePointerDecl (),
6295
+ /* parent=*/ Type (), {*elementTy});
6296
+ case PTK_UnsafeMutablePointer:
6297
+ assert (elementTy);
6298
+ return BoundGenericType::get (ctx.getUnsafeMutablePointerDecl (),
6299
+ /* parent=*/ Type (), {*elementTy});
6300
+
6301
+ case PTK_UnsafeRawPointer:
6302
+ return ctx.getUnsafeRawPointerDecl ()->getDeclaredInterfaceType ();
6303
+
6304
+ case PTK_UnsafeMutableRawPointer:
6305
+ return ctx.getUnsafeMutableRawPointerDecl ()->getDeclaredInterfaceType ();
6306
+
6307
+ case PTK_AutoreleasingUnsafeMutablePointer:
6308
+ llvm_unreachable (" no implicit conversion" );
6309
+ }
6310
+ };
6311
+
6281
6312
// String -> UnsafePointer<Void>
6282
6313
if (auto *string = ctx.getStringDecl ()) {
6283
6314
if (resolvedTy->isEqual (string->getDeclaredInterfaceType ())) {
6284
- typesToCheck.push_back (BoundGenericType::get (ptrDecl, /* parent= */ Type (),
6285
- { ctx.TheEmptyTupleType } ));
6315
+ typesToCheck.push_back (
6316
+ getPointerFor (PTK_UnsafePointer, ctx.TheEmptyTupleType ));
6286
6317
}
6287
6318
}
6288
6319
6289
- // Array<T> -> UnsafePointer <T>
6320
+ // Array<T> -> Unsafe{Raw}Pointer <T>
6290
6321
if (auto elt = isArrayType (resolvedTy)) {
6291
- typesToCheck.push_back (
6292
- BoundGenericType::get (ptrDecl, /* parent= */ Type (), { *elt} ));
6322
+ typesToCheck.push_back (getPointerFor (PTK_UnsafePointer, *elt));
6323
+ typesToCheck. push_back ( getPointerFor (PTK_UnsafeRawPointer, *elt));
6293
6324
}
6294
6325
6295
- // inout argument -> UnsafePointer<T>, UnsafeMutablePointer<T>
6326
+ // inout argument -> UnsafePointer<T>, UnsafeMutablePointer<T>,
6327
+ // UnsafeRawPointer, UnsafeMutableRawPointer.
6296
6328
if (type->is <InOutType>()) {
6297
- typesToCheck.push_back (
6298
- BoundGenericType::get (ptrDecl, /* parent=*/ Type (), {resolvedTy}));
6299
-
6300
- if (auto *mutablePtr = ctx.getUnsafeMutablePointerDecl ())
6301
- typesToCheck.push_back (
6302
- BoundGenericType::get (mutablePtr, /* parent=*/ Type (), {resolvedTy}));
6329
+ typesToCheck.push_back (getPointerFor (PTK_UnsafePointer, resolvedTy));
6330
+ typesToCheck.push_back (getPointerFor (PTK_UnsafeMutablePointer, resolvedTy));
6331
+ typesToCheck.push_back (getPointerFor (PTK_UnsafeRawPointer));
6332
+ typesToCheck.push_back (getPointerFor (PTK_UnsafeMutableRawPointer));
6303
6333
}
6304
6334
}
6305
6335
0 commit comments