@@ -54,6 +54,10 @@ llvm::cl::opt<bool> TypeLoweringForceOpaqueValueLowering(
54
54
llvm::cl::desc(" Force TypeLowering to behave as if building with opaque "
55
55
" values enabled" ));
56
56
57
+ llvm::cl::opt<bool > TypeLoweringDisableVerification (
58
+ " type-lowering-disable-verification" , llvm::cl::init(false ),
59
+ llvm::cl::desc(" Disable the asserts-only verification of lowerings" ));
60
+
57
61
namespace {
58
62
// / A CRTP type visitor for deciding whether the metatype for a type
59
63
// / is a singleton type, i.e. whether there can only ever be one
@@ -2945,6 +2949,9 @@ void TypeConverter::verifyLowering(const TypeLowering &lowering,
2945
2949
AbstractionPattern origType,
2946
2950
CanType substType,
2947
2951
TypeExpansionContext forExpansion) {
2952
+ if (TypeLoweringDisableVerification) {
2953
+ return ;
2954
+ }
2948
2955
verifyLexicalLowering (lowering, origType, substType, forExpansion);
2949
2956
verifyTrivialLowering (lowering, origType, substType, forExpansion);
2950
2957
}
@@ -3049,7 +3056,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3049
3056
3050
3057
if (lowering.isTrivial () && !conformance) {
3051
3058
// A trivial type can lack a conformance in a few cases:
3052
- // (1) containing or being a resilient type
3059
+ // (1) containing or being a public, non-frozen type
3053
3060
// (2) containing or being a generic type which doesn't conform
3054
3061
// unconditionally but in this particular instantiation is trivial
3055
3062
// (3) being a special type that's not worth forming a conformance for
@@ -3064,6 +3071,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3064
3071
// unowned(unsafe) var o: AnyObject
3065
3072
// }
3066
3073
// (5) being defined in a different module
3074
+ // (6) being defined in a module built from interface
3067
3075
bool hasNoNonconformingNode = visitAggregateLeaves (
3068
3076
origType, substType, forExpansion,
3069
3077
/* isLeafAggregate=*/
@@ -3081,12 +3089,22 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3081
3089
return true ;
3082
3090
}
3083
3091
3084
- // Resilient trivial types may not conform (case (1)).
3085
- if (nominal->isResilient ())
3092
+ // Public, non-frozen trivial types may not conform (case (1)).
3093
+ if (nominal
3094
+ ->getFormalAccessScope (/* useDC=*/ nullptr ,
3095
+ /* treatUsableFromInlineAsPublic=*/ true )
3096
+ .isPublic ())
3086
3097
return true ;
3087
3098
3099
+ auto *module = nominal->getModuleContext ();
3100
+
3101
+ // Types in modules built from interfaces may not conform (case (6)).
3102
+ if (module && module ->isBuiltFromInterface ()) {
3103
+ return false ;
3104
+ }
3105
+
3088
3106
// Trivial types from other modules may not conform (case (5)).
3089
- return nominal-> getModuleContext () != &M;
3107
+ return module != &M;
3090
3108
},
3091
3109
/* visit=*/
3092
3110
[&](auto ty, auto origTy, auto *field, auto index) -> bool {
@@ -3141,12 +3159,22 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3141
3159
return false ;
3142
3160
}
3143
3161
3144
- // Resilient trivial types may not conform (case (1)).
3145
- if (nominal->isResilient ())
3162
+ // Public, non-frozen trivial types may not conform (case (1)).
3163
+ if (nominal
3164
+ ->getFormalAccessScope (/* useDC=*/ nullptr ,
3165
+ /* treatUsableFromInlineAsPublic=*/ true )
3166
+ .isPublic ())
3167
+ return false ;
3168
+
3169
+ auto *module = nominal->getModuleContext ();
3170
+
3171
+ // Types in modules built from interfaces may not conform (case (6)).
3172
+ if (module && module ->isBuiltFromInterface ()) {
3146
3173
return false ;
3174
+ }
3147
3175
3148
3176
// Trivial types from other modules may not conform (case (5)).
3149
- return nominal-> getModuleContext () == &M;
3177
+ return module == &M;
3150
3178
});
3151
3179
if (hasNoNonconformingNode) {
3152
3180
llvm::errs () << " Trivial type without a BitwiseCopyable conformance!?:\n "
@@ -3159,10 +3187,19 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3159
3187
if (!lowering.isTrivial () && conformance) {
3160
3188
// A non-trivial type can have a conformance in one case:
3161
3189
// (1) contains a conforming archetype
3190
+ // (2) is resilient with minimal expansion
3162
3191
bool hasNoConformingArchetypeNode = visitAggregateLeaves (
3163
3192
origType, substType, forExpansion,
3164
3193
/* isLeaf=*/
3165
3194
[&](auto ty, auto origTy, auto *field, auto index) -> bool {
3195
+ // A resilient type that's with minimal expansion may be non-trivial
3196
+ // but still conform (case (2)).
3197
+ auto *nominal = ty.getAnyNominal ();
3198
+ if (nominal && nominal->isResilient () &&
3199
+ forExpansion.getResilienceExpansion () ==
3200
+ ResilienceExpansion::Minimal) {
3201
+ return true ;
3202
+ }
3166
3203
// Walk into every aggregate.
3167
3204
return false ;
3168
3205
},
@@ -3173,7 +3210,16 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
3173
3210
" leaf of non-trivial BitwiseCopyable type that doesn't "
3174
3211
" conform to BitwiseCopyable!?" );
3175
3212
3176
- // An archetype may conform but be non-trivial (case (2)).
3213
+ // A resilient type that's with minimal expansion may be non-trivial
3214
+ // but still conform (case (2)).
3215
+ auto *nominal = ty.getAnyNominal ();
3216
+ if (nominal && nominal->isResilient () &&
3217
+ forExpansion.getResilienceExpansion () ==
3218
+ ResilienceExpansion::Minimal) {
3219
+ return false ;
3220
+ }
3221
+
3222
+ // An archetype may conform but be non-trivial (case (1)).
3177
3223
if (origTy.isTypeParameter ())
3178
3224
return false ;
3179
3225
0 commit comments