@@ -531,7 +531,8 @@ class PatternMatchEmission {
531531 bool forIrrefutableRow, bool hasMultipleItems);
532532
533533 // Bind noncopyable variable bindings as borrows.
534- void bindIrrefutableBorrows (const ClauseRow &row, ArgArray args);
534+ void bindIrrefutableBorrows (const ClauseRow &row, ArgArray args,
535+ bool forIrrefutableRow, bool hasMultipleItems);
535536
536537 // End the borrow of the subject and derived values during a move-only match.
537538 void unbindAndEndBorrows (const ClauseRow &row, ArgArray args);
@@ -1187,7 +1188,8 @@ void PatternMatchEmission::emitWildcardDispatch(ClauseMatrix &clauses,
11871188 // If the final pattern match is only borrowing as well,
11881189 // we can bind the variables immediately here too.
11891190 if (*ownership <= ValueOwnership::Shared) {
1190- bindIrrefutableBorrows (clauses[row], args);
1191+ bindIrrefutableBorrows (clauses[row], args,
1192+ !hasGuard, hasMultipleItems);
11911193 }
11921194
11931195 if (hasGuard) {
@@ -1286,7 +1288,9 @@ void PatternMatchEmission::bindIrrefutablePatterns(const ClauseRow &row,
12861288}
12871289
12881290void PatternMatchEmission::bindIrrefutableBorrows (const ClauseRow &row,
1289- ArgArray args) {
1291+ ArgArray args,
1292+ bool forIrrefutableRow,
1293+ bool hasMultipleItems) {
12901294 assert (row.columns () == args.size ());
12911295 for (unsigned i = 0 , e = args.size (); i != e; ++i) {
12921296 if (!row[i]) // We use null patterns to mean artificial AnyPatterns
@@ -1301,7 +1305,16 @@ void PatternMatchEmission::bindIrrefutableBorrows(const ClauseRow &row,
13011305 break ;
13021306 case PatternKind::Named: {
13031307 NamedPattern *named = cast<NamedPattern>(pattern);
1304- bindBorrow (pattern, named->getDecl (), args[i]);
1308+ // If the subpattern matches a copyable type, and the match isn't
1309+ // explicitly `borrowing`, then we can bind it as a normal copyable
1310+ // value.
1311+ if (named->getDecl ()->getIntroducer () != VarDecl::Introducer::Borrowing
1312+ && !named->getType ()->isNoncopyable ()) {
1313+ bindVariable (pattern, named->getDecl (), args[i], forIrrefutableRow,
1314+ hasMultipleItems);
1315+ } else {
1316+ bindBorrow (pattern, named->getDecl (), args[i]);
1317+ }
13051318 break ;
13061319 }
13071320 default :
@@ -1391,14 +1404,25 @@ void PatternMatchEmission::bindBorrow(Pattern *pattern, VarDecl *var,
13911404 assert (value.getFinalConsumption () == CastConsumptionKind::BorrowAlways);
13921405
13931406 auto bindValue = value.asBorrowedOperand2 (SGF, pattern).getFinalManagedValue ();
1394- if (bindValue.getType ().isMoveOnly ()) {
1395- if (bindValue.getType ().isObject ()) {
1396- // Create a notional copy for the borrow checker to use.
1397- bindValue = bindValue.copy (SGF, pattern);
1407+
1408+ // Borrow bindings of copyable type should still be no-implicit-copy.
1409+ if (!bindValue.getType ().isMoveOnly ()) {
1410+ if (bindValue.getType ().isAddress ()) {
1411+ bindValue = ManagedValue::forBorrowedAddressRValue (
1412+ SGF.B .createCopyableToMoveOnlyWrapperAddr (pattern, bindValue.getValue ()));
1413+ } else {
1414+ bindValue =
1415+ SGF.B .createGuaranteedCopyableToMoveOnlyWrapperValue (pattern, bindValue);
13981416 }
1399- bindValue = SGF.B .createMarkUnresolvedNonCopyableValueInst (pattern, bindValue,
1400- MarkUnresolvedNonCopyableValueInst::CheckKind::NoConsumeOrAssign);
14011417 }
1418+
1419+ if (bindValue.getType ().isObject ()) {
1420+ // Create a notional copy for the borrow checker to use.
1421+ bindValue = bindValue.copy (SGF, pattern);
1422+ }
1423+ bindValue = SGF.B .createMarkUnresolvedNonCopyableValueInst (pattern, bindValue,
1424+ MarkUnresolvedNonCopyableValueInst::CheckKind::NoConsumeOrAssign);
1425+
14021426 SGF.VarLocs [var] = SILGenFunction::VarLoc::get (bindValue.getValue ());
14031427}
14041428
@@ -1420,7 +1444,9 @@ void PatternMatchEmission::emitGuardBranch(SILLocation loc, Expr *guard,
14201444 // subject yet.
14211445 if (auto ownership = getNoncopyableOwnership ()) {
14221446 if (*ownership > ValueOwnership::Shared) {
1423- bindIrrefutableBorrows (row, args);
1447+ bindIrrefutableBorrows (row, args,
1448+ /* irrefutable*/ false ,
1449+ /* multiple items*/ false );
14241450 }
14251451 }
14261452 testBool = SGF.emitRValueAsSingleValue (guard).getUnmanagedValue ();
0 commit comments