27
27
28
28
using namespace swift ;
29
29
30
- // / A uniquely-typed boolean to reduce the chances of accidentally inverting
31
- // / a check.
32
- enum class DowngradeToWarning : bool {
33
- No,
34
- Yes
35
- };
36
-
37
30
bool TypeChecker::diagnoseInlinableDeclRef (SourceLoc loc,
38
- ConcreteDeclRef declRef,
39
- const DeclContext *DC,
40
- FragileFunctionKind Kind) {
41
- assert (Kind.kind != FragileFunctionKind::None);
31
+ const ValueDecl *D,
32
+ ExportContext where) {
33
+ auto fragileKind = where.getFragileFunctionKind ();
34
+ if (fragileKind.kind == FragileFunctionKind::None)
35
+ return false ;
42
36
43
- const ValueDecl *D = declRef.getDecl ();
44
37
// Do some important fast-path checks that apply to all cases.
45
38
46
39
// Type parameters are OK.
47
40
if (isa<AbstractTypeParamDecl>(D))
48
41
return false ;
49
42
50
43
// Check whether the declaration is accessible.
51
- if (diagnoseInlinableDeclRefAccess (loc, D, DC, Kind ))
44
+ if (diagnoseInlinableDeclRefAccess (loc, D, where ))
52
45
return true ;
53
46
54
47
// Check whether the declaration comes from a publically-imported module.
55
48
// Skip this check for accessors because the associated property or subscript
56
49
// will also be checked, and will provide a better error message.
57
50
if (!isa<AccessorDecl>(D))
58
- if (diagnoseDeclRefExportability (loc, declRef, DC, Kind ))
51
+ if (diagnoseDeclRefExportability (loc, D, where ))
59
52
return true ;
60
53
61
54
return false ;
62
55
}
63
56
64
57
bool TypeChecker::diagnoseInlinableDeclRefAccess (SourceLoc loc,
65
- const ValueDecl *D,
66
- const DeclContext *DC,
67
- FragileFunctionKind Kind) {
68
- assert (Kind.kind != FragileFunctionKind::None);
58
+ const ValueDecl *D,
59
+ ExportContext where) {
60
+ auto *DC = where.getDeclContext ();
61
+ auto fragileKind = where.getFragileFunctionKind ();
62
+ assert (fragileKind.kind != FragileFunctionKind::None);
69
63
70
64
// Local declarations are OK.
71
65
if (D->getDeclContext ()->isLocalContext ())
72
66
return false ;
73
67
74
68
// Public declarations or SPI used from SPI are OK.
75
69
if (D->getFormalAccessScope (/* useDC=*/ nullptr ,
76
- Kind .allowUsableFromInline ).isPublic () &&
70
+ fragileKind .allowUsableFromInline ).isPublic () &&
77
71
!(D->isSPI () && !DC->getInnermostDeclarationDeclContext ()->isSPI ()))
78
72
return false ;
79
73
@@ -133,10 +127,10 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
133
127
loc, diagID,
134
128
D->getDescriptiveKind (), diagName,
135
129
D->getFormalAccessScope ().accessLevelForDiagnostics (),
136
- static_cast <unsigned >(Kind .kind ),
130
+ static_cast <unsigned >(fragileKind .kind ),
137
131
isAccessor);
138
132
139
- if (Kind .allowUsableFromInline ) {
133
+ if (fragileKind .allowUsableFromInline ) {
140
134
Context.Diags .diagnose (D, diag::resilience_decl_declared_here,
141
135
D->getDescriptiveKind (), diagName, isAccessor);
142
136
} else {
@@ -147,99 +141,74 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
147
141
return (downgradeToWarning == DowngradeToWarning::No);
148
142
}
149
143
150
- static bool diagnoseDeclExportability (SourceLoc loc, const ValueDecl *D,
151
- const SourceFile &userSF,
152
- const DeclContext *userDC,
153
- FragileFunctionKind fragileKind) {
154
- assert (fragileKind.kind != FragileFunctionKind::None);
144
+ bool
145
+ TypeChecker::diagnoseDeclRefExportability (SourceLoc loc,
146
+ const ValueDecl *D,
147
+ ExportContext where) {
148
+ if (!where.mustOnlyReferenceExportedDecls ())
149
+ return false ;
155
150
156
151
auto definingModule = D->getModuleContext ();
157
152
153
+ auto downgradeToWarning = DowngradeToWarning::No;
154
+
158
155
auto originKind = getDisallowedOriginKind (
159
- D, userSF, userDC-> getInnermostDeclarationDeclContext () );
156
+ D, where, downgradeToWarning );
160
157
if (originKind == DisallowedOriginKind::None)
161
158
return false ;
162
159
163
- // TODO: different diagnostics
164
160
ASTContext &ctx = definingModule->getASTContext ();
165
- ctx.Diags .diagnose (loc, diag::inlinable_decl_ref_from_hidden_module,
166
- D->getDescriptiveKind (), D->getName (),
167
- static_cast <unsigned >(fragileKind.kind ),
168
- definingModule->getName (),
169
- static_cast <unsigned >(originKind));
170
- return true ;
171
- }
172
161
173
- static bool
174
- diagnoseGenericArgumentsExportability (SourceLoc loc,
175
- SubstitutionMap subs,
176
- const SourceFile &userSF,
177
- const DeclContext *userDC) {
178
- bool hadAnyIssues = false ;
179
- for (ProtocolConformanceRef conformance : subs.getConformances ()) {
180
- if (!conformance.isConcrete ())
181
- continue ;
182
- const ProtocolConformance *concreteConf = conformance.getConcrete ();
183
-
184
- SubstitutionMap subConformanceSubs =
185
- concreteConf->getSubstitutions (userSF.getParentModule ());
186
- diagnoseGenericArgumentsExportability (loc, subConformanceSubs, userSF, userDC);
187
-
188
- const RootProtocolConformance *rootConf =
189
- concreteConf->getRootConformance ();
190
- ModuleDecl *M = rootConf->getDeclContext ()->getParentModule ();
191
-
192
- auto originKind = getDisallowedOriginKind (
193
- rootConf->getDeclContext ()->getAsDecl (),
194
- userSF, userDC->getInnermostDeclarationDeclContext ());
195
- if (originKind == DisallowedOriginKind::None)
196
- continue ;
197
-
198
- ASTContext &ctx = M->getASTContext ();
199
- ctx.Diags .diagnose (loc, diag::conformance_from_implementation_only_module,
200
- rootConf->getType (),
201
- rootConf->getProtocol ()->getName (), 0 , M->getName (),
162
+ auto fragileKind = where.getFragileFunctionKind ();
163
+ auto reason = where.getExportabilityReason ();
164
+
165
+ if (fragileKind.kind == FragileFunctionKind::None) {
166
+ auto errorOrWarning = downgradeToWarning == DowngradeToWarning::Yes?
167
+ diag::decl_from_hidden_module_warn:
168
+ diag::decl_from_hidden_module;
169
+ ctx.Diags .diagnose (loc, errorOrWarning,
170
+ D->getDescriptiveKind (),
171
+ D->getName (),
172
+ static_cast <unsigned >(*reason),
173
+ definingModule->getName (),
202
174
static_cast <unsigned >(originKind));
203
- hadAnyIssues = true ;
204
- }
205
- return hadAnyIssues;
206
- }
207
175
208
- void TypeChecker::diagnoseGenericTypeExportability (SourceLoc Loc, Type T,
209
- const DeclContext *DC) {
210
- const SourceFile *SF = DC->getParentSourceFile ();
211
- if (!SF)
212
- return ;
213
-
214
- // FIXME: It would be nice to highlight just the part of the type that's
215
- // problematic, but unfortunately the TypeRepr doesn't have the
216
- // information we need and the Type doesn't easily map back to it.
217
- if (auto *BGT = dyn_cast<BoundGenericType>(T.getPointer ())) {
218
- ModuleDecl *useModule = SF->getParentModule ();
219
- auto subs = T->getContextSubstitutionMap (useModule, BGT->getDecl ());
220
- (void )diagnoseGenericArgumentsExportability (Loc, subs, *SF, DC);
221
- } else if (auto *TAT = dyn_cast<TypeAliasType>(T.getPointer ())) {
222
- auto subs = TAT->getSubstitutionMap ();
223
- (void )diagnoseGenericArgumentsExportability (Loc, subs, *SF, DC);
176
+ D->diagnose (diag::kind_declared_here, DescriptiveDeclKind::Type);
177
+ } else {
178
+ ctx.Diags .diagnose (loc, diag::inlinable_decl_ref_from_hidden_module,
179
+ D->getDescriptiveKind (), D->getName (),
180
+ static_cast <unsigned >(fragileKind.kind ),
181
+ definingModule->getName (),
182
+ static_cast <unsigned >(originKind));
224
183
}
184
+ return true ;
225
185
}
226
186
227
187
bool
228
- TypeChecker::diagnoseDeclRefExportability (SourceLoc loc,
229
- ConcreteDeclRef declRef,
230
- const DeclContext *DC,
231
- FragileFunctionKind fragileKind) {
232
- // We're only interested in diagnosing uses from source files.
233
- auto userSF = DC->getParentSourceFile ();
234
- if (!userSF)
188
+ TypeChecker::diagnoseConformanceExportability (SourceLoc loc,
189
+ const RootProtocolConformance *rootConf,
190
+ ExportContext where) {
191
+ if (!where.mustOnlyReferenceExportedDecls ())
235
192
return false ;
236
193
237
- const ValueDecl *D = declRef.getDecl ();
238
- if (diagnoseDeclExportability (loc, D, *userSF, DC, fragileKind))
239
- return true ;
240
- if (diagnoseGenericArgumentsExportability (loc, declRef.getSubstitutions (),
241
- *userSF, DC)) {
242
- return true ;
243
- }
244
- return false ;
194
+ auto originKind = getDisallowedOriginKind (
195
+ rootConf->getDeclContext ()->getAsDecl (),
196
+ where);
197
+ if (originKind == DisallowedOriginKind::None)
198
+ return false ;
199
+
200
+ ModuleDecl *M = rootConf->getDeclContext ()->getParentModule ();
201
+ ASTContext &ctx = M->getASTContext ();
202
+
203
+ auto reason = where.getExportabilityReason ();
204
+ if (!reason.hasValue ())
205
+ reason = ExportabilityReason::General;
206
+
207
+ ctx.Diags .diagnose (loc, diag::conformance_from_implementation_only_module,
208
+ rootConf->getType (),
209
+ rootConf->getProtocol ()->getName (),
210
+ static_cast <unsigned >(*reason),
211
+ M->getName (),
212
+ static_cast <unsigned >(originKind));
213
+ return true ;
245
214
}
0 commit comments