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