@@ -1566,41 +1566,42 @@ emitCastOperand(SILGenFunction &SGF, SILLocation loc,
1566
1566
SGFContext ctx;
1567
1567
if (requiresAddress) {
1568
1568
init = SGF.emitTemporary (loc, srcAbstractTL);
1569
-
1570
- // Okay, if all we need to do is drop the value in an address,
1571
- // this is easy.
1572
- if (!hasAbstraction) {
1573
- // TODO: Refactor this into a materialize method on CastConsumptionKind.
1574
- ManagedValue finalValue = src.getFinalManagedValue ();
1575
- if (finalValue.getOwnershipKind () == ValueOwnershipKind::Guaranteed)
1576
- finalValue = finalValue.copy (SGF, loc);
1577
- SGF.B .emitStoreValueOperation (loc, finalValue.forward (SGF),
1578
- init->getAddress (),
1579
- StoreOwnershipQualifier::Init);
1580
- init->finishInitialization (SGF);
1581
- // If we had borrow_always, we need to switch to copy_on_success since
1582
- // that is the address only variant of borrow_always.
1583
- auto consumption = src.getFinalConsumption ();
1584
- if (consumption == CastConsumptionKind::BorrowAlways)
1585
- consumption = CastConsumptionKind::CopyOnSuccess;
1586
- ConsumableManagedValue result = {init->getManagedAddress (), consumption};
1587
- if (ArgUnforwarder::requiresUnforwarding (SGF, src))
1588
- borrowedValues.push_back (result);
1589
- return result;
1590
- }
1591
-
1592
1569
ctx = SGFContext (init.get ());
1593
1570
}
1594
1571
1595
- assert (hasAbstraction);
1596
- assert (src.getType ().isObject () &&
1597
- " address-only type with abstraction difference?" );
1598
-
1599
- // Produce the value at +1.
1600
1572
ManagedValue substValue = SGF.getManagedValue (loc, src);
1601
- ManagedValue origValue =
1602
- SGF.emitSubstToOrigValue (loc, substValue, abstraction, sourceType);
1603
- return ConsumableManagedValue::forOwned (origValue);
1573
+ ManagedValue finalValue;
1574
+ if (hasAbstraction) {
1575
+ assert (src.getType ().isObject () &&
1576
+ " address-only type with abstraction difference?" );
1577
+ // Produce the value at +1.
1578
+ finalValue = SGF.emitSubstToOrigValue (loc, substValue,
1579
+ abstraction, sourceType, ctx);
1580
+ } else {
1581
+ finalValue = substValue;
1582
+ }
1583
+
1584
+ if (requiresAddress) {
1585
+ if (finalValue.getOwnershipKind () == ValueOwnershipKind::Guaranteed)
1586
+ finalValue = finalValue.copy (SGF, loc);
1587
+ SGF.B .emitStoreValueOperation (loc, finalValue.forward (SGF),
1588
+ init->getAddress (),
1589
+ StoreOwnershipQualifier::Init);
1590
+ init->finishInitialization (SGF);
1591
+
1592
+ // If we had borrow_always, we need to switch to copy_on_success since
1593
+ // that is the address only variant of borrow_always.
1594
+ auto consumption = src.getFinalConsumption ();
1595
+ if (consumption == CastConsumptionKind::BorrowAlways)
1596
+ consumption = CastConsumptionKind::CopyOnSuccess;
1597
+ ConsumableManagedValue result = {init->getManagedAddress (), consumption};
1598
+ if (ArgUnforwarder::requiresUnforwarding (SGF, src))
1599
+ borrowedValues.push_back (result);
1600
+
1601
+ return result;
1602
+ }
1603
+
1604
+ return ConsumableManagedValue::forOwned (finalValue);
1604
1605
}
1605
1606
1606
1607
// / Perform specialized dispatch for a sequence of IsPatterns.
@@ -2536,6 +2537,7 @@ class Lowering::PatternMatchContext {
2536
2537
static void emitDiagnoseOfUnexpectedEnumCaseValue (SILGenFunction &SGF,
2537
2538
SILLocation loc,
2538
2539
ManagedValue value,
2540
+ Type subjectTy,
2539
2541
const EnumDecl *enumDecl) {
2540
2542
ASTContext &ctx = SGF.getASTContext ();
2541
2543
auto diagnoseFailure = ctx.getDiagnoseUnexpectedEnumCaseValue (nullptr );
@@ -2549,10 +2551,9 @@ static void emitDiagnoseOfUnexpectedEnumCaseValue(SILGenFunction &SGF,
2549
2551
assert (value.getType ().isTrivial (SGF.getModule ()));
2550
2552
2551
2553
// Get the enum type as an Any.Type value.
2552
- CanType switchedValueSwiftType = value.getType ().getASTType ();
2553
2554
SILType metatypeType = SGF.getLoweredType (
2554
- CanMetatypeType::get (switchedValueSwiftType ,
2555
- MetatypeRepresentation::Thick ));
2555
+ AbstractionPattern::getOpaque () ,
2556
+ MetatypeType::get (subjectTy ));
2556
2557
SILValue metatype = SGF.B .createMetatype (loc, metatypeType);
2557
2558
2558
2559
// Bitcast the enum value to its raw type. (This is only safe for @objc
@@ -2573,7 +2574,7 @@ static void emitDiagnoseOfUnexpectedEnumCaseValue(SILGenFunction &SGF,
2573
2574
assert (genericParam->getIndex () < 2 );
2574
2575
switch (genericParam->getIndex ()) {
2575
2576
case 0 :
2576
- return switchedValueSwiftType ;
2577
+ return subjectTy ;
2577
2578
2578
2579
case 1 :
2579
2580
return enumDecl->getRawType ();
@@ -2592,7 +2593,8 @@ static void emitDiagnoseOfUnexpectedEnumCaseValue(SILGenFunction &SGF,
2592
2593
2593
2594
static void emitDiagnoseOfUnexpectedEnumCase (SILGenFunction &SGF,
2594
2595
SILLocation loc,
2595
- ManagedValue value) {
2596
+ ManagedValue value,
2597
+ Type subjectTy) {
2596
2598
ASTContext &ctx = SGF.getASTContext ();
2597
2599
auto diagnoseFailure = ctx.getDiagnoseUnexpectedEnumCase (nullptr );
2598
2600
if (!diagnoseFailure) {
@@ -2601,16 +2603,15 @@ static void emitDiagnoseOfUnexpectedEnumCase(SILGenFunction &SGF,
2601
2603
}
2602
2604
2603
2605
// Get the switched-upon value's type.
2604
- CanType switchedValueSwiftType = value.getType ().getASTType ();
2605
2606
SILType metatypeType = SGF.getLoweredType (
2606
- CanMetatypeType::get (switchedValueSwiftType ,
2607
- MetatypeRepresentation::Thick ));
2607
+ AbstractionPattern::getOpaque () ,
2608
+ MetatypeType::get (subjectTy)-> getCanonicalType ( ));
2608
2609
ManagedValue metatype = SGF.B .createValueMetatype (loc, metatypeType, value);
2609
2610
2610
2611
auto diagnoseSignature = diagnoseFailure->getGenericSignature ();
2611
2612
auto genericArgsMap = SubstitutionMap::get (
2612
2613
diagnoseSignature,
2613
- [&](SubstitutableType *type) -> Type { return switchedValueSwiftType ; },
2614
+ [&](SubstitutableType *type) -> Type { return subjectTy ; },
2614
2615
LookUpConformanceInSignature (*diagnoseSignature));
2615
2616
2616
2617
SGF.emitApplyOfLibraryIntrinsic (loc, diagnoseFailure, genericArgsMap,
@@ -2622,9 +2623,12 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
2622
2623
LLVM_DEBUG (llvm::dbgs () << " emitting switch stmt\n " ;
2623
2624
S->dump (llvm::dbgs ());
2624
2625
llvm::dbgs () << ' \n ' );
2626
+
2627
+ auto subjectTy = S->getSubjectExpr ()->getType ();
2628
+
2625
2629
// If the subject expression is uninhabited, we're already dead.
2626
2630
// Emit an unreachable in place of the switch statement.
2627
- if (S-> getSubjectExpr ()-> getType () ->isStructurallyUninhabited ()) {
2631
+ if (subjectTy ->isStructurallyUninhabited ()) {
2628
2632
emitIgnoredExpr (S->getSubjectExpr ());
2629
2633
B.createUnreachable (S);
2630
2634
return ;
@@ -2789,12 +2793,13 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
2789
2793
if (singleEnumDecl->isObjC ()) {
2790
2794
emitDiagnoseOfUnexpectedEnumCaseValue (*this , location,
2791
2795
subject.getFinalManagedValue (),
2792
- singleEnumDecl);
2796
+ subjectTy, singleEnumDecl);
2793
2797
return ;
2794
2798
}
2795
2799
}
2796
2800
emitDiagnoseOfUnexpectedEnumCase (*this , location,
2797
- subject.getFinalManagedValue ());
2801
+ subject.getFinalManagedValue (),
2802
+ subjectTy);
2798
2803
};
2799
2804
2800
2805
// Set up an initial clause matrix.
0 commit comments