@@ -716,46 +716,60 @@ std::optional<LifetimeDependenceInfo> LifetimeDependenceInfo::inferMutatingSelf(
716
716
return dep;
717
717
}
718
718
719
+ static bool hasDependsOn (AbstractFunctionDecl *afd) {
720
+ if (isa_and_nonnull<LifetimeDependentTypeRepr>(afd->getResultTypeRepr ())) {
721
+ return true ;
722
+ }
723
+ for (auto param : *afd->getParameters ()) {
724
+ if (isa_and_nonnull<LifetimeDependentTypeRepr>(param->getTypeRepr ())) {
725
+ return true ;
726
+ }
727
+ }
728
+ return false ;
729
+ }
730
+
719
731
std::optional<llvm::ArrayRef<LifetimeDependenceInfo>>
720
732
LifetimeDependenceInfo::get (AbstractFunctionDecl *afd) {
721
733
assert (isa<FuncDecl>(afd) || isa<ConstructorDecl>(afd));
722
734
735
+ // Get lifetime dependence from @lifetime attribute.
723
736
if (afd->getAttrs ().hasAttribute <LifetimeAttr>()) {
724
737
return LifetimeDependenceInfo::fromLifetimeAttribute (afd);
725
738
}
726
739
727
740
SmallVector<LifetimeDependenceInfo> lifetimeDependencies;
728
-
729
- for (unsigned targetIndex : indices (*afd->getParameters ())) {
730
- auto *param = (*afd->getParameters ())[targetIndex];
731
- auto paramType =
732
- afd->mapTypeIntoContext (param->toFunctionParam ().getParameterType ());
733
- if (auto result = LifetimeDependenceInfo::fromDependsOn (
734
- afd, param->getTypeRepr (), paramType, targetIndex)) {
735
- lifetimeDependencies.push_back (*result);
741
+ // Get lifetime dependence from dependsOn type modifier if present.
742
+ if (hasDependsOn (afd)) {
743
+ for (unsigned targetIndex : indices (*afd->getParameters ())) {
744
+ auto *param = (*afd->getParameters ())[targetIndex];
745
+ auto paramType =
746
+ afd->mapTypeIntoContext (param->toFunctionParam ().getParameterType ());
747
+ auto paramDependence = LifetimeDependenceInfo::fromDependsOn (
748
+ afd, param->getTypeRepr (), paramType, targetIndex);
749
+ if (paramDependence) {
750
+ lifetimeDependencies.push_back (*paramDependence);
751
+ }
736
752
}
737
- }
738
-
739
- std::optional<LifetimeDependenceInfo> resultDependence;
740
753
741
- if (auto *lifetimeTypeRepr = dyn_cast_or_null<LifetimeDependentTypeRepr>(
742
- afd->getResultTypeRepr ())) {
743
- resultDependence = LifetimeDependenceInfo::fromDependsOn (
744
- afd, lifetimeTypeRepr, getResultOrYield (afd),
754
+ auto resultDependence = LifetimeDependenceInfo::fromDependsOn (
755
+ afd, afd->getResultTypeRepr (), getResultOrYield (afd),
745
756
afd->hasImplicitSelfDecl () ? afd->getParameters ()->size () + 1
746
757
: afd->getParameters ()->size ());
747
- } else {
748
- resultDependence = LifetimeDependenceInfo::infer (afd);
749
- }
750
-
751
- if (resultDependence.has_value ()) {
752
- lifetimeDependencies.push_back (*resultDependence);
758
+ if (resultDependence) {
759
+ lifetimeDependencies.push_back (*resultDependence);
760
+ }
761
+ if (lifetimeDependencies.empty ()) {
762
+ return std::nullopt;
763
+ }
764
+ return afd->getASTContext ().AllocateCopy (lifetimeDependencies);
753
765
}
754
766
755
- if (lifetimeDependencies.empty ()) {
767
+ // Infer lifetime dependence if the function has a ~Escapable result.
768
+ auto resultDependence = LifetimeDependenceInfo::infer (afd);
769
+ if (!resultDependence.has_value ()) {
756
770
return std::nullopt;
757
771
}
758
-
772
+ lifetimeDependencies. push_back (*resultDependence);
759
773
return afd->getASTContext ().AllocateCopy (lifetimeDependencies);
760
774
}
761
775
0 commit comments