@@ -4190,6 +4190,55 @@ void UnboundGenericType::Profile(llvm::FoldingSetNodeID &ID,
4190
4190
ID.AddPointer (Parent.getPointer ());
4191
4191
}
4192
4192
4193
+ // / The safety of a parent type does not have an impact on a nested type within
4194
+ // / it. This produces the recursive properties of a given type that should
4195
+ // / be propagated to a nested type, which won't include any "IsUnsafe" bit
4196
+ // / determined based on the declaration itself.
4197
+ static RecursiveTypeProperties getRecursivePropertiesAsParent (Type type) {
4198
+ if (!type)
4199
+ return RecursiveTypeProperties ();
4200
+
4201
+ // We only need to do anything interesting at all for unsafe types.
4202
+ auto properties = type->getRecursiveProperties ();
4203
+ if (!properties.isUnsafe ())
4204
+ return properties;
4205
+
4206
+ if (auto nominal = type->getAnyNominal ()) {
4207
+ // If the nominal wasn't itself unsafe, then we got the unsafety from
4208
+ // something else (e.g., a generic argument), so it won't change.
4209
+ if (nominal->getExplicitSafety () != ExplicitSafety::Unsafe)
4210
+ return properties;
4211
+ }
4212
+
4213
+ // Drop the "unsafe" bit. We have to recompute it without considering the
4214
+ // enclosing nominal type.
4215
+ properties = RecursiveTypeProperties (
4216
+ properties.getBits () & ~static_cast <unsigned >(RecursiveTypeProperties::IsUnsafe));
4217
+
4218
+ // Check generic arguments of parent types.
4219
+ while (type) {
4220
+ // Merge from the generic arguments.
4221
+ if (auto boundGeneric = type->getAs <BoundGenericType>()) {
4222
+ for (auto genericArg : boundGeneric->getGenericArgs ())
4223
+ properties |= genericArg->getRecursiveProperties ();
4224
+ }
4225
+
4226
+ if (auto nominalOrBound = type->getAs <NominalOrBoundGenericNominalType>()) {
4227
+ type = nominalOrBound->getParent ();
4228
+ continue ;
4229
+ }
4230
+
4231
+ if (auto unbound = type->getAs <UnboundGenericType>()) {
4232
+ type = unbound->getParent ();
4233
+ continue ;
4234
+ }
4235
+
4236
+ break ;
4237
+ };
4238
+
4239
+ return properties;
4240
+ }
4241
+
4193
4242
UnboundGenericType *UnboundGenericType::
4194
4243
get (GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
4195
4244
llvm::FoldingSetNodeID ID;
@@ -4198,7 +4247,7 @@ get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
4198
4247
RecursiveTypeProperties properties;
4199
4248
if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
4200
4249
properties |= RecursiveTypeProperties::IsUnsafe;
4201
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4250
+ properties |= getRecursivePropertiesAsParent (Parent );
4202
4251
4203
4252
auto arena = getArena (properties);
4204
4253
@@ -4252,7 +4301,7 @@ BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl,
4252
4301
RecursiveTypeProperties properties;
4253
4302
if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
4254
4303
properties |= RecursiveTypeProperties::IsUnsafe;
4255
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4304
+ properties |= getRecursivePropertiesAsParent (Parent );
4256
4305
for (Type Arg : GenericArgs) {
4257
4306
properties |= Arg->getRecursiveProperties ();
4258
4307
}
@@ -4335,7 +4384,7 @@ EnumType *EnumType::get(EnumDecl *D, Type Parent, const ASTContext &C) {
4335
4384
RecursiveTypeProperties properties;
4336
4385
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
4337
4386
properties |= RecursiveTypeProperties::IsUnsafe;
4338
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4387
+ properties |= getRecursivePropertiesAsParent (Parent );
4339
4388
auto arena = getArena (properties);
4340
4389
4341
4390
auto *&known = C.getImpl ().getArena (arena).EnumTypes [{D, Parent}];
@@ -4353,7 +4402,7 @@ StructType *StructType::get(StructDecl *D, Type Parent, const ASTContext &C) {
4353
4402
RecursiveTypeProperties properties;
4354
4403
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
4355
4404
properties |= RecursiveTypeProperties::IsUnsafe;
4356
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4405
+ properties |= getRecursivePropertiesAsParent (Parent );
4357
4406
auto arena = getArena (properties);
4358
4407
4359
4408
auto *&known = C.getImpl ().getArena (arena).StructTypes [{D, Parent}];
@@ -4371,7 +4420,7 @@ ClassType *ClassType::get(ClassDecl *D, Type Parent, const ASTContext &C) {
4371
4420
RecursiveTypeProperties properties;
4372
4421
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
4373
4422
properties |= RecursiveTypeProperties::IsUnsafe;
4374
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4423
+ properties |= getRecursivePropertiesAsParent (Parent );
4375
4424
auto arena = getArena (properties);
4376
4425
4377
4426
auto *&known = C.getImpl ().getArena (arena).ClassTypes [{D, Parent}];
@@ -5538,7 +5587,7 @@ ProtocolType *ProtocolType::get(ProtocolDecl *D, Type Parent,
5538
5587
RecursiveTypeProperties properties;
5539
5588
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
5540
5589
properties |= RecursiveTypeProperties::IsUnsafe;
5541
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
5590
+ properties |= getRecursivePropertiesAsParent (Parent );
5542
5591
auto arena = getArena (properties);
5543
5592
5544
5593
auto *&known = C.getImpl ().getArena (arena).ProtocolTypes [{D, Parent}];
0 commit comments