@@ -2793,6 +2793,17 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
2793
2793
}
2794
2794
2795
2795
namespace 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
+
2796
2807
// Arguments:
2797
2808
// - value: whose type will be printed
2798
2809
// Dumps:
@@ -3028,67 +3039,78 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3028
3039
auto conformance = M.checkConformance (substType, bitwiseCopyableProtocol);
3029
3040
3030
3041
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
+ // }
3033
3057
bool hasNoNonconformingNode = visitAggregateLeaves (
3034
3058
origType, substType, forExpansion,
3035
- /* isLeaf =*/
3059
+ /* isLeafAggregate =*/
3036
3060
[&](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.
3039
3061
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 .
3042
3064
if (!nominal)
3043
3065
return false ;
3044
3066
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 ()) {
3049
3071
return true ;
3050
3072
}
3051
3073
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 ();
3056
3076
},
3057
3077
/* visit=*/
3058
3078
[&](auto ty, auto origTy, auto *field, auto index) -> bool {
3059
3079
// Return false to indicate seeing a leaf which justifies the type
3060
3080
// being trivial but not conforming to BitwiseCopyable.
3061
3081
3082
+ auto isTopLevel = !field;
3083
+
3062
3084
// A BitwiseCopyable conformer appearing within its layout doesn't
3063
3085
// explain why substType doesn't itself conform.
3064
3086
if (M.checkConformance (ty, bitwiseCopyableProtocol))
3065
3087
return true ;
3066
3088
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;
3076
3099
}
3077
3100
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)) .
3080
3103
auto rst = dyn_cast<ReferenceStorageType>(ty);
3081
3104
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;
3087
3108
}
3088
3109
3089
3110
auto *nominal = ty.getAnyNominal ();
3090
3111
3091
- // Non-nominal types are trivial iff conforming.
3112
+ // Non-nominal types (besides case (3) handled above) are trivial iff
3113
+ // conforming.
3092
3114
if (!nominal) {
3093
3115
llvm::errs ()
3094
3116
<< " Non-nominal type without conformance to _BitwiseCopyable:\n "
@@ -3099,20 +3121,14 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3099
3121
return true ;
3100
3122
}
3101
3123
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 ()) {
3106
3127
return false ;
3107
3128
}
3108
3129
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 ();
3116
3132
});
3117
3133
if (hasNoNonconformingNode) {
3118
3134
llvm::errs () << " Trivial type without a BitwiseCopyable conformance!?:\n "
@@ -3123,8 +3139,8 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3123
3139
}
3124
3140
3125
3141
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
3128
3144
bool hasNoConformingArchetypeNode = visitAggregateLeaves (
3129
3145
origType, substType, forExpansion,
3130
3146
/* isLeaf=*/
@@ -3139,6 +3155,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3139
3155
" leaf of non-trivial BitwiseCopyable type that doesn't "
3140
3156
" conform to BitwiseCopyable!?" );
3141
3157
3158
+ // An archetype may conform but be non-trivial (case (2)).
3142
3159
if (origTy.isTypeParameter ())
3143
3160
return false ;
3144
3161
@@ -3148,6 +3165,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3148
3165
llvm::errs () << " Non-trivial type with _BitwiseCopyable conformance!?:\n "
3149
3166
<< substType << " \n " ;
3150
3167
conformance.print (llvm::errs ());
3168
+ llvm::errs () << " \n " ;
3151
3169
assert (false );
3152
3170
}
3153
3171
}
0 commit comments