@@ -6254,6 +6254,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyTransitivelyConformsTo(
62546254 [](Type type) { return type->is <ProtocolCompositionType>(); }))
62556255 return SolutionKind::Solved;
62566256
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+
62576265 auto *protocol = protocolTy->castTo <ProtocolType>()->getDecl ();
62586266
62596267 auto *M = DC->getParentModule ();
@@ -6277,29 +6285,51 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyTransitivelyConformsTo(
62776285 typesToCheck.push_back (anyHashable->getDeclaredInterfaceType ());
62786286
62796287 // 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+
62816312 // String -> UnsafePointer<Void>
62826313 if (auto *string = ctx.getStringDecl ()) {
62836314 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 ));
62866317 }
62876318 }
62886319
6289- // Array<T> -> UnsafePointer <T>
6320+ // Array<T> -> Unsafe{Raw}Pointer <T>
62906321 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));
62936324 }
62946325
6295- // inout argument -> UnsafePointer<T>, UnsafeMutablePointer<T>
6326+ // inout argument -> UnsafePointer<T>, UnsafeMutablePointer<T>,
6327+ // UnsafeRawPointer, UnsafeMutableRawPointer.
62966328 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));
63036333 }
63046334 }
63056335
0 commit comments