@@ -2941,6 +2941,14 @@ void TypeConverter::verifyLowering(const TypeLowering &lowering,
29412941 AbstractionPattern origType,
29422942 CanType substType,
29432943 TypeExpansionContext forExpansion) {
2944+ verifyLexicalLowering (lowering, origType, substType, forExpansion);
2945+ verifyTrivialLowering (lowering, origType, substType, forExpansion);
2946+ }
2947+
2948+ void TypeConverter::verifyLexicalLowering (const TypeLowering &lowering,
2949+ AbstractionPattern origType,
2950+ CanType substType,
2951+ TypeExpansionContext forExpansion) {
29442952 // Non-trivial lowerings should always be lexical unless all non-trivial
29452953 // fields are eager move.
29462954 if (!lowering.isTrivial () && !lowering.isLexical ()) {
@@ -3007,6 +3015,148 @@ void TypeConverter::verifyLowering(const TypeLowering &lowering,
30073015 " Found non-trivial lexical leaf in non-trivial non-lexical type?!" );
30083016 }
30093017}
3018+
3019+ void TypeConverter::verifyTrivialLowering (const TypeLowering &lowering,
3020+ AbstractionPattern origType,
3021+ CanType substType,
3022+ TypeExpansionContext forExpansion) {
3023+ if (!Context.LangOpts .hasFeature (Feature::BitwiseCopyable))
3024+ return ;
3025+ auto *bitwiseCopyableProtocol =
3026+ Context.getProtocol (KnownProtocolKind::BitwiseCopyable);
3027+ if (!bitwiseCopyableProtocol)
3028+ return ;
3029+
3030+ auto conformance = M.conformsToProtocol (substType, bitwiseCopyableProtocol);
3031+
3032+ if (lowering.isTrivial () && !conformance) {
3033+ // A trivial type can only lack a conformance if one of its leaves is a
3034+ // public type that doesn't conform.
3035+ bool hasNoNonconformingNode = visitAggregateLeaves (
3036+ origType, substType, forExpansion,
3037+ /* isLeaf=*/
3038+ [&](auto ty, auto origTy, auto *field, auto index) -> bool {
3039+ // The field's type is an aggregate. Treat it as a leaf if it is
3040+ // public.
3041+ auto *nominal = ty.getAnyNominal ();
3042+ // Non-nominal types are public iff their components are; visit the
3043+ // components.
3044+ if (!nominal)
3045+ return false ;
3046+
3047+ // Nominals with generic parameters must be explicitly conformed to
3048+ // BitwiseCopyable.
3049+ auto *generic = ty.getAnyGeneric ();
3050+ if (generic && generic->isGenericContext ()) {
3051+ return true ;
3052+ }
3053+
3054+ return nominal
3055+ ->getFormalAccessScope (/* useDC=*/ nullptr ,
3056+ /* treatUsableFromInlineAsPublic=*/ true )
3057+ .isPublic ();
3058+ },
3059+ /* visit=*/
3060+ [&](auto ty, auto origTy, auto *field, auto index) -> bool {
3061+ // Return false to indicate seeing a leaf which justifies the type
3062+ // being trivial but not conforming to BitwiseCopyable.
3063+
3064+ // A BitwiseCopyable conformer appearing within its layout doesn't
3065+ // explain why substType doesn't itself conform.
3066+ if (M.conformsToProtocol (ty, bitwiseCopyableProtocol))
3067+ return true ;
3068+
3069+ // ModuleTypes are trivial but don't warrant being given a conformance
3070+ // to BitwiseCopyable.
3071+ if (auto mt = dyn_cast<ModuleType>(ty)) {
3072+ // If one were to appear within a type, its lack of conformance
3073+ // wouldn't result in the type's failure to conform. Conversely, if
3074+ // substType itself is the ModuleType, it is trivial and
3075+ // non-conformant; return false to indicate its the leaf which
3076+ // justifies substType being non-conformant.
3077+ return field;
3078+ }
3079+
3080+ // Given a non-bitwise-copyable C, unowned(unsafe) C is still
3081+ // BitwiseCopyable.
3082+ auto rst = dyn_cast<ReferenceStorageType>(ty);
3083+ if (rst && rst->getOwnership () == ReferenceOwnership::Unmanaged) {
3084+ // If a ReferenceStorageType appears as a component of an aggregate,
3085+ // that shouldn't stop the aggregate from being BitwiseCopyable. If
3086+ // the whole type is the ReferenceStorageType, however, it does not
3087+ // conform.
3088+ return field;
3089+ }
3090+
3091+ auto *nominal = ty.getAnyNominal ();
3092+
3093+ // Non-nominal types are trivial iff conforming.
3094+ if (!nominal) {
3095+ llvm::errs ()
3096+ << " Non-nominal type without conformance to _BitwiseCopyable:\n "
3097+ << ty << " \n "
3098+ << " within " << substType << " \n "
3099+ << " of " << origType << " \n " ;
3100+ assert (false );
3101+ return true ;
3102+ }
3103+
3104+ // / A non-conforming generic nominal type justifies substType not
3105+ // / conforming.
3106+ auto *generic = ty.getAnyGeneric ();
3107+ if (generic && generic->isGenericContext ()) {
3108+ return false ;
3109+ }
3110+
3111+ // The field is trivial and the whole type is nonconforming. That's
3112+ // legal iff the type is public.
3113+ return !nominal
3114+ ->getFormalAccessScope (
3115+ /* useDC=*/ nullptr ,
3116+ /* treatUsableFromInlineAsPublic=*/ true )
3117+ .isPublic ();
3118+ });
3119+ if (hasNoNonconformingNode) {
3120+ llvm::errs () << " Trivial type without a BitwiseCopyable conformance!?:\n "
3121+ << substType << " \n "
3122+ << " of " << origType << " \n " ;
3123+ assert (false );
3124+ }
3125+ }
3126+
3127+ if (!lowering.isTrivial () && conformance) {
3128+ // A non-trivial type can only conform if at least one of its leaves is a
3129+ // type parameter that conforms.
3130+ bool hasNoConformingArchetypeNode = visitAggregateLeaves (
3131+ origType, substType, forExpansion,
3132+ /* isLeaf=*/
3133+ [&](auto ty, auto origTy, auto *field, auto index) -> bool {
3134+ // Walk into every aggregate.
3135+ return false ;
3136+ },
3137+ /* visit=*/
3138+ [&](auto ty, auto origTy, auto *field, auto index) -> bool {
3139+ // Return false to indicate visiting a type parameter.
3140+
3141+ if (origTy.isTypeParameter ())
3142+ return false ;
3143+
3144+ // Unfortunately, the type parameter's conformance may not be visible
3145+ // here.
3146+ assert (M.conformsToProtocol (ty, bitwiseCopyableProtocol) &&
3147+ " leaf of non-trivial BitwiseCopyable type that doesn't "
3148+ " conform to BitwiseCopyable!?" );
3149+
3150+ return true ;
3151+ });
3152+ if (hasNoConformingArchetypeNode) {
3153+ llvm::errs () << " Non-trivial type with _BitwiseCopyable conformance!?:\n "
3154+ << substType << " \n " ;
3155+ conformance.print (llvm::errs ());
3156+ assert (false );
3157+ }
3158+ }
3159+ }
30103160#endif
30113161
30123162CanType
0 commit comments