1010//
1111// ===----------------------------------------------------------------------===//
1212
13- #include " TypeChecker.h"
14-
13+ #include " swift/AST/LifetimeDependence.h"
1514#include " swift/AST/ASTContext.h"
1615#include " swift/AST/Decl.h"
17- #include " swift/AST/LifetimeDependence.h"
16+ #include " swift/AST/DiagnosticsSema.h"
17+ #include " swift/AST/Module.h"
1818#include " swift/AST/ParameterList.h"
1919#include " swift/AST/Type.h"
2020#include " swift/AST/TypeRepr.h"
@@ -165,13 +165,25 @@ static LifetimeDependenceKind getLifetimeDependenceKindFromDecl(
165165 return LifetimeDependenceKind::Scope;
166166 }
167167 if (parsedLifetimeDependenceKind == ParsedLifetimeDependenceKind::Inherit) {
168- // TODO: assert that this can happen only on deserialized decls
168+ // TODO: assert that this can happen in SIL tests
169169 return LifetimeDependenceKind::Inherit;
170170 }
171171 return paramType->isEscapable () ? LifetimeDependenceKind::Scope
172172 : LifetimeDependenceKind::Inherit;
173173}
174174
175+ static bool isBitwiseCopyable (Type type, ModuleDecl *mod, ASTContext &ctx) {
176+ if (!ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
177+ return false ;
178+ }
179+ auto *bitwiseCopyableProtocol =
180+ ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
181+ if (!bitwiseCopyableProtocol) {
182+ return false ;
183+ }
184+ return (bool )(mod->checkConformance (type, bitwiseCopyableProtocol));
185+ }
186+
175187std::optional<LifetimeDependenceInfo>
176188LifetimeDependenceInfo::fromTypeRepr (AbstractFunctionDecl *afd) {
177189 auto *dc = afd->getDeclContext ();
@@ -205,14 +217,9 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd) {
205217 // error.
206218 // TODO: Diagnose ~Escapable types are always non-trivial in SIL.
207219 if (paramType->isEscapable ()) {
208- if (ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
209- auto *bitwiseCopyableProtocol =
210- ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
211- if (bitwiseCopyableProtocol &&
212- mod->checkConformance (paramType, bitwiseCopyableProtocol)) {
213- diags.diagnose (loc, diag::lifetime_dependence_on_bitwise_copyable);
214- return true ;
215- }
220+ if (isBitwiseCopyable (paramType, mod, ctx)) {
221+ diags.diagnose (loc, diag::lifetime_dependence_on_bitwise_copyable);
222+ return true ;
216223 }
217224 }
218225
@@ -277,7 +284,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd) {
277284 }
278285 case LifetimeDependenceSpecifier::SpecifierKind::Ordered: {
279286 auto index = specifier.getIndex ();
280- if (index > afd->getParameters ()->size ()) {
287+ if (index >= afd->getParameters ()->size ()) {
281288 diags.diagnose (specifier.getLoc (),
282289 diag::lifetime_dependence_invalid_param_index, index);
283290 return std::nullopt ;
@@ -426,16 +433,11 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
426433 if (!cd && afd->hasImplicitSelfDecl ()) {
427434 Type selfTypeInContext = dc->getSelfTypeInContext ();
428435 if (selfTypeInContext->isEscapable ()) {
429- if (ctx.LangOpts .hasFeature (Feature::BitwiseCopyable)) {
430- auto *bitwiseCopyableProtocol =
431- ctx.getProtocol (KnownProtocolKind::BitwiseCopyable);
432- if (bitwiseCopyableProtocol &&
433- mod->checkConformance (selfTypeInContext, bitwiseCopyableProtocol)) {
436+ if (isBitwiseCopyable (selfTypeInContext, mod, ctx)) {
434437 diags.diagnose (
435438 returnLoc,
436439 diag::lifetime_dependence_method_escapable_bitwisecopyable_self);
437440 return std::nullopt ;
438- }
439441 }
440442 }
441443 auto kind = getLifetimeDependenceKindFromType (selfTypeInContext);
@@ -455,23 +457,26 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
455457 unsigned paramIndex = 0 ;
456458 bool hasParamError = false ;
457459 for (auto *param : *afd->getParameters ()) {
458- SWIFT_DEFER {
459- paramIndex++;
460- };
460+ SWIFT_DEFER { paramIndex++; };
461461 Type paramTypeInContext =
462462 afd->mapTypeIntoContext (param->getInterfaceType ());
463463 if (paramTypeInContext->hasError ()) {
464464 hasParamError = true ;
465465 continue ;
466466 }
467467 auto paramOwnership = param->getValueOwnership ();
468- if (paramTypeInContext->isEscapable () && paramOwnership == ValueOwnership::Default) {
469- continue ;
468+ if (paramTypeInContext->isEscapable ()) {
469+ if (isBitwiseCopyable (paramTypeInContext, mod, ctx)) {
470+ continue ;
471+ }
472+ if (paramOwnership == ValueOwnership::Default) {
473+ continue ;
474+ }
470475 }
471476
472477 auto lifetimeKind = getLifetimeDependenceKindFromType (paramTypeInContext);
473- if (!isLifetimeDependenceCompatibleWithOwnership (lifetimeKind, paramOwnership,
474- afd)) {
478+ if (!isLifetimeDependenceCompatibleWithOwnership (lifetimeKind,
479+ paramOwnership, afd)) {
475480 continue ;
476481 }
477482 if (candidateParam) {
@@ -496,12 +501,11 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
496501 if (cd && afd->isImplicit ()) {
497502 diags.diagnose (returnLoc,
498503 diag::lifetime_dependence_cannot_infer_no_candidates,
499- " on implicit initializer" );
504+ " on implicit initializer" );
500505 return std::nullopt ;
501506 }
502507 diags.diagnose (returnLoc,
503- diag::lifetime_dependence_cannot_infer_no_candidates,
504- " " );
508+ diag::lifetime_dependence_cannot_infer_no_candidates, " " );
505509 return std::nullopt ;
506510 }
507511 return lifetimeDependenceInfo;
0 commit comments