Skip to content

Commit ecb864c

Browse files
authored
Merge pull request swiftlang#63755 from gottesmm/pr-dac78af5673ab6d4a9bebea882b8440c37c9457c
[move-only] A few small changes in preparation for a larger patch
2 parents c82189d + 969d776 commit ecb864c

25 files changed

+493
-168
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,8 @@ ERROR(sil_moveonlychecker_not_understand_consumable_and_assignable, none,
792792
ERROR(sil_moveonlychecker_not_understand_moveonly, none,
793793
"Usage of a move only type that the move checker does not know how to "
794794
"check!", ())
795+
ERROR(sil_moveonlychecker_missed_copy, none,
796+
"copy of noncopyable typed value. This is a compiler bug. Please file a bug with a small example of the bug", ())
795797

796798
// move kills copyable values checker diagnostics
797799
ERROR(sil_movekillscopyablevalue_value_consumed_more_than_once, none,

include/swift/SIL/DebugUtils.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,13 +556,26 @@ inline DebugVarCarryingInst DebugVarCarryingInst::getFromValue(SILValue value) {
556556
return DebugVarCarryingInst();
557557
}
558558

559+
static_assert(sizeof(DebugVarCarryingInst) == sizeof(VarDeclCarryingInst) &&
560+
alignof(DebugVarCarryingInst) == alignof(VarDeclCarryingInst),
561+
"Expected debug var carrying inst to have the same "
562+
"size/alignment/layout as VarDeclCarryingInst!");
563+
559564
/// Attempt to discover a StringRef varName for the value \p value based only
560565
/// off of debug var information. If we fail, we return the name "unknown".
561566
inline StringRef getDebugVarName(SILValue value) {
562567
auto inst = DebugVarCarryingInst::getFromValue(value);
563568
return DebugVarCarryingInst::getName(inst);
564569
}
565570

571+
inline StringRef getDiagnosticName(SILValue value) {
572+
if (auto inst = DebugVarCarryingInst::getFromValue(value))
573+
return inst.getName();
574+
if (auto inst = VarDeclCarryingInst::getFromValue(value))
575+
return inst.getName();
576+
return "unknown";
577+
}
578+
566579
} // end namespace swift
567580

568581
#endif // SWIFT_SIL_DEBUGUTILS_H

include/swift/SIL/MemAccessUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,8 @@ struct AccessPathWithBase {
12541254
return AccessBase(base, accessPath.getStorage().getKind());
12551255
}
12561256

1257+
bool isValid() const { return base && accessPath.isValid(); }
1258+
12571259
bool operator==(AccessPathWithBase other) const {
12581260
return accessPath == other.accessPath && base == other.base;
12591261
}

include/swift/SIL/SILBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,16 @@ class SILBuilder {
439439
ElementTypes, ElementCountOperands));
440440
}
441441

442+
/// Helper function that calls \p createAllocBox after constructing a
443+
/// SILBoxType for \p fieldType.
444+
AllocBoxInst *createAllocBox(SILLocation loc, SILType fieldType,
445+
Optional<SILDebugVariable> Var = None,
446+
bool hasDynamicLifetime = false,
447+
bool reflection = false) {
448+
return createAllocBox(loc, SILBoxType::get(fieldType.getASTType()), Var,
449+
hasDynamicLifetime, reflection);
450+
}
451+
442452
AllocBoxInst *createAllocBox(SILLocation Loc, CanSILBoxType BoxType,
443453
Optional<SILDebugVariable> Var = None,
444454
bool hasDynamicLifetime = false,

include/swift/SIL/SILType.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ class SILType {
695695
///
696696
/// \p field Return the type of the ith field of the box. Default set to 0
697697
/// since we only support one field today. This is just future proofing.
698-
SILType getSILBoxFieldType(const SILFunction *f, unsigned field = 0);
698+
SILType getSILBoxFieldType(const SILFunction *f, unsigned field = 0) const;
699699

700700
/// Returns the hash code for the SILType.
701701
llvm::hash_code getHashCode() const {
@@ -708,6 +708,17 @@ class SILType {
708708
SILType getSingletonAggregateFieldType(SILModule &M,
709709
ResilienceExpansion expansion) const;
710710

711+
/// \returns true if this is a SILBoxType containing a noncopyable type.
712+
bool isBoxedNonCopyableType(const SILFunction *fn) const {
713+
if (!this->is<SILBoxType>())
714+
return false;
715+
return getSILBoxFieldType(fn).isMoveOnly();
716+
}
717+
718+
bool isBoxedNonCopyableType(const SILFunction &fn) const {
719+
return isBoxedNonCopyableType(&fn);
720+
}
721+
711722
//
712723
// Accessors for types used in SIL instructions:
713724
//

include/swift/SIL/TypeLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,8 @@ struct SILConstantInfo {
665665
enum class CaptureKind {
666666
/// A local value captured as a mutable box.
667667
Box,
668+
/// A local value captured as an immutable box.
669+
ImmutableBox,
668670
/// A local value captured as a single pointer to storage (formed with
669671
/// @noescape closures).
670672
StorageAddress,
@@ -674,7 +676,6 @@ enum class CaptureKind {
674676
Immutable
675677
};
676678

677-
678679
/// TypeConverter - helper class for creating and managing TypeLowerings.
679680
class TypeConverter {
680681
friend class TypeLowering;

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,21 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
18531853
inputs.push_back(param);
18541854
break;
18551855
}
1856+
case CaptureKind::ImmutableBox: {
1857+
// The type in the box is lowered in the minimal context.
1858+
auto minimalLoweredTy =
1859+
TC.getTypeLowering(AbstractionPattern(genericSig, canType), canType,
1860+
TypeExpansionContext::minimal())
1861+
.getLoweredType();
1862+
// Lvalues are captured as a box that owns the captured value.
1863+
auto boxTy =
1864+
TC.getInterfaceBoxTypeForCapture(VD, minimalLoweredTy.getASTType(),
1865+
/*mutable*/ false);
1866+
auto convention = ParameterConvention::Direct_Guaranteed;
1867+
auto param = SILParameterInfo(boxTy, convention);
1868+
inputs.push_back(param);
1869+
break;
1870+
}
18561871
case CaptureKind::StorageAddress: {
18571872
// Non-escaping lvalues are captured as the address of the value.
18581873
SILType ty = loweredTy.getAddressType();

lib/SIL/IR/SILType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ bool SILType::isEffectivelyExhaustiveEnumType(SILFunction *f) {
861861
f->getResilienceExpansion());
862862
}
863863

864-
SILType SILType::getSILBoxFieldType(const SILFunction *f, unsigned field) {
864+
SILType SILType::getSILBoxFieldType(const SILFunction *f, unsigned field) const {
865865
auto *boxTy = getASTType()->getAs<SILBoxType>();
866866
if (!boxTy)
867867
return SILType();

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,8 @@ swift::findTransitiveUsesForAddress(SILValue projectedAddress,
10701070
isa<SwitchEnumAddrInst>(user) || isa<CheckedCastAddrBranchInst>(user) ||
10711071
isa<SelectEnumAddrInst>(user) || isa<InjectEnumAddrInst>(user) ||
10721072
isa<IsUniqueInst>(user) || isa<ValueMetatypeInst>(user) ||
1073-
isa<DebugValueInst>(user) || isa<EndBorrowInst>(user)) {
1073+
isa<DebugValueInst>(user) || isa<EndBorrowInst>(user) ||
1074+
isa<ExplicitCopyAddrInst>(user)) {
10741075
leafUse(op);
10751076
continue;
10761077
}

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,15 @@ struct ImmutableAddressUseVerifier {
505505
return false;
506506
}
507507

508+
bool isConsumingOrMutatingExplicitCopyAddrUse(Operand *use) {
509+
auto *copyAddr = cast<ExplicitCopyAddrInst>(use->getUser());
510+
if (copyAddr->getDest() == use->get())
511+
return true;
512+
if (copyAddr->getSrc() == use->get() && copyAddr->isTakeOfSrc() == IsTake)
513+
return true;
514+
return false;
515+
}
516+
508517
bool isAddrCastToNonConsuming(SingleValueInstruction *i) {
509518
// Check if any of our uses are consuming. If none of them are consuming, we
510519
// are good to go.
@@ -604,6 +613,11 @@ struct ImmutableAddressUseVerifier {
604613
// mutation can happen. The checker will prove eventually that we can
605614
// convert it to a copy_addr [take] [init].
606615
break;
616+
case SILInstructionKind::ExplicitCopyAddrInst:
617+
if (isConsumingOrMutatingExplicitCopyAddrUse(use))
618+
return true;
619+
else
620+
break;
607621
case SILInstructionKind::CopyAddrInst:
608622
if (isConsumingOrMutatingCopyAddrUse(use))
609623
return true;

0 commit comments

Comments
 (0)