@@ -371,7 +371,7 @@ class OwnershipCompatibilityUseChecker
371
371
OwnershipUseCheckerResult visitTransformingTerminatorInst (TermInst *TI);
372
372
373
373
OwnershipUseCheckerResult
374
- visitNonTrivialEnum (EnumDecl *E, ValueOwnershipKind RequiredConvention);
374
+ visitEnumArgument (EnumDecl *E, ValueOwnershipKind RequiredConvention);
375
375
OwnershipUseCheckerResult
376
376
visitApplyParameter (ValueOwnershipKind RequiredConvention,
377
377
UseLifetimeConstraint Requirement);
@@ -790,7 +790,7 @@ OwnershipCompatibilityUseChecker::checkTerminatorArgumentMatchesDestBB(
790
790
return {matches, lifetimeConstraint};
791
791
}
792
792
793
- return visitNonTrivialEnum (E, DestBlockArgOwnershipKind);
793
+ return visitEnumArgument (E, DestBlockArgOwnershipKind);
794
794
}
795
795
796
796
OwnershipUseCheckerResult
@@ -923,7 +923,7 @@ OwnershipCompatibilityUseChecker::visitReturnInst(ReturnInst *RI) {
923
923
}
924
924
925
925
if (auto *E = getType ().getEnumOrBoundGenericEnum ()) {
926
- return visitNonTrivialEnum (E, Base);
926
+ return visitEnumArgument (E, Base);
927
927
}
928
928
929
929
return {compatibleWithOwnership (Base),
@@ -1011,42 +1011,31 @@ OwnershipUseCheckerResult OwnershipCompatibilityUseChecker::visitCallee(
1011
1011
llvm_unreachable (" Unhandled ParameterConvention in switch." );
1012
1012
}
1013
1013
1014
- OwnershipUseCheckerResult OwnershipCompatibilityUseChecker::visitNonTrivialEnum (
1014
+ // Visit an enum value that is passed at argument position, including block
1015
+ // arguments, apply arguments, and return values.
1016
+ //
1017
+ // The operand definition's ownership kind may be known to be "trivial",
1018
+ // but it is still valid to pass that enum to a argument nontrivial type.
1019
+ // For example:
1020
+ //
1021
+ // %val = enum $Optional<SomeClass>, #Optional.none // trivial ownership
1022
+ // apply %f(%val) : (@owned Optional<SomeClass>) // owned argument
1023
+ OwnershipUseCheckerResult OwnershipCompatibilityUseChecker::visitEnumArgument (
1015
1024
EnumDecl *E, ValueOwnershipKind RequiredKind) {
1016
- // Otherwise, first see if the enum is completely trivial. In such a case, we
1017
- // need an argument with a trivial convention. If we have an enum with at
1018
- // least 1 non-trivial case, then we need an argument with a non-trivial
1019
- // convention. If our parameter is trivial, then we just let it through in
1020
- // such a case. Otherwise we need to make sure that the non-trivial ownership
1021
- // convention matches the one on the argument parameter.
1022
-
1023
- // Check if this enum has at least one case that is non-trivially typed.
1024
- bool HasNonTrivialCase =
1025
- llvm::any_of (E->getAllElements (), [this ](EnumElementDecl *E) -> bool {
1026
- if (!E->hasAssociatedValues ())
1027
- return false ;
1028
- SILType EnumEltType = getType ().getEnumElementType (E, Mod);
1029
- return !EnumEltType.isTrivial (Mod);
1030
- });
1031
-
1032
- // If we have all trivial cases, make sure we are compatible with a trivial
1033
- // ownership kind.
1034
- if (!HasNonTrivialCase) {
1035
- return {compatibleWithOwnership (ValueOwnershipKind::Trivial),
1036
- UseLifetimeConstraint::MustBeLive};
1037
- }
1038
-
1039
- // Otherwise, if this value is a trivial ownership kind, return.
1025
+ // If this value is already categorized as a trivial ownership kind, it is
1026
+ // safe to pass to any argument convention.
1040
1027
if (compatibleWithOwnership (ValueOwnershipKind::Trivial)) {
1041
1028
return {true , UseLifetimeConstraint::MustBeLive};
1042
1029
}
1043
1030
1044
- // And finally finish by making sure that if we have a non-trivial ownership
1045
- // kind that it matches the argument's convention.
1046
- auto lifetimeConstraint = hasExactOwnership (ValueOwnershipKind::Owned)
1031
+ // The operand has a non-trivial ownership kind. It must match the argument
1032
+ // convention.
1033
+ auto ownership = getOwnershipKind ();
1034
+ auto lifetimeConstraint = (ownership == ValueOwnershipKind::Owned)
1047
1035
? UseLifetimeConstraint::MustBeInvalidated
1048
1036
: UseLifetimeConstraint::MustBeLive;
1049
- return {compatibleWithOwnership (RequiredKind), lifetimeConstraint};
1037
+ return {compatibleOwnershipKinds (ownership, RequiredKind),
1038
+ lifetimeConstraint};
1050
1039
}
1051
1040
1052
1041
// We allow for trivial cases of enums with non-trivial cases to be passed in
@@ -1060,7 +1049,7 @@ OwnershipUseCheckerResult OwnershipCompatibilityUseChecker::visitApplyParameter(
1060
1049
if (!E) {
1061
1050
return {compatibleWithOwnership (Kind), Requirement};
1062
1051
}
1063
- return visitNonTrivialEnum (E, Kind);
1052
+ return visitEnumArgument (E, Kind);
1064
1053
}
1065
1054
1066
1055
// Handle Apply and TryApply.
0 commit comments