@@ -531,7 +531,8 @@ class PatternMatchEmission {
531
531
bool forIrrefutableRow, bool hasMultipleItems);
532
532
533
533
// 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);
535
536
536
537
// End the borrow of the subject and derived values during a move-only match.
537
538
void unbindAndEndBorrows (const ClauseRow &row, ArgArray args);
@@ -1187,7 +1188,8 @@ void PatternMatchEmission::emitWildcardDispatch(ClauseMatrix &clauses,
1187
1188
// If the final pattern match is only borrowing as well,
1188
1189
// we can bind the variables immediately here too.
1189
1190
if (*ownership <= ValueOwnership::Shared) {
1190
- bindIrrefutableBorrows (clauses[row], args);
1191
+ bindIrrefutableBorrows (clauses[row], args,
1192
+ !hasGuard, hasMultipleItems);
1191
1193
}
1192
1194
1193
1195
if (hasGuard) {
@@ -1286,7 +1288,9 @@ void PatternMatchEmission::bindIrrefutablePatterns(const ClauseRow &row,
1286
1288
}
1287
1289
1288
1290
void PatternMatchEmission::bindIrrefutableBorrows (const ClauseRow &row,
1289
- ArgArray args) {
1291
+ ArgArray args,
1292
+ bool forIrrefutableRow,
1293
+ bool hasMultipleItems) {
1290
1294
assert (row.columns () == args.size ());
1291
1295
for (unsigned i = 0 , e = args.size (); i != e; ++i) {
1292
1296
if (!row[i]) // We use null patterns to mean artificial AnyPatterns
@@ -1301,7 +1305,16 @@ void PatternMatchEmission::bindIrrefutableBorrows(const ClauseRow &row,
1301
1305
break ;
1302
1306
case PatternKind::Named: {
1303
1307
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
+ }
1305
1318
break ;
1306
1319
}
1307
1320
default :
@@ -1391,14 +1404,25 @@ void PatternMatchEmission::bindBorrow(Pattern *pattern, VarDecl *var,
1391
1404
assert (value.getFinalConsumption () == CastConsumptionKind::BorrowAlways);
1392
1405
1393
1406
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);
1398
1416
}
1399
- bindValue = SGF.B .createMarkUnresolvedNonCopyableValueInst (pattern, bindValue,
1400
- MarkUnresolvedNonCopyableValueInst::CheckKind::NoConsumeOrAssign);
1401
1417
}
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
+
1402
1426
SGF.VarLocs [var] = SILGenFunction::VarLoc::get (bindValue.getValue ());
1403
1427
}
1404
1428
@@ -1420,7 +1444,9 @@ void PatternMatchEmission::emitGuardBranch(SILLocation loc, Expr *guard,
1420
1444
// subject yet.
1421
1445
if (auto ownership = getNoncopyableOwnership ()) {
1422
1446
if (*ownership > ValueOwnership::Shared) {
1423
- bindIrrefutableBorrows (row, args);
1447
+ bindIrrefutableBorrows (row, args,
1448
+ /* irrefutable*/ false ,
1449
+ /* multiple items*/ false );
1424
1450
}
1425
1451
}
1426
1452
testBool = SGF.emitRValueAsSingleValue (guard).getUnmanagedValue ();
0 commit comments