@@ -107,6 +107,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
107107 bool allowIndex) {
108108 auto *dc = afd->getDeclContext ();
109109 auto &ctx = dc->getASTContext ();
110+ auto *mod = afd->getModuleContext ();
110111 auto &diags = ctx.Diags ;
111112 auto capacity = afd->getParameters ()->size () + 1 ;
112113 auto lifetimeDependentRepr =
@@ -116,7 +117,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
116117 SmallBitVector scopeLifetimeParamIndices (capacity);
117118
118119 auto updateLifetimeDependenceInfo = [&](LifetimeDependenceSpecifier specifier,
119- unsigned paramIndexToSet,
120+ unsigned paramIndexToSet, Type type,
120121 ValueOwnership ownership) {
121122 auto loc = specifier.getLoc ();
122123 auto kind = specifier.getLifetimeDependenceKind ();
@@ -148,6 +149,24 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
148149 getOwnershipSpelling (ownership));
149150 return true ;
150151 }
152+ if (kind == LifetimeDependenceKind::Consume ||
153+ kind == LifetimeDependenceKind::Copy) {
154+ if (type->isEscapable ()) {
155+ diags.diagnose (loc, diag::lifetime_dependence_cannot_use_infer,
156+ specifier.getLifetimeDependenceKindString ());
157+ return true ;
158+ }
159+ }
160+
161+ if (ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
162+ auto *bitwiseCopyableProtocol =
163+ ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
164+ if (bitwiseCopyableProtocol && mod->checkConformance (type, bitwiseCopyableProtocol)) {
165+ diags.diagnose (loc, diag::lifetime_dependence_on_bitwise_copyable);
166+ return true ;
167+ }
168+ }
169+
151170 if (inheritLifetimeParamIndices.test (paramIndexToSet) ||
152171 scopeLifetimeParamIndices.test (paramIndexToSet)) {
153172 diags.diagnose (loc, diag::lifetime_dependence_duplicate_param_id);
@@ -168,17 +187,20 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
168187 switch (specifier.getSpecifierKind ()) {
169188 case LifetimeDependenceSpecifier::SpecifierKind::Named: {
170189 bool foundParamName = false ;
171- unsigned paramIndexToSet = 1 ;
190+ unsigned paramIndex = 0 ;
172191 for (auto *param : *afd->getParameters ()) {
173192 if (param->getParameterName () == specifier.getName ()) {
174193 foundParamName = true ;
175- if (updateLifetimeDependenceInfo (specifier, paramIndexToSet,
176- param->getValueOwnership ())) {
194+ if (updateLifetimeDependenceInfo (
195+ specifier, paramIndex + 1 ,
196+ afd->mapTypeIntoContext (
197+ param->toFunctionParam ().getParameterType ()),
198+ param->getValueOwnership ())) {
177199 return llvm::None;
178200 }
179201 break ;
180202 }
181- paramIndexToSet ++;
203+ paramIndex ++;
182204 }
183205 if (!foundParamName) {
184206 diags.diagnose (specifier.getLoc (),
@@ -189,29 +211,23 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
189211 break ;
190212 }
191213 case LifetimeDependenceSpecifier::SpecifierKind::Ordered: {
192- auto paramIndex = specifier.getIndex ();
193- if (paramIndex > afd->getParameters ()->size ()) {
214+ auto index = specifier.getIndex ();
215+ if (index > afd->getParameters ()->size ()) {
194216 diags.diagnose (specifier.getLoc (),
195- diag::lifetime_dependence_invalid_param_index,
196- paramIndex);
217+ diag::lifetime_dependence_invalid_param_index, index);
197218 return llvm::None;
198219 }
199- if (paramIndex == 0 ) {
200- if (!afd->hasImplicitSelfDecl ()) {
201- diags.diagnose (specifier.getLoc (),
202- diag::lifetime_dependence_invalid_self);
220+ if (index != 0 ) {
221+ auto param = afd->getParameters ()->get (index - 1 );
222+ auto ownership = param->getValueOwnership ();
223+ auto type = afd->mapTypeIntoContext (
224+ param->toFunctionParam ().getParameterType ());
225+ if (updateLifetimeDependenceInfo (specifier, index, type, ownership)) {
203226 return llvm::None;
204227 }
228+ break ;
205229 }
206- auto ownership =
207- paramIndex == 0
208- ? afd->getImplicitSelfDecl ()->getValueOwnership ()
209- : afd->getParameters ()->get (paramIndex - 1 )->getValueOwnership ();
210- if (updateLifetimeDependenceInfo (
211- specifier, /* paramIndexToSet*/ specifier.getIndex (), ownership)) {
212- return llvm::None;
213- }
214- break ;
230+ LLVM_FALLTHROUGH;
215231 }
216232 case LifetimeDependenceSpecifier::SpecifierKind::Self: {
217233 if (!afd->hasImplicitSelfDecl ()) {
@@ -221,6 +237,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
221237 }
222238 if (updateLifetimeDependenceInfo (
223239 specifier, /* selfIndex*/ 0 ,
240+ afd->getImplicitSelfDecl ()->getTypeInContext (),
224241 afd->getImplicitSelfDecl ()->getValueOwnership ())) {
225242 return llvm::None;
226243 }
@@ -293,19 +310,21 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
293310 if (param->getValueOwnership () == ValueOwnership::Default) {
294311 continue ;
295312 }
313+ if (param->getValueOwnership () == ValueOwnership::Owned &&
314+ paramTypeInContext->isEscapable ()) {
315+ continue ;
316+ }
296317
297- if (!paramTypeInContext->isEscapable () ||
298- paramTypeInContext->isNoncopyable ()) {
299- if (candidateParam) {
300- diags.diagnose (
301- returnLoc,
302- diag::lifetime_dependence_cannot_infer_wo_ambiguous_candidate);
303- return llvm::None;
304- }
305- candidateParam = param;
306- lifetimeDependenceInfo = LifetimeDependenceInfo::getForParamIndex (
307- afd, paramIndex + 1 , param->getValueOwnership ());
318+ if (candidateParam) {
319+ diags.diagnose (
320+ returnLoc,
321+ diag::lifetime_dependence_cannot_infer_ambiguous_candidate);
322+ return llvm::None;
308323 }
324+ candidateParam = param;
325+ lifetimeDependenceInfo = LifetimeDependenceInfo::getForParamIndex (
326+ afd, paramIndex + 1 , param->getValueOwnership ());
327+
309328 paramIndex++;
310329 }
311330 if (!candidateParam && !hasParamError) {
0 commit comments