@@ -136,38 +136,47 @@ bool TypeChecker::diagnoseInlineableDeclRef(SourceLoc loc,
136
136
}
137
137
138
138
void TypeChecker::diagnoseResilientConstructor (ConstructorDecl *ctor) {
139
- auto nominalDecl = ctor->getDeclContext ()
140
- ->getAsNominalTypeOrNominalTypeExtensionContext ();
139
+ const DeclContext *containingContext = ctor->getDeclContext ();
140
+ const NominalTypeDecl *nominalDecl =
141
+ containingContext->getAsNominalTypeOrNominalTypeExtensionContext ();
141
142
142
- // These restrictions only apply to concrete types, and not protocol
143
- // extensions.
144
- if (isa<ProtocolDecl>(nominalDecl))
143
+ // These restrictions only apply to structs and classes.
144
+ if (isa<ProtocolDecl>(nominalDecl) || isa<EnumDecl>(nominalDecl))
145
145
return ;
146
146
147
- bool isDelegating =
148
- (ctor->getDelegatingOrChainedInitKind (&Diags) ==
149
- ConstructorDecl::BodyInitKind::Delegating);
150
-
151
- if (!isDelegating &&
152
- !nominalDecl->hasFixedLayout (ctor->getParentModule (),
153
- ctor->getResilienceExpansion ())) {
154
- if (ctor->getResilienceExpansion () == ResilienceExpansion::Minimal) {
155
- // An @_inlineable designated initializer defined in a resilient type
156
- // cannot initialize stored properties directly, and must chain to
157
- // another initializer.
158
- diagnose (ctor->getLoc (),
159
- isa<ClassDecl>(nominalDecl)
160
- ? diag::class_designated_init_inlineable_resilient
161
- : diag::designated_init_inlineable_resilient,
162
- nominalDecl->getDeclaredInterfaceType (),
163
- getFragileFunctionKind (ctor));
164
- } else {
165
- // A designated initializer defined on an extension of a resilient
166
- // type from a different resilience domain cannot initialize stored
167
- // properties directly, and must chain to another initializer.
168
- diagnose (ctor->getLoc (),
169
- diag::designated_init_in_extension_resilient,
170
- nominalDecl->getDeclaredInterfaceType ());
171
- }
147
+ if (ctor->getDelegatingOrChainedInitKind (&Diags) ==
148
+ ConstructorDecl::BodyInitKind::Delegating) {
149
+ return ;
150
+ }
151
+
152
+ // An initializer defined on an extension of a struct from another module
153
+ // cannot initialize stored properties directly, and must chain to another
154
+ // initializer.
155
+ if (isa<ExtensionDecl>(containingContext) &&
156
+ nominalDecl->getParentModule () != containingContext->getParentModule ()) {
157
+ // Classes already can't have designated initializers in extensions, and
158
+ // we diagnose this elsewhere.
159
+ if (isa<ClassDecl>(nominalDecl))
160
+ return ;
161
+
162
+ diagnose (ctor->getLoc (),
163
+ diag::designated_init_in_cross_module_extension,
164
+ nominalDecl->getDescriptiveKind (),
165
+ nominalDecl->getDeclaredInterfaceType (),
166
+ nominalDecl->getParentModule ()->getName ());
167
+ return ;
168
+ }
169
+
170
+ // Within the module, we're only concerned about inlinable initializers on
171
+ // non-fixed-layout types.
172
+ if (ctor->getResilienceExpansion () == ResilienceExpansion::Minimal &&
173
+ !nominalDecl->hasFixedLayout ()) {
174
+ // An @_inlineable designated initializer defined in a resilient type
175
+ // cannot initialize stored properties directly, and must chain to
176
+ // another initializer.
177
+ diagnose (ctor->getLoc (), diag::designated_init_inlineable_resilient,
178
+ isa<ClassDecl>(nominalDecl),
179
+ nominalDecl->getDeclaredInterfaceType (),
180
+ getFragileFunctionKind (ctor));
172
181
}
173
182
}
0 commit comments