Alternative noncopyable switch design based on expression kind.

If an expression refers to noncopyable storage, then default to performing
a borrowing switch, where `let` bindings in patterns borrow out of the
matched value. If an expression refers to a temporary value or explicitly
uses the `consume` keyword, then perform a consuming switch, where
`let` bindings take ownership of corresponding parts of the matched value.
Allow `_borrowing` to still be used to explicitly bind a pattern variable
as a borrow, with no-implicit-copy semantics for copyable values.
This commit is contained in:
Joe Groff
2024-03-27 18:08:13 -07:00
parent 3b830bffb5
commit ba3494802a
9 changed files with 181 additions and 57 deletions

View File

@@ -777,6 +777,9 @@ Pattern::getOwnership(
void visitNamedPattern(NamedPattern *p) {
switch (p->getDecl()->getIntroducer()) {
case VarDecl::Introducer::Let:
// `let` defaults to the prevailing ownership of the switch.
break;
case VarDecl::Introducer::Var:
// If the subpattern type is copyable, then we can bind the variable
// by copying without requiring more than a borrow of the original.
@@ -786,7 +789,7 @@ Pattern::getOwnership(
// TODO: An explicit `consuming` binding kind consumes regardless of
// type.
// Noncopyable `let` and `var` consume the bound value to move it into
// Noncopyable `var` consumes the bound value to move it into
// a new independent variable.
increaseOwnership(ValueOwnership::Owned, p);
break;
@@ -797,8 +800,8 @@ Pattern::getOwnership(
break;
case VarDecl::Introducer::Borrowing:
// `borrow` bindings borrow parts of the value in-place so they don't
// need stronger access to the subject value.
// `borrow` bindings borrow parts of the value in-place.
increaseOwnership(ValueOwnership::Shared, p);
break;
}
}