@@ -48,6 +48,20 @@ getLifetimeDependenceFor(ArrayRef<LifetimeDependenceInfo> lifetimeDependencies,
48
48
return std::nullopt;
49
49
}
50
50
51
+ StringRef
52
+ getNameForParsedLifetimeDependenceKind (ParsedLifetimeDependenceKind kind) {
53
+ switch (kind) {
54
+ case ParsedLifetimeDependenceKind::Scope:
55
+ return " borrow" ;
56
+ case ParsedLifetimeDependenceKind::Inherit:
57
+ return " copy" ;
58
+ case ParsedLifetimeDependenceKind::Inout:
59
+ return " inout" ;
60
+ default :
61
+ return " " ;
62
+ }
63
+ }
64
+
51
65
std::string LifetimeDependenceInfo::getString () const {
52
66
std::string lifetimeDependenceString = " @lifetime(" ;
53
67
auto addressable = getAddressableIndices ();
@@ -420,26 +434,43 @@ class LifetimeDependenceChecker {
420
434
}
421
435
}
422
436
423
- bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
437
+ bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
424
438
ValueOwnership ownership) const {
425
- if (kind == LifetimeDependenceKind ::Inherit) {
439
+ if (kind == ParsedLifetimeDependenceKind ::Inherit) {
426
440
return true ;
427
441
}
428
442
// Lifetime dependence always propagates through temporary BitwiseCopyable
429
443
// values, even if the dependence is scoped.
430
444
if (isBitwiseCopyable (type, ctx)) {
431
445
return true ;
432
446
}
433
- assert (kind == LifetimeDependenceKind::Scope);
434
447
auto loweredOwnership = ownership != ValueOwnership::Default
435
448
? ownership : getLoweredOwnership (afd);
436
449
437
- if (loweredOwnership == ValueOwnership::InOut ||
438
- loweredOwnership == ValueOwnership::Shared) {
450
+ if (kind == ParsedLifetimeDependenceKind::Scope) {
451
+ return loweredOwnership == ValueOwnership::Shared;
452
+ }
453
+ assert (kind == ParsedLifetimeDependenceKind::Inout);
454
+ return loweredOwnership == ValueOwnership::InOut;
455
+ }
456
+
457
+ bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
458
+ ValueOwnership ownership) const {
459
+ if (kind == LifetimeDependenceKind::Inherit) {
439
460
return true ;
440
461
}
441
- assert (loweredOwnership == ValueOwnership::Owned);
442
- return false ;
462
+ // Lifetime dependence always propagates through temporary BitwiseCopyable
463
+ // values, even if the dependence is scoped.
464
+ if (isBitwiseCopyable (type, ctx)) {
465
+ return true ;
466
+ }
467
+ auto loweredOwnership = ownership != ValueOwnership::Default
468
+ ? ownership
469
+ : getLoweredOwnership (afd);
470
+
471
+ assert (kind == LifetimeDependenceKind::Scope);
472
+ return loweredOwnership == ValueOwnership::Shared ||
473
+ loweredOwnership == ValueOwnership::InOut;
443
474
}
444
475
445
476
struct TargetDeps {
@@ -515,44 +546,51 @@ class LifetimeDependenceChecker {
515
546
std::optional<LifetimeDependenceKind>
516
547
getDependenceKindFromDescriptor (LifetimeDescriptor descriptor,
517
548
ParamDecl *decl) {
518
- auto loc = descriptor.getLoc ();
519
-
520
- auto ownership = decl->getValueOwnership ();
549
+ auto loc = decl->getLoc ();
521
550
auto type = decl->getTypeInContext ();
551
+ auto parsedLifetimeKind = descriptor.getParsedLifetimeDependenceKind ();
552
+ auto ownership = decl->getValueOwnership ();
553
+ auto loweredOwnership = ownership != ValueOwnership::Default
554
+ ? ownership
555
+ : getLoweredOwnership (afd);
522
556
523
- LifetimeDependenceKind kind;
524
- switch (descriptor.getParsedLifetimeDependenceKind ()) {
525
- case ParsedLifetimeDependenceKind::Default:
557
+ if (parsedLifetimeKind == ParsedLifetimeDependenceKind::Default) {
526
558
if (type->isEscapable ()) {
527
- kind = LifetimeDependenceKind::Scope;
559
+ if (loweredOwnership == ValueOwnership::Shared ||
560
+ loweredOwnership == ValueOwnership::InOut) {
561
+ return LifetimeDependenceKind::Scope;
562
+ } else {
563
+ diagnose (
564
+ loc,
565
+ diag::lifetime_dependence_cannot_use_default_escapable_consuming,
566
+ getOwnershipSpelling (loweredOwnership));
567
+ return std::nullopt;
568
+ }
528
569
} else if (useLazyInference ()) {
529
- kind = LifetimeDependenceKind::Inherit;
530
- } else {
531
- diagnose (loc, diag::lifetime_dependence_cannot_infer_kind,
532
- diagnosticQualifier (), descriptor.getString ());
533
- return std::nullopt;
570
+ return LifetimeDependenceKind::Inherit;
534
571
}
535
- break ;
536
- case ParsedLifetimeDependenceKind::Scope:
537
- kind = LifetimeDependenceKind::Scope;
538
- break ;
539
- case ParsedLifetimeDependenceKind::Inherit:
540
- kind = LifetimeDependenceKind::Inherit;
541
- break ;
572
+ diagnose (loc, diag::lifetime_dependence_cannot_infer_kind,
573
+ diagnosticQualifier (), descriptor.getString ());
574
+ return std::nullopt;
542
575
}
543
- // @lifetime(borrow x) is invalid for consuming parameters.
544
- if (!isCompatibleWithOwnership (kind, type, ownership)) {
576
+
577
+ // @lifetime(borrow x) is valid only for borrowing parameters.
578
+ // @lifetime(inout x) is valid only for inout parameters.
579
+ if (!isCompatibleWithOwnership (parsedLifetimeKind, type, ownership)) {
545
580
diagnose (loc,
546
581
diag::lifetime_dependence_cannot_use_parsed_borrow_consuming);
547
582
return std::nullopt;
548
583
}
549
584
// @lifetime(copy x) is only invalid for Escapable types.
550
- if (kind == LifetimeDependenceKind::Inherit && type->isEscapable ()) {
585
+ if (parsedLifetimeKind == ParsedLifetimeDependenceKind::Inherit &&
586
+ type->isEscapable ()) {
551
587
diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
552
588
descriptor.getString ());
553
589
return std::nullopt;
554
590
}
555
- return kind;
591
+ return parsedLifetimeKind == ParsedLifetimeDependenceKind::Inherit
592
+ ? LifetimeDependenceKind::Inherit
593
+ : LifetimeDependenceKind::Scope;
556
594
}
557
595
558
596
// Finds the ParamDecl* and its index from a LifetimeDescriptor
0 commit comments