@@ -80,6 +80,8 @@ getLifetimeDependenceKindFromType(Type sourceType) {
8080 return LifetimeDependenceKind::Inherit;
8181}
8282
83+ // Warning: this is incorrect for Setter 'newValue' parameters. It should only
84+ // be called for a Setter's 'self'.
8385static ValueOwnership getLoweredOwnership (AbstractFunctionDecl *afd) {
8486 if (isa<ConstructorDecl>(afd)) {
8587 return ValueOwnership::Owned;
@@ -437,6 +439,13 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
437439 return std::nullopt ;
438440 }
439441
442+ // Setters infer 'self' dependence on 'newValue'.
443+ if (auto accessor = dyn_cast<AccessorDecl>(afd)) {
444+ if (accessor->getAccessorKind () == AccessorKind::Set) {
445+ return inferSetter (accessor);
446+ }
447+ }
448+
440449 if (hasEscapableResultOrYield (afd)) {
441450 return std::nullopt ;
442451 }
@@ -542,6 +551,53 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
542551 afd, resultIndex, *candidateParamIndex, *candidateLifetimeKind);
543552}
544553
554+ // / Infer LifetimeDependenceInfo on a setter where 'self' is nonescapable.
555+ std::optional<LifetimeDependenceInfo> LifetimeDependenceInfo::inferSetter (
556+ AbstractFunctionDecl *afd) {
557+
558+ auto *param = afd->getParameters ()->get (0 );
559+ Type paramTypeInContext =
560+ afd->mapTypeIntoContext (param->getInterfaceType ());
561+ if (paramTypeInContext->hasError ()) {
562+ return std::nullopt ;
563+ }
564+ if (paramTypeInContext->isEscapable ()) {
565+ return std::nullopt ;
566+ }
567+ auto kind = getLifetimeDependenceKindFromType (paramTypeInContext);
568+ return LifetimeDependenceInfo::getForIndex (
569+ afd, /* selfIndex */ afd->getParameters ()->size (), 0 , kind);
570+ }
571+
572+ // / Infer LifetimeDependenceInfo on a mutating method where 'self' is
573+ // / nonescapable and the result is 'void'. For now, we'll assume that 'self'
574+ // / depends on a single nonescapable argument.
575+ std::optional<LifetimeDependenceInfo> LifetimeDependenceInfo::inferMutatingSelf (
576+ AbstractFunctionDecl *afd) {
577+ std::optional<LifetimeDependenceInfo> dep;
578+ for (unsigned paramIndex : range (afd->getParameters ()->size ())) {
579+ auto *param = afd->getParameters ()->get (paramIndex);
580+ Type paramTypeInContext =
581+ afd->mapTypeIntoContext (param->getInterfaceType ());
582+ if (paramTypeInContext->hasError ()) {
583+ continue ;
584+ }
585+ if (paramTypeInContext->isEscapable ()) {
586+ continue ;
587+ }
588+ if (dep) {
589+ // Don't infer dependence on multiple nonescapable parameters. We may want
590+ // to do this in the future if dependsOn(self: arg1, arg2) syntax is too
591+ // cumbersome.
592+ return std::nullopt ;
593+ }
594+ int selfIndex = afd->getParameters ()->size ();
595+ dep = LifetimeDependenceInfo::getForIndex (
596+ afd, selfIndex, paramIndex, LifetimeDependenceKind::Inherit);
597+ }
598+ return dep;
599+ }
600+
545601std::optional<llvm::ArrayRef<LifetimeDependenceInfo>>
546602LifetimeDependenceInfo::get (AbstractFunctionDecl *afd) {
547603 if (!afd->getASTContext ().LangOpts .hasFeature (Feature::NonescapableTypes)) {
0 commit comments