@@ -3543,6 +3543,12 @@ TypeAliasType *TypeAliasType::get(TypeAliasDecl *typealias, Type parent,
35433543 auto &ctx = underlying->getASTContext ();
35443544 auto arena = getArena (properties);
35453545
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+
35463552 // Profile the type.
35473553 llvm::FoldingSetNodeID id;
35483554 TypeAliasType::Profile (id, typealias, parent, genericArgs, underlying);
@@ -4190,6 +4196,54 @@ void UnboundGenericType::Profile(llvm::FoldingSetNodeID &ID,
41904196 ID.AddPointer (Parent.getPointer ());
41914197}
41924198
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+
41934247UnboundGenericType *UnboundGenericType::
41944248get (GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
41954249 llvm::FoldingSetNodeID ID;
@@ -4198,7 +4252,7 @@ get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
41984252 RecursiveTypeProperties properties;
41994253 if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
42004254 properties |= RecursiveTypeProperties::IsUnsafe;
4201- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4255+ properties |= getRecursivePropertiesAsParent (Parent );
42024256
42034257 auto arena = getArena (properties);
42044258
@@ -4252,7 +4306,7 @@ BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl,
42524306 RecursiveTypeProperties properties;
42534307 if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
42544308 properties |= RecursiveTypeProperties::IsUnsafe;
4255- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4309+ properties |= getRecursivePropertiesAsParent (Parent );
42564310 for (Type Arg : GenericArgs) {
42574311 properties |= Arg->getRecursiveProperties ();
42584312 }
@@ -4335,7 +4389,7 @@ EnumType *EnumType::get(EnumDecl *D, Type Parent, const ASTContext &C) {
43354389 RecursiveTypeProperties properties;
43364390 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
43374391 properties |= RecursiveTypeProperties::IsUnsafe;
4338- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4392+ properties |= getRecursivePropertiesAsParent (Parent );
43394393 auto arena = getArena (properties);
43404394
43414395 auto *&known = C.getImpl ().getArena (arena).EnumTypes [{D, Parent}];
@@ -4353,7 +4407,7 @@ StructType *StructType::get(StructDecl *D, Type Parent, const ASTContext &C) {
43534407 RecursiveTypeProperties properties;
43544408 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
43554409 properties |= RecursiveTypeProperties::IsUnsafe;
4356- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4410+ properties |= getRecursivePropertiesAsParent (Parent );
43574411 auto arena = getArena (properties);
43584412
43594413 auto *&known = C.getImpl ().getArena (arena).StructTypes [{D, Parent}];
@@ -4371,7 +4425,7 @@ ClassType *ClassType::get(ClassDecl *D, Type Parent, const ASTContext &C) {
43714425 RecursiveTypeProperties properties;
43724426 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
43734427 properties |= RecursiveTypeProperties::IsUnsafe;
4374- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4428+ properties |= getRecursivePropertiesAsParent (Parent );
43754429 auto arena = getArena (properties);
43764430
43774431 auto *&known = C.getImpl ().getArena (arena).ClassTypes [{D, Parent}];
@@ -5538,7 +5592,7 @@ ProtocolType *ProtocolType::get(ProtocolDecl *D, Type Parent,
55385592 RecursiveTypeProperties properties;
55395593 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
55405594 properties |= RecursiveTypeProperties::IsUnsafe;
5541- if (Parent) properties |= Parent-> getRecursiveProperties ( );
5595+ properties |= getRecursivePropertiesAsParent (Parent );
55425596 auto arena = getArena (properties);
55435597
55445598 auto *&known = C.getImpl ().getArena (arena).ProtocolTypes [{D, Parent}];
0 commit comments