@@ -278,50 +278,7 @@ bool TypeBase::allowsOwnership(const GenericSignatureImpl *sig) {
278278 return getCanonicalType ().allowsOwnership (sig);
279279}
280280
281- // / Adds the inferred default protocols for an ExistentialLayout with respect
282- // / to that existential's inverses and existing protocols. For example, if an
283- // / inverse ~P exists, then P will not be added to the protocols list.
284- // /
285- // / Similarly, if the protocols list has a protocol Q that already implies
286- // / Copyable, then we will not add `Copyable` to the protocols list.
287- // /
288- // / \param inverses the inverses '& ~P' that are in the existential's type.
289- // / \param protocols the output vector of protocols for an ExistentialLayout
290- // / to be modified.
291- static void expandDefaultProtocols (
292- ASTContext &ctx,
293- InvertibleProtocolSet inverses,
294- SmallVectorImpl<ProtocolDecl*> &protocols) {
295-
296- // Skip unless noncopyable generics is enabled
297- if (!ctx.LangOpts .hasFeature (swift::Feature::NoncopyableGenerics))
298- return ;
299281
300- // Try to add all invertible protocols, unless:
301- // - an inverse was provided
302- // - an existing protocol already requires it
303- for (auto ip : InvertibleProtocolSet::full ()) {
304- if (inverses.contains (ip))
305- continue ;
306-
307- // This matches with `lookupExistentialConformance`'s use of 'inheritsFrom'.
308- bool alreadyRequired = false ;
309- for (auto proto : protocols) {
310- if (proto->requiresInvertible (ip)) {
311- alreadyRequired = true ;
312- break ;
313- }
314- }
315-
316- if (alreadyRequired)
317- continue ;
318-
319- auto proto = ctx.getProtocol (getKnownProtocolKind (ip));
320- assert (proto && " missing Copyable/Escapable from stdlib!" );
321-
322- protocols.push_back (proto);
323- }
324- }
325282
326283ExistentialLayout::ExistentialLayout (CanProtocolType type) {
327284 auto *protoDecl = type->getDecl ();
@@ -336,7 +293,7 @@ ExistentialLayout::ExistentialLayout(CanProtocolType type) {
336293 protocols.push_back (protoDecl);
337294
338295 // NOTE: all the invertible protocols are usable from ObjC.
339- expandDefaultProtocols (type->getASTContext (), {}, protocols);
296+ InverseRequirement::expandDefaults (type->getASTContext (), {}, protocols);
340297}
341298
342299ExistentialLayout::ExistentialLayout (CanProtocolCompositionType type) {
@@ -373,7 +330,9 @@ ExistentialLayout::ExistentialLayout(CanProtocolCompositionType type) {
373330 hasExplicitAnyObject && !explicitSuperclass && getProtocols ().empty ();
374331
375332 // NOTE: all the invertible protocols are usable from ObjC.
376- expandDefaultProtocols (type->getASTContext (), type->getInverses (), protocols);
333+ InverseRequirement::expandDefaults (type->getASTContext (),
334+ type->getInverses (),
335+ protocols);
377336}
378337
379338ExistentialLayout::ExistentialLayout (CanParameterizedProtocolType type)
@@ -3939,7 +3898,7 @@ Type ProtocolCompositionType::get(const ASTContext &C,
39393898 ArrayRef<Type> Members,
39403899 InvertibleProtocolSet Inverses,
39413900 bool HasExplicitAnyObject) {
3942- // Fast path for 'AnyObject' and 'Any '.
3901+ // Fast path for 'AnyObject', 'Any', and '~Copyable '.
39433902 if (Members.empty ()) {
39443903 return build (C, Members, Inverses, HasExplicitAnyObject);
39453904 }
@@ -3994,6 +3953,13 @@ Type ProtocolCompositionType::get(const ASTContext &C,
39943953 }
39953954 }
39963955
3956+ // Drop any explicitly provided invertible protocols.
3957+ if (auto ip = proto->getInvertibleProtocolKind ()) {
3958+ // We diagnose '~Copyable & Copyable' before forming the PCT.
3959+ assert (!Inverses.contains (*ip) && " opposing invertible constraints!" );
3960+ continue ;
3961+ }
3962+
39973963 CanTypes.push_back (proto->getDeclaredInterfaceType ());
39983964 }
39993965
0 commit comments