10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
- #include " TypeChecker.h"
14
-
13
+ #include " swift/AST/LifetimeDependence.h"
15
14
#include " swift/AST/ASTContext.h"
16
15
#include " swift/AST/Decl.h"
17
- #include " swift/AST/LifetimeDependence.h"
16
+ #include " swift/AST/DiagnosticsSema.h"
17
+ #include " swift/AST/Module.h"
18
18
#include " swift/AST/ParameterList.h"
19
19
#include " swift/AST/Type.h"
20
20
#include " swift/AST/TypeRepr.h"
@@ -165,13 +165,25 @@ static LifetimeDependenceKind getLifetimeDependenceKindFromDecl(
165
165
return LifetimeDependenceKind::Scope;
166
166
}
167
167
if (parsedLifetimeDependenceKind == ParsedLifetimeDependenceKind::Inherit) {
168
- // TODO: assert that this can happen only on deserialized decls
168
+ // TODO: assert that this can happen in SIL tests
169
169
return LifetimeDependenceKind::Inherit;
170
170
}
171
171
return paramType->isEscapable () ? LifetimeDependenceKind::Scope
172
172
: LifetimeDependenceKind::Inherit;
173
173
}
174
174
175
+ static bool isBitwiseCopyable (Type type, ModuleDecl *mod, ASTContext &ctx) {
176
+ if (!ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
177
+ return false ;
178
+ }
179
+ auto *bitwiseCopyableProtocol =
180
+ ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
181
+ if (!bitwiseCopyableProtocol) {
182
+ return false ;
183
+ }
184
+ return (bool )(mod->checkConformance (type, bitwiseCopyableProtocol));
185
+ }
186
+
175
187
std::optional<LifetimeDependenceInfo>
176
188
LifetimeDependenceInfo::fromTypeRepr (AbstractFunctionDecl *afd) {
177
189
auto *dc = afd->getDeclContext ();
@@ -205,14 +217,9 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd) {
205
217
// error.
206
218
// TODO: Diagnose ~Escapable types are always non-trivial in SIL.
207
219
if (paramType->isEscapable ()) {
208
- if (ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
209
- auto *bitwiseCopyableProtocol =
210
- ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
211
- if (bitwiseCopyableProtocol &&
212
- mod->checkConformance (paramType, bitwiseCopyableProtocol)) {
213
- diags.diagnose (loc, diag::lifetime_dependence_on_bitwise_copyable);
214
- return true ;
215
- }
220
+ if (isBitwiseCopyable (paramType, mod, ctx)) {
221
+ diags.diagnose (loc, diag::lifetime_dependence_on_bitwise_copyable);
222
+ return true ;
216
223
}
217
224
}
218
225
@@ -277,7 +284,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd) {
277
284
}
278
285
case LifetimeDependenceSpecifier::SpecifierKind::Ordered: {
279
286
auto index = specifier.getIndex ();
280
- if (index > afd->getParameters ()->size ()) {
287
+ if (index >= afd->getParameters ()->size ()) {
281
288
diags.diagnose (specifier.getLoc (),
282
289
diag::lifetime_dependence_invalid_param_index, index);
283
290
return std::nullopt;
@@ -426,16 +433,11 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
426
433
if (!cd && afd->hasImplicitSelfDecl ()) {
427
434
Type selfTypeInContext = dc->getSelfTypeInContext ();
428
435
if (selfTypeInContext->isEscapable ()) {
429
- if (ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
430
- auto *bitwiseCopyableProtocol =
431
- ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
432
- if (bitwiseCopyableProtocol &&
433
- mod->checkConformance (selfTypeInContext, bitwiseCopyableProtocol)) {
436
+ if (isBitwiseCopyable (selfTypeInContext, mod, ctx)) {
434
437
diags.diagnose (
435
438
returnLoc,
436
439
diag::lifetime_dependence_method_escapable_bitwisecopyable_self);
437
440
return std::nullopt;
438
- }
439
441
}
440
442
}
441
443
auto kind = getLifetimeDependenceKindFromType (selfTypeInContext);
@@ -455,23 +457,26 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
455
457
unsigned paramIndex = 0 ;
456
458
bool hasParamError = false ;
457
459
for (auto *param : *afd->getParameters ()) {
458
- SWIFT_DEFER {
459
- paramIndex++;
460
- };
460
+ SWIFT_DEFER { paramIndex++; };
461
461
Type paramTypeInContext =
462
462
afd->mapTypeIntoContext (param->getInterfaceType ());
463
463
if (paramTypeInContext->hasError ()) {
464
464
hasParamError = true ;
465
465
continue ;
466
466
}
467
467
auto paramOwnership = param->getValueOwnership ();
468
- if (paramTypeInContext->isEscapable () && paramOwnership == ValueOwnership::Default) {
469
- continue ;
468
+ if (paramTypeInContext->isEscapable ()) {
469
+ if (isBitwiseCopyable (paramTypeInContext, mod, ctx)) {
470
+ continue ;
471
+ }
472
+ if (paramOwnership == ValueOwnership::Default) {
473
+ continue ;
474
+ }
470
475
}
471
476
472
477
auto lifetimeKind = getLifetimeDependenceKindFromType (paramTypeInContext);
473
- if (!isLifetimeDependenceCompatibleWithOwnership (lifetimeKind, paramOwnership,
474
- afd)) {
478
+ if (!isLifetimeDependenceCompatibleWithOwnership (lifetimeKind,
479
+ paramOwnership, afd)) {
475
480
continue ;
476
481
}
477
482
if (candidateParam) {
@@ -496,12 +501,11 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
496
501
if (cd && afd->isImplicit ()) {
497
502
diags.diagnose (returnLoc,
498
503
diag::lifetime_dependence_cannot_infer_no_candidates,
499
- " on implicit initializer" );
504
+ " on implicit initializer" );
500
505
return std::nullopt;
501
506
}
502
507
diags.diagnose (returnLoc,
503
- diag::lifetime_dependence_cannot_infer_no_candidates,
504
- " " );
508
+ diag::lifetime_dependence_cannot_infer_no_candidates, " " );
505
509
return std::nullopt;
506
510
}
507
511
return lifetimeDependenceInfo;
0 commit comments