@@ -3543,6 +3543,12 @@ TypeAliasType *TypeAliasType::get(TypeAliasDecl *typealias, Type parent,
3543
3543
auto &ctx = underlying->getASTContext ();
3544
3544
auto arena = getArena (properties);
3545
3545
3546
+ // Typealiases can't meaningfully be unsafe; it's the underlying type that
3547
+ // matters.
3548
+ properties.removeIsUnsafe ();
3549
+ if (underlying->isUnsafe ())
3550
+ properties |= RecursiveTypeProperties::IsUnsafe;
3551
+
3546
3552
// Profile the type.
3547
3553
llvm::FoldingSetNodeID id;
3548
3554
TypeAliasType::Profile (id, typealias, parent, genericArgs, underlying);
@@ -4190,6 +4196,54 @@ void UnboundGenericType::Profile(llvm::FoldingSetNodeID &ID,
4190
4196
ID.AddPointer (Parent.getPointer ());
4191
4197
}
4192
4198
4199
+ // / The safety of a parent type does not have an impact on a nested type within
4200
+ // / it. This produces the recursive properties of a given type that should
4201
+ // / be propagated to a nested type, which won't include any "IsUnsafe" bit
4202
+ // / determined based on the declaration itself.
4203
+ static RecursiveTypeProperties getRecursivePropertiesAsParent (Type type) {
4204
+ if (!type)
4205
+ return RecursiveTypeProperties ();
4206
+
4207
+ // We only need to do anything interesting at all for unsafe types.
4208
+ auto properties = type->getRecursiveProperties ();
4209
+ if (!properties.isUnsafe ())
4210
+ return properties;
4211
+
4212
+ if (auto nominal = type->getAnyNominal ()) {
4213
+ // If the nominal wasn't itself unsafe, then we got the unsafety from
4214
+ // something else (e.g., a generic argument), so it won't change.
4215
+ if (nominal->getExplicitSafety () != ExplicitSafety::Unsafe)
4216
+ return properties;
4217
+ }
4218
+
4219
+ // Drop the "unsafe" bit. We have to recompute it without considering the
4220
+ // enclosing nominal type.
4221
+ properties.removeIsUnsafe ();
4222
+
4223
+ // Check generic arguments of parent types.
4224
+ while (type) {
4225
+ // Merge from the generic arguments.
4226
+ if (auto boundGeneric = type->getAs <BoundGenericType>()) {
4227
+ for (auto genericArg : boundGeneric->getGenericArgs ())
4228
+ properties |= genericArg->getRecursiveProperties ();
4229
+ }
4230
+
4231
+ if (auto nominalOrBound = type->getAs <NominalOrBoundGenericNominalType>()) {
4232
+ type = nominalOrBound->getParent ();
4233
+ continue ;
4234
+ }
4235
+
4236
+ if (auto unbound = type->getAs <UnboundGenericType>()) {
4237
+ type = unbound->getParent ();
4238
+ continue ;
4239
+ }
4240
+
4241
+ break ;
4242
+ };
4243
+
4244
+ return properties;
4245
+ }
4246
+
4193
4247
UnboundGenericType *UnboundGenericType::
4194
4248
get (GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
4195
4249
llvm::FoldingSetNodeID ID;
@@ -4198,7 +4252,7 @@ get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
4198
4252
RecursiveTypeProperties properties;
4199
4253
if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
4200
4254
properties |= RecursiveTypeProperties::IsUnsafe;
4201
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4255
+ properties |= getRecursivePropertiesAsParent (Parent );
4202
4256
4203
4257
auto arena = getArena (properties);
4204
4258
@@ -4252,7 +4306,7 @@ BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl,
4252
4306
RecursiveTypeProperties properties;
4253
4307
if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
4254
4308
properties |= RecursiveTypeProperties::IsUnsafe;
4255
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4309
+ properties |= getRecursivePropertiesAsParent (Parent );
4256
4310
for (Type Arg : GenericArgs) {
4257
4311
properties |= Arg->getRecursiveProperties ();
4258
4312
}
@@ -4335,7 +4389,7 @@ EnumType *EnumType::get(EnumDecl *D, Type Parent, const ASTContext &C) {
4335
4389
RecursiveTypeProperties properties;
4336
4390
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
4337
4391
properties |= RecursiveTypeProperties::IsUnsafe;
4338
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4392
+ properties |= getRecursivePropertiesAsParent (Parent );
4339
4393
auto arena = getArena (properties);
4340
4394
4341
4395
auto *&known = C.getImpl ().getArena (arena).EnumTypes [{D, Parent}];
@@ -4353,7 +4407,7 @@ StructType *StructType::get(StructDecl *D, Type Parent, const ASTContext &C) {
4353
4407
RecursiveTypeProperties properties;
4354
4408
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
4355
4409
properties |= RecursiveTypeProperties::IsUnsafe;
4356
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4410
+ properties |= getRecursivePropertiesAsParent (Parent );
4357
4411
auto arena = getArena (properties);
4358
4412
4359
4413
auto *&known = C.getImpl ().getArena (arena).StructTypes [{D, Parent}];
@@ -4371,7 +4425,7 @@ ClassType *ClassType::get(ClassDecl *D, Type Parent, const ASTContext &C) {
4371
4425
RecursiveTypeProperties properties;
4372
4426
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
4373
4427
properties |= RecursiveTypeProperties::IsUnsafe;
4374
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4428
+ properties |= getRecursivePropertiesAsParent (Parent );
4375
4429
auto arena = getArena (properties);
4376
4430
4377
4431
auto *&known = C.getImpl ().getArena (arena).ClassTypes [{D, Parent}];
@@ -5538,7 +5592,7 @@ ProtocolType *ProtocolType::get(ProtocolDecl *D, Type Parent,
5538
5592
RecursiveTypeProperties properties;
5539
5593
if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
5540
5594
properties |= RecursiveTypeProperties::IsUnsafe;
5541
- if (Parent) properties |= Parent-> getRecursiveProperties ( );
5595
+ properties |= getRecursivePropertiesAsParent (Parent );
5542
5596
auto arena = getArena (properties);
5543
5597
5544
5598
auto *&known = C.getImpl ().getArena (arena).ProtocolTypes [{D, Parent}];
0 commit comments