@@ -4190,6 +4190,55 @@ void UnboundGenericType::Profile(llvm::FoldingSetNodeID &ID,
41904190 ID.AddPointer (Parent.getPointer ());
41914191}
41924192
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+
41934242UnboundGenericType *UnboundGenericType::
41944243get (GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
41954244 llvm::FoldingSetNodeID ID;
@@ -4198,7 +4247,7 @@ get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) {
41984247 RecursiveTypeProperties properties;
41994248 if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
42004249 properties |= RecursiveTypeProperties::IsUnsafe;
4201- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4250+ properties |= getRecursivePropertiesAsParent (Parent );
42024251
42034252 auto arena = getArena (properties);
42044253
@@ -4252,7 +4301,7 @@ BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl,
42524301 RecursiveTypeProperties properties;
42534302 if (TheDecl->getExplicitSafety () == ExplicitSafety::Unsafe)
42544303 properties |= RecursiveTypeProperties::IsUnsafe;
4255- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4304+ properties |= getRecursivePropertiesAsParent (Parent );
42564305 for (Type Arg : GenericArgs) {
42574306 properties |= Arg->getRecursiveProperties ();
42584307 }
@@ -4335,7 +4384,7 @@ EnumType *EnumType::get(EnumDecl *D, Type Parent, const ASTContext &C) {
43354384 RecursiveTypeProperties properties;
43364385 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
43374386 properties |= RecursiveTypeProperties::IsUnsafe;
4338- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4387+ properties |= getRecursivePropertiesAsParent (Parent );
43394388 auto arena = getArena (properties);
43404389
43414390 auto *&known = C.getImpl ().getArena (arena).EnumTypes [{D, Parent}];
@@ -4353,7 +4402,7 @@ StructType *StructType::get(StructDecl *D, Type Parent, const ASTContext &C) {
43534402 RecursiveTypeProperties properties;
43544403 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
43554404 properties |= RecursiveTypeProperties::IsUnsafe;
4356- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4405+ properties |= getRecursivePropertiesAsParent (Parent );
43574406 auto arena = getArena (properties);
43584407
43594408 auto *&known = C.getImpl ().getArena (arena).StructTypes [{D, Parent}];
@@ -4371,7 +4420,7 @@ ClassType *ClassType::get(ClassDecl *D, Type Parent, const ASTContext &C) {
43714420 RecursiveTypeProperties properties;
43724421 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
43734422 properties |= RecursiveTypeProperties::IsUnsafe;
4374- if (Parent) properties |= Parent-> getRecursiveProperties ( );
4423+ properties |= getRecursivePropertiesAsParent (Parent );
43754424 auto arena = getArena (properties);
43764425
43774426 auto *&known = C.getImpl ().getArena (arena).ClassTypes [{D, Parent}];
@@ -5538,7 +5587,7 @@ ProtocolType *ProtocolType::get(ProtocolDecl *D, Type Parent,
55385587 RecursiveTypeProperties properties;
55395588 if (D->getExplicitSafety () == ExplicitSafety::Unsafe)
55405589 properties |= RecursiveTypeProperties::IsUnsafe;
5541- if (Parent) properties |= Parent-> getRecursiveProperties ( );
5590+ properties |= getRecursivePropertiesAsParent (Parent );
55425591 auto arena = getArena (properties);
55435592
55445593 auto *&known = C.getImpl ().getArena (arena).ProtocolTypes [{D, Parent}];
0 commit comments