1010//
1111// ===----------------------------------------------------------------------===//
1212
13- #include " swift/AST/LifetimeDependence.h"
1413#include " TypeChecker.h"
14+
1515#include " swift/AST/ASTContext.h"
1616#include " swift/AST/Decl.h"
17+ #include " swift/AST/LifetimeDependence.h"
1718#include " swift/AST/ParameterList.h"
1819#include " swift/AST/Type.h"
1920#include " swift/AST/TypeRepr.h"
@@ -62,6 +63,28 @@ void LifetimeDependenceInfo::Profile(llvm::FoldingSetNodeID &ID) const {
6263 }
6364}
6465
66+ LifetimeDependenceInfo LifetimeDependenceInfo::getForParamIndex (
67+ AbstractFunctionDecl *afd, unsigned index, ValueOwnership ownership) {
68+ auto *dc = afd->getDeclContext ();
69+ auto &ctx = dc->getASTContext ();
70+ unsigned capacity = afd->getParameters ()->size () + 1 ;
71+ auto indexSubset = IndexSubset::get (ctx, capacity, {index});
72+ if (ownership == ValueOwnership::Owned) {
73+ return LifetimeDependenceInfo{/* inheritLifetimeParamIndices*/ indexSubset,
74+ /* borrowLifetimeParamIndices*/ nullptr ,
75+ /* mutateLifetimeParamIndices*/ nullptr };
76+ }
77+ if (ownership == ValueOwnership::Shared) {
78+ return LifetimeDependenceInfo{/* inheritLifetimeParamIndices*/ nullptr ,
79+ /* borrowLifetimeParamIndices*/ indexSubset,
80+ /* mutateLifetimeParamIndices*/ nullptr };
81+ }
82+ assert (ownership == ValueOwnership::InOut);
83+ return LifetimeDependenceInfo{/* inheritLifetimeParamIndices*/ nullptr ,
84+ /* borrowLifetimeParamIndices*/ nullptr ,
85+ /* mutateLifetimeParamIndices*/ indexSubset};
86+ }
87+
6588llvm::Optional<LifetimeDependenceInfo>
6689LifetimeDependenceInfo::fromTypeRepr (AbstractFunctionDecl *afd, Type resultType,
6790 bool allowIndex) {
@@ -81,8 +104,8 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
81104 ValueOwnership ownership) {
82105 auto loc = specifier.getLoc ();
83106 auto kind = specifier.getLifetimeDependenceKind ();
84-
85- if (resultType ->isEscapable ()) {
107+ Type resultTypeInContext = afd-> mapTypeIntoContext (resultType);
108+ if (resultTypeInContext ->isEscapable ()) {
86109 diags.diagnose (loc, diag::lifetime_dependence_invalid_return_type);
87110 return true ;
88111 }
@@ -187,6 +210,78 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
187210 IndexSubset::get (ctx, mutateLifetimeParamIndices));
188211}
189212
213+ llvm::Optional<LifetimeDependenceInfo>
214+ LifetimeDependenceInfo::infer (AbstractFunctionDecl *afd, Type resultType) {
215+ auto *dc = afd->getDeclContext ();
216+ auto &ctx = dc->getASTContext ();
217+
218+ if (!ctx.LangOpts .hasFeature (Feature::NonescapableTypes)) {
219+ return llvm::None;
220+ }
221+
222+ auto &diags = ctx.Diags ;
223+ auto returnTypeRepr = afd->getResultTypeRepr ();
224+ auto returnLoc = returnTypeRepr->getLoc ();
225+ Type returnTyInContext = afd->mapTypeIntoContext (resultType);
226+
227+ if (returnTyInContext->isEscapable ()) {
228+ return llvm::None;
229+ }
230+ if (afd->getAttrs ().hasAttribute <UnsafeNonEscapableResultAttr>()) {
231+ return llvm::None;
232+ }
233+
234+ if (afd->hasImplicitSelfDecl ()) {
235+ auto ownership = afd->getImplicitSelfDecl ()->getValueOwnership ();
236+ if (ownership == ValueOwnership::Default) {
237+ diags.diagnose (
238+ returnLoc,
239+ diag::
240+ lifetime_dependence_cannot_infer_wo_ownership_modifier_on_method);
241+ return llvm::None;
242+ }
243+ return LifetimeDependenceInfo::getForParamIndex (afd, /* selfIndex*/ 0 ,
244+ ownership);
245+ }
246+
247+ LifetimeDependenceInfo lifetimeDependenceInfo;
248+ ParamDecl *candidateParam = nullptr ;
249+ unsigned paramIndex = 0 ;
250+ bool hasParamError = false ;
251+ for (auto *param : *afd->getParameters ()) {
252+ Type paramTypeInContext =
253+ afd->mapTypeIntoContext (param->getInterfaceType ());
254+
255+ if (paramTypeInContext->hasError ()) {
256+ hasParamError = true ;
257+ continue ;
258+ }
259+ if (param->getValueOwnership () == ValueOwnership::Default) {
260+ continue ;
261+ }
262+
263+ if (!paramTypeInContext->isEscapable () ||
264+ paramTypeInContext->isNoncopyable ()) {
265+ if (candidateParam) {
266+ diags.diagnose (
267+ returnLoc,
268+ diag::lifetime_dependence_cannot_infer_wo_ambiguous_candidate);
269+ return llvm::None;
270+ }
271+ candidateParam = param;
272+ lifetimeDependenceInfo = LifetimeDependenceInfo::getForParamIndex (
273+ afd, paramIndex + 1 , param->getValueOwnership ());
274+ }
275+ paramIndex++;
276+ }
277+ if (!candidateParam && !hasParamError) {
278+ diags.diagnose (returnLoc,
279+ diag::lifetime_dependence_cannot_infer_no_candidates);
280+ return llvm::None;
281+ }
282+ return lifetimeDependenceInfo;
283+ }
284+
190285llvm::Optional<LifetimeDependenceInfo>
191286LifetimeDependenceInfo::get (AbstractFunctionDecl *afd, Type resultType,
192287 bool allowIndex) {
@@ -195,7 +290,7 @@ LifetimeDependenceInfo::get(AbstractFunctionDecl *afd, Type resultType,
195290 return llvm::None;
196291 }
197292 if (!isa<LifetimeDependentReturnTypeRepr>(returnTypeRepr)) {
198- return llvm::None ;
293+ return LifetimeDependenceInfo::infer (afd, resultType) ;
199294 }
200295 return LifetimeDependenceInfo::fromTypeRepr (afd, resultType, allowIndex);
201296}
0 commit comments