@@ -252,7 +252,7 @@ void LifetimeDependenceInfo::getConcatenatedData(
252
252
}
253
253
254
254
class LifetimeDependenceChecker {
255
- AbstractFunctionDecl *afd ;
255
+ ValueDecl *decl ;
256
256
257
257
DeclContext *dc;
258
258
ASTContext &ctx;
@@ -273,9 +273,8 @@ class LifetimeDependenceChecker {
273
273
bool performedDiagnostics = false ;
274
274
275
275
public:
276
- LifetimeDependenceChecker (AbstractFunctionDecl *afd):
277
- afd (afd), dc(afd->getDeclContext ()), ctx(dc->getASTContext ())
278
- {
276
+ LifetimeDependenceChecker (AbstractFunctionDecl *afd)
277
+ : decl(afd), dc(afd->getDeclContext ()), ctx(dc->getASTContext ()) {
279
278
auto resultTypeRepr = afd->getResultTypeRepr ();
280
279
returnLoc = resultTypeRepr ? resultTypeRepr->getLoc () : afd->getLoc ();
281
280
@@ -292,13 +291,14 @@ class LifetimeDependenceChecker {
292
291
if (lifetimeDependencies.empty ()) {
293
292
return std::nullopt;
294
293
}
295
- return afd ->getASTContext ().AllocateCopy (lifetimeDependencies);
294
+ return decl ->getASTContext ().AllocateCopy (lifetimeDependencies);
296
295
}
297
296
298
297
std::optional<llvm::ArrayRef<LifetimeDependenceInfo>> checkFuncDecl () {
299
- assert (isa<FuncDecl>(afd ) || isa<ConstructorDecl>(afd ));
298
+ assert (isa<FuncDecl>(decl ) || isa<ConstructorDecl>(decl ));
300
299
assert (lifetimeDependencies.empty ());
301
300
301
+ auto *afd = cast<AbstractFunctionDecl>(decl);
302
302
// Handle Builtins first because, even though Builtins require
303
303
// LifetimeDependence, we don't force the experimental feature
304
304
// to be enabled when importing the Builtin module.
@@ -367,9 +367,7 @@ class LifetimeDependenceChecker {
367
367
return ctx.Diags .diagnose (decl, Diagnostic (id, std::move (args)...));
368
368
}
369
369
370
- bool isInit () const {
371
- return isa<ConstructorDecl>(afd);
372
- }
370
+ bool isInit () const { return isa<ConstructorDecl>(decl); }
373
371
374
372
// For initializers, the implicit self parameter is ignored and instead shows
375
373
// up as the result type.
@@ -381,11 +379,13 @@ class LifetimeDependenceChecker {
381
379
// the extra formal self parameter, a dependency targeting the formal result
382
380
// index would incorrectly target the SIL metatype parameter.
383
381
bool hasImplicitSelfParam () const {
382
+ auto *afd = cast<AbstractFunctionDecl>(decl);
384
383
return !isInit () && afd->hasImplicitSelfDecl ();
385
384
}
386
385
387
386
// In SIL, implicit initializers and accessors become explicit.
388
387
bool isImplicitOrSIL () const {
388
+ auto *afd = cast<AbstractFunctionDecl>(decl);
389
389
if (afd->isImplicit ()) {
390
390
return true ;
391
391
}
@@ -404,7 +404,7 @@ class LifetimeDependenceChecker {
404
404
bool isInterfaceFile () const {
405
405
// TODO: remove this check once all compilers that are rev-locked to the
406
406
// stdlib print the 'copy' dependence kind in the interface (Aug '25)
407
- if (auto *sf = afd ->getParentSourceFile ()) {
407
+ if (auto *sf = decl-> getDeclContext () ->getParentSourceFile ()) {
408
408
if (sf->Kind == SourceFileKind::Interface) {
409
409
return true ;
410
410
}
@@ -418,6 +418,7 @@ class LifetimeDependenceChecker {
418
418
}
419
419
420
420
std::string diagnosticQualifier () const {
421
+ auto *afd = cast<AbstractFunctionDecl>(decl);
421
422
if (afd->isImplicit ()) {
422
423
if (isInit ()) {
423
424
return " an implicit initializer" ;
@@ -462,6 +463,7 @@ class LifetimeDependenceChecker {
462
463
// initializers, the inout self parameter is actually considered the result
463
464
// type so is not handled here.
464
465
void diagnoseMissingSelfDependencies (DiagID diagID) {
466
+ auto *afd = cast<AbstractFunctionDecl>(decl);
465
467
if (!hasImplicitSelfParam ()) {
466
468
return ;
467
469
}
@@ -482,6 +484,7 @@ class LifetimeDependenceChecker {
482
484
}
483
485
484
486
void diagnoseMissingInoutDependencies (DiagID diagID) {
487
+ auto *afd = cast<AbstractFunctionDecl>(decl);
485
488
unsigned paramIndex = 0 ;
486
489
for (auto *param : *afd->getParameters ()) {
487
490
SWIFT_DEFER { paramIndex++; };
@@ -528,6 +531,7 @@ class LifetimeDependenceChecker {
528
531
529
532
bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
530
533
ValueOwnership ownership) const {
534
+ auto *afd = cast<AbstractFunctionDecl>(decl);
531
535
if (kind == LifetimeDependenceKind::Inherit) {
532
536
return true ;
533
537
}
@@ -568,6 +572,7 @@ class LifetimeDependenceChecker {
568
572
};
569
573
570
574
TargetDeps createDeps (unsigned targetIndex) {
575
+ auto *afd = cast<AbstractFunctionDecl>(decl);
571
576
unsigned capacity = afd->hasImplicitSelfDecl ()
572
577
? (afd->getParameters ()->size () + 1 )
573
578
: afd->getParameters ()->size ();
@@ -598,6 +603,7 @@ class LifetimeDependenceChecker {
598
603
}
599
604
600
605
Type getResultOrYield () const {
606
+ auto *afd = cast<AbstractFunctionDecl>(decl);
601
607
if (auto *accessor = dyn_cast<AccessorDecl>(afd)) {
602
608
if (accessor->isCoroutine ()) {
603
609
auto yieldTyInContext = accessor->mapTypeIntoContext (
@@ -617,11 +623,12 @@ class LifetimeDependenceChecker {
617
623
618
624
std::optional<LifetimeDependenceKind>
619
625
getDependenceKindFromDescriptor (LifetimeDescriptor descriptor,
620
- ParamDecl *decl) {
626
+ ParamDecl *paramDecl) {
627
+ auto *afd = cast<AbstractFunctionDecl>(decl);
621
628
auto loc = descriptor.getLoc ();
622
- auto type = decl ->getTypeInContext ();
629
+ auto type = paramDecl ->getTypeInContext ();
623
630
auto parsedLifetimeKind = descriptor.getParsedLifetimeDependenceKind ();
624
- auto ownership = decl ->getValueOwnership ();
631
+ auto ownership = paramDecl ->getValueOwnership ();
625
632
auto loweredOwnership = ownership != ValueOwnership::Default
626
633
? ownership
627
634
: getLoweredOwnership (afd);
@@ -703,6 +710,7 @@ class LifetimeDependenceChecker {
703
710
// Finds the ParamDecl* and its index from a LifetimeDescriptor
704
711
std::optional<std::pair<ParamDecl *, unsigned >>
705
712
getParamDeclFromDescriptor (LifetimeDescriptor descriptor) {
713
+ auto *afd = cast<AbstractFunctionDecl>(decl);
706
714
switch (descriptor.getDescriptorKind ()) {
707
715
case LifetimeDescriptor::DescriptorKind::Named: {
708
716
unsigned paramIndex = 0 ;
@@ -751,6 +759,7 @@ class LifetimeDependenceChecker {
751
759
}
752
760
753
761
std::optional<ArrayRef<LifetimeDependenceInfo>> checkAttribute () {
762
+ auto *afd = cast<AbstractFunctionDecl>(decl);
754
763
SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
755
764
llvm::SmallSet<unsigned , 1 > lifetimeDependentTargets;
756
765
auto lifetimeAttrs = afd->getAttrs ().getAttributes <LifetimeAttr>();
@@ -775,6 +784,7 @@ class LifetimeDependenceChecker {
775
784
776
785
std::optional<LifetimeDependenceInfo>
777
786
checkAttributeEntry (LifetimeEntry *entry) {
787
+ auto *afd = cast<AbstractFunctionDecl>(decl);
778
788
auto capacity = afd->hasImplicitSelfDecl ()
779
789
? (afd->getParameters ()->size () + 1 )
780
790
: afd->getParameters ()->size ();
@@ -896,6 +906,7 @@ class LifetimeDependenceChecker {
896
906
// / If the current function is a mutating method and 'self' is non-Escapable,
897
907
// / return 'self's ParamDecl.
898
908
bool isMutatingNonEscapableSelf () {
909
+ auto *afd = cast<AbstractFunctionDecl>(decl);
899
910
if (!hasImplicitSelfParam ())
900
911
return false ;
901
912
@@ -912,6 +923,7 @@ class LifetimeDependenceChecker {
912
923
913
924
// Infer method dependence: result depends on self. This includes _modify.
914
925
void inferNonEscapableResultOnSelf () {
926
+ auto *afd = cast<AbstractFunctionDecl>(decl);
915
927
Type selfTypeInContext = dc->getSelfTypeInContext ();
916
928
if (selfTypeInContext->hasError ()) {
917
929
return ;
@@ -963,6 +975,7 @@ class LifetimeDependenceChecker {
963
975
964
976
std::optional<LifetimeDependenceKind>
965
977
inferLifetimeDependenceKind (Type sourceType, ValueOwnership ownership) {
978
+ auto *afd = cast<AbstractFunctionDecl>(decl);
966
979
if (!sourceType->isEscapable ()) {
967
980
return LifetimeDependenceKind::Inherit;
968
981
}
@@ -985,6 +998,7 @@ class LifetimeDependenceChecker {
985
998
// to an implicit setter, because the implementation is simply an assignment
986
999
// to stored property.
987
1000
void inferImplicitInit () {
1001
+ auto *afd = cast<AbstractFunctionDecl>(decl);
988
1002
if (afd->getParameters ()->size () == 0 ) {
989
1003
// Empty ~Escapable types can be implicitly initialized without any
990
1004
// dependencies. In SIL, implicit initializers become explicit. Set
@@ -1024,6 +1038,7 @@ class LifetimeDependenceChecker {
1024
1038
// inference if any exist, infer scoped dependency, or infer no
1025
1039
// dependency. Implicit setters for Escapable properties are not inferred.
1026
1040
void inferNonEscapableResultOnParam () {
1041
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1027
1042
// This is only called when there is no 'self' argument that can be the
1028
1043
// source of a dependence.
1029
1044
assert (!hasImplicitSelfParam ());
@@ -1073,6 +1088,7 @@ class LifetimeDependenceChecker {
1073
1088
// Lazy inference for .swiftinterface backward compatibility and
1074
1089
// experimentation. Inference cases can be added but not removed.
1075
1090
void lazillyInferNonEscapableResultOnParam () {
1091
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1076
1092
std::optional<unsigned > candidateParamIndex;
1077
1093
std::optional<LifetimeDependenceKind> candidateLifetimeKind;
1078
1094
unsigned paramIndex = 0 ;
@@ -1119,6 +1135,7 @@ class LifetimeDependenceChecker {
1119
1135
// Infer a mutating 'self' dependency when 'self' is non-Escapable and the
1120
1136
// result is 'void'.
1121
1137
void inferMutatingSelf () {
1138
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1122
1139
if (!isMutatingNonEscapableSelf ()) {
1123
1140
return ;
1124
1141
}
@@ -1144,6 +1161,7 @@ class LifetimeDependenceChecker {
1144
1161
1145
1162
// Infer a mutating accessor's non-Escapable 'self' dependencies.
1146
1163
void inferMutatingAccessor (AccessorDecl *accessor) {
1164
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1147
1165
if (!isImplicitOrSIL () && !useLazyInference ()) {
1148
1166
// Explicit setters require explicit lifetime dependencies.
1149
1167
return ;
@@ -1231,6 +1249,7 @@ class LifetimeDependenceChecker {
1231
1249
// Do not issue any diagnostics. This inference is triggered even when the
1232
1250
// feature is disabled!
1233
1251
void inferInoutParams () {
1252
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1234
1253
if (isMutatingNonEscapableSelf ()) {
1235
1254
return ;
1236
1255
}
@@ -1263,6 +1282,7 @@ class LifetimeDependenceChecker {
1263
1282
}
1264
1283
1265
1284
void inferUnambiguousInoutParams () {
1285
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1266
1286
if (afd->getParameters ()->size () != 1 ) {
1267
1287
return ;
1268
1288
}
@@ -1280,6 +1300,7 @@ class LifetimeDependenceChecker {
1280
1300
}
1281
1301
1282
1302
void inferBuiltin () {
1303
+ auto *afd = cast<AbstractFunctionDecl>(decl);
1283
1304
// Normal inout parameter inference works for most generic Builtins.
1284
1305
inferUnambiguousInoutParams ();
1285
1306
if (!lifetimeDependencies.empty ()) {
0 commit comments