@@ -2793,6 +2793,17 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
27932793}
27942794
27952795namespace swift ::test {
2796+ static FunctionTest PrintASTTypeLowering (
2797+ " print_ast_type_lowering" , [](auto &function, auto &arguments, auto &test) {
2798+ auto value = arguments.takeValue ();
2799+ auto silTy = value->getType ();
2800+ auto canTy = silTy.getRawASTType ();
2801+ auto *ty = canTy.getPointer ();
2802+ function.getModule ()
2803+ .Types .getTypeLowering (AbstractionPattern (ty), ty, function)
2804+ .print (llvm::outs ());
2805+ });
2806+
27962807// Arguments:
27972808// - value: whose type will be printed
27982809// Dumps:
@@ -3028,67 +3039,78 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30283039 auto conformance = M.checkConformance (substType, bitwiseCopyableProtocol);
30293040
30303041 if (lowering.isTrivial () && !conformance) {
3031- // A trivial type can only lack a conformance if one of its leaves is a
3032- // public type that doesn't conform.
3042+ // A trivial type can lack a conformance in a few cases:
3043+ // (1) containing or being a resilient type
3044+ // (2) containing or being a generic type which doesn't conform
3045+ // unconditionally but in this particular instantiation is trivial
3046+ // (3) being a special type that's not worth forming a conformance for
3047+ // - ModuleType
3048+ // - SILTokenType
3049+ // (4) being an unowned(unsafe) reference to a class/class-bound existential
3050+ // NOTE: ReferenceStorageType(C) does not conform HOWEVER the presence
3051+ // of an unowned(unsafe) field within an aggregate DOES NOT allow
3052+ // the aggregate to lack conformance. In other words, this must
3053+ // conform:
3054+ // struct S {
3055+ // unowned(unsafe) var o: AnyObject
3056+ // }
30333057 bool hasNoNonconformingNode = visitAggregateLeaves (
30343058 origType, substType, forExpansion,
3035- /* isLeaf =*/
3059+ /* isLeafAggregate =*/
30363060 [&](auto ty, auto origTy, auto *field, auto index) -> bool {
3037- // The field's type is an aggregate. Treat it as a leaf if it is
3038- // public.
30393061 auto *nominal = ty.getAnyNominal ();
3040- // Non-nominal types are public iff their components are; visit the
3041- // components .
3062+ // Non-nominal aggregates must not be responsible for non-conformance;
3063+ // walk into them .
30423064 if (!nominal)
30433065 return false ;
30443066
3045- // Nominals with generic parameters must be explicitly conformed to
3046- // BitwiseCopyable.
3047- auto *generic = ty. getAnyGeneric ();
3048- if (generic && generic ->isGenericContext ()) {
3067+ // Nominals with fields that are generic may not conform
3068+ // unconditionally (the only kind automatically derived currently)
3069+ // and so may lack a conformance (case (2)).
3070+ if (nominal ->isGenericContext ()) {
30493071 return true ;
30503072 }
30513073
3052- return nominal
3053- ->getFormalAccessScope (/* useDC=*/ nullptr ,
3054- /* treatUsableFromInlineAsPublic=*/ true )
3055- .isPublic ();
3074+ // Resilient trivial types may not conform (case (1)).
3075+ return nominal->isResilient ();
30563076 },
30573077 /* visit=*/
30583078 [&](auto ty, auto origTy, auto *field, auto index) -> bool {
30593079 // Return false to indicate seeing a leaf which justifies the type
30603080 // being trivial but not conforming to BitwiseCopyable.
30613081
3082+ auto isTopLevel = !field;
3083+
30623084 // A BitwiseCopyable conformer appearing within its layout doesn't
30633085 // explain why substType doesn't itself conform.
30643086 if (M.checkConformance (ty, bitwiseCopyableProtocol))
30653087 return true ;
30663088
3067- // ModuleTypes are trivial but don't warrant being given a conformance
3068- // to BitwiseCopyable.
3069- if (auto mt = dyn_cast<ModuleType>(ty)) {
3070- // If one were to appear within a type, its lack of conformance
3071- // wouldn't result in the type's failure to conform. Conversely, if
3072- // substType itself is the ModuleType, it is trivial and
3073- // non-conformant; return false to indicate its the leaf which
3074- // justifies substType being non-conformant.
3075- return field;
3089+ // ModuleTypes are trivial but don't warrant being given a
3090+ // conformance to BitwiseCopyable (case (3)).
3091+ if (isa<ModuleType, SILTokenType>(ty)) {
3092+ // These types should never appear within aggregates.
3093+ assert (isTopLevel && " aggregate containing marker type!?" );
3094+ // If they did, though, they would not justify the aggregate's
3095+ // non-conformance.
3096+ // top-level -> justified to be trivial and non-conformant -> false
3097+ // leaf -> must not be responsible for non-conformance -> true
3098+ return !isTopLevel;
30763099 }
30773100
3078- // Given a non-bitwise-copyable C, unowned(unsafe) C is still
3079- // BitwiseCopyable .
3101+ // ReferenceStorageTypes with unmanaged ownership do not themselves
3102+ // conform (case (4)) .
30803103 auto rst = dyn_cast<ReferenceStorageType>(ty);
30813104 if (rst && rst->getOwnership () == ReferenceOwnership::Unmanaged) {
3082- // If a ReferenceStorageType appears as a component of an aggregate,
3083- // that shouldn't stop the aggregate from being BitwiseCopyable. If
3084- // the whole type is the ReferenceStorageType, however, it does not
3085- // conform.
3086- return field;
3105+ // top-level -> justified to be trivial and non-conformant -> false
3106+ // leaf -> must not be responsible for non-conformance -> true
3107+ return !isTopLevel;
30873108 }
30883109
30893110 auto *nominal = ty.getAnyNominal ();
30903111
3091- // Non-nominal types are trivial iff conforming.
3112+ // Non-nominal types (besides case (3) handled above) are trivial iff
3113+ // conforming.
30923114 if (!nominal) {
30933115 llvm::errs ()
30943116 << " Non-nominal type without conformance to _BitwiseCopyable:\n "
@@ -3099,20 +3121,14 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30993121 return true ;
31003122 }
31013123
3102- // / A non-conforming generic nominal type justifies substType not
3103- // / conforming.
3104- auto *generic = ty.getAnyGeneric ();
3105- if (generic && generic->isGenericContext ()) {
3124+ // A generic type may be trivial when instantiated with particular
3125+ // types but lack a conformance (case (3)).
3126+ if (nominal->isGenericContext ()) {
31063127 return false ;
31073128 }
31083129
3109- // The field is trivial and the whole type is nonconforming. That's
3110- // legal iff the type is public.
3111- return !nominal
3112- ->getFormalAccessScope (
3113- /* useDC=*/ nullptr ,
3114- /* treatUsableFromInlineAsPublic=*/ true )
3115- .isPublic ();
3130+ // Resilient trivial types may not conform (case (1)).
3131+ return !nominal->isResilient ();
31163132 });
31173133 if (hasNoNonconformingNode) {
31183134 llvm::errs () << " Trivial type without a BitwiseCopyable conformance!?:\n "
@@ -3123,8 +3139,8 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
31233139 }
31243140
31253141 if (!lowering.isTrivial () && conformance) {
3126- // A non-trivial type can only conform if at least one of its leaves is a
3127- // type parameter that conforms.
3142+ // A non-trivial type can have a conformance in one case:
3143+ // (1) contains a conforming archetype
31283144 bool hasNoConformingArchetypeNode = visitAggregateLeaves (
31293145 origType, substType, forExpansion,
31303146 /* isLeaf=*/
@@ -3139,6 +3155,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
31393155 " leaf of non-trivial BitwiseCopyable type that doesn't "
31403156 " conform to BitwiseCopyable!?" );
31413157
3158+ // An archetype may conform but be non-trivial (case (2)).
31423159 if (origTy.isTypeParameter ())
31433160 return false ;
31443161
@@ -3148,6 +3165,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
31483165 llvm::errs () << " Non-trivial type with _BitwiseCopyable conformance!?:\n "
31493166 << substType << " \n " ;
31503167 conformance.print (llvm::errs ());
3168+ llvm::errs () << " \n " ;
31513169 assert (false );
31523170 }
31533171 }
0 commit comments