@@ -79,6 +79,20 @@ filterEscapableLifetimeDependencies(GenericSignature sig,
79
79
return didRemoveLifetimeDependencies;
80
80
}
81
81
82
+ StringRef
83
+ getNameForParsedLifetimeDependenceKind (ParsedLifetimeDependenceKind kind) {
84
+ switch (kind) {
85
+ case ParsedLifetimeDependenceKind::Scope:
86
+ return " borrow" ;
87
+ case ParsedLifetimeDependenceKind::Inherit:
88
+ return " copy" ;
89
+ case ParsedLifetimeDependenceKind::Inout:
90
+ return " inout" ;
91
+ default :
92
+ return " " ;
93
+ }
94
+ }
95
+
82
96
std::string LifetimeDependenceInfo::getString () const {
83
97
std::string lifetimeDependenceString = " @lifetime(" ;
84
98
auto addressable = getAddressableIndices ();
@@ -451,26 +465,43 @@ class LifetimeDependenceChecker {
451
465
}
452
466
}
453
467
454
- bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
468
+ bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
455
469
ValueOwnership ownership) const {
456
- if (kind == LifetimeDependenceKind ::Inherit) {
470
+ if (kind == ParsedLifetimeDependenceKind ::Inherit) {
457
471
return true ;
458
472
}
459
473
// Lifetime dependence always propagates through temporary BitwiseCopyable
460
474
// values, even if the dependence is scoped.
461
475
if (isBitwiseCopyable (type, ctx)) {
462
476
return true ;
463
477
}
464
- assert (kind == LifetimeDependenceKind::Scope);
465
478
auto loweredOwnership = ownership != ValueOwnership::Default
466
479
? ownership : getLoweredOwnership (afd);
467
480
468
- if (loweredOwnership == ValueOwnership::InOut ||
469
- loweredOwnership == ValueOwnership::Shared) {
481
+ if (kind == ParsedLifetimeDependenceKind::Scope) {
482
+ return loweredOwnership == ValueOwnership::Shared;
483
+ }
484
+ assert (kind == ParsedLifetimeDependenceKind::Inout);
485
+ return loweredOwnership == ValueOwnership::InOut;
486
+ }
487
+
488
+ bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
489
+ ValueOwnership ownership) const {
490
+ if (kind == LifetimeDependenceKind::Inherit) {
470
491
return true ;
471
492
}
472
- assert (loweredOwnership == ValueOwnership::Owned);
473
- return false ;
493
+ // Lifetime dependence always propagates through temporary BitwiseCopyable
494
+ // values, even if the dependence is scoped.
495
+ if (isBitwiseCopyable (type, ctx)) {
496
+ return true ;
497
+ }
498
+ auto loweredOwnership = ownership != ValueOwnership::Default
499
+ ? ownership
500
+ : getLoweredOwnership (afd);
501
+
502
+ assert (kind == LifetimeDependenceKind::Scope);
503
+ return loweredOwnership == ValueOwnership::Shared ||
504
+ loweredOwnership == ValueOwnership::InOut;
474
505
}
475
506
476
507
struct TargetDeps {
@@ -546,44 +577,51 @@ class LifetimeDependenceChecker {
546
577
std::optional<LifetimeDependenceKind>
547
578
getDependenceKindFromDescriptor (LifetimeDescriptor descriptor,
548
579
ParamDecl *decl) {
549
- auto loc = descriptor.getLoc ();
550
-
551
- auto ownership = decl->getValueOwnership ();
580
+ auto loc = decl->getLoc ();
552
581
auto type = decl->getTypeInContext ();
582
+ auto parsedLifetimeKind = descriptor.getParsedLifetimeDependenceKind ();
583
+ auto ownership = decl->getValueOwnership ();
584
+ auto loweredOwnership = ownership != ValueOwnership::Default
585
+ ? ownership
586
+ : getLoweredOwnership (afd);
553
587
554
- LifetimeDependenceKind kind;
555
- switch (descriptor.getParsedLifetimeDependenceKind ()) {
556
- case ParsedLifetimeDependenceKind::Default:
588
+ if (parsedLifetimeKind == ParsedLifetimeDependenceKind::Default) {
557
589
if (type->isEscapable ()) {
558
- kind = LifetimeDependenceKind::Scope;
590
+ if (loweredOwnership == ValueOwnership::Shared ||
591
+ loweredOwnership == ValueOwnership::InOut) {
592
+ return LifetimeDependenceKind::Scope;
593
+ } else {
594
+ diagnose (
595
+ loc,
596
+ diag::lifetime_dependence_cannot_use_default_escapable_consuming,
597
+ getOwnershipSpelling (loweredOwnership));
598
+ return std::nullopt;
599
+ }
559
600
} else if (useLazyInference ()) {
560
- kind = LifetimeDependenceKind::Inherit;
561
- } else {
562
- diagnose (loc, diag::lifetime_dependence_cannot_infer_kind,
563
- diagnosticQualifier (), descriptor.getString ());
564
- return std::nullopt;
601
+ return LifetimeDependenceKind::Inherit;
565
602
}
566
- break ;
567
- case ParsedLifetimeDependenceKind::Scope:
568
- kind = LifetimeDependenceKind::Scope;
569
- break ;
570
- case ParsedLifetimeDependenceKind::Inherit:
571
- kind = LifetimeDependenceKind::Inherit;
572
- break ;
603
+ diagnose (loc, diag::lifetime_dependence_cannot_infer_kind,
604
+ diagnosticQualifier (), descriptor.getString ());
605
+ return std::nullopt;
573
606
}
574
- // @lifetime(borrow x) is invalid for consuming parameters.
575
- if (!isCompatibleWithOwnership (kind, type, ownership)) {
607
+
608
+ // @lifetime(borrow x) is valid only for borrowing parameters.
609
+ // @lifetime(inout x) is valid only for inout parameters.
610
+ if (!isCompatibleWithOwnership (parsedLifetimeKind, type, ownership)) {
576
611
diagnose (loc,
577
612
diag::lifetime_dependence_cannot_use_parsed_borrow_consuming);
578
613
return std::nullopt;
579
614
}
580
615
// @lifetime(copy x) is only invalid for Escapable types.
581
- if (kind == LifetimeDependenceKind::Inherit && type->isEscapable ()) {
616
+ if (parsedLifetimeKind == ParsedLifetimeDependenceKind::Inherit &&
617
+ type->isEscapable ()) {
582
618
diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
583
619
descriptor.getString ());
584
620
return std::nullopt;
585
621
}
586
- return kind;
622
+ return parsedLifetimeKind == ParsedLifetimeDependenceKind::Inherit
623
+ ? LifetimeDependenceKind::Inherit
624
+ : LifetimeDependenceKind::Scope;
587
625
}
588
626
589
627
// Finds the ParamDecl* and its index from a LifetimeDescriptor
0 commit comments