diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index ad891af868296..e2da4684e1b20 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -699,6 +699,9 @@ class alignas(1 << TypeAlignInBits) TypeBase /// Copyable. bool isNoncopyable(); + /// Returns true if this contextual type satisfies a conformance to Copyable. + bool isCopyable(); + /// Returns true if this contextual type satisfies a conformance to Escapable. bool isEscapable(); @@ -6102,7 +6105,7 @@ class SILMoveOnlyWrappedType final : public TypeBase, innerType(innerType) { // If it has a type parameter, we can't check whether it's copyable. assert(innerType->hasTypeParameter() || - !innerType->isNoncopyable() && "Inner type must be copyable"); + innerType->isCopyable() && "Inner type must be copyable"); } public: diff --git a/lib/AST/ConformanceLookup.cpp b/lib/AST/ConformanceLookup.cpp index 9f80de0d3f45a..3e323a87158a1 100644 --- a/lib/AST/ConformanceLookup.cpp +++ b/lib/AST/ConformanceLookup.cpp @@ -946,6 +946,11 @@ bool TypeBase::isNoncopyable() { return !Bits.TypeBase.IsCopyable; } +/// \returns true iff this type conforms to Copyable. +bool TypeBase::isCopyable() { + return !isNoncopyable(); +} + /// \returns true iff this type conforms to Escaping. bool TypeBase::isEscapable() { if (!Bits.TypeBase.ComputedInvertibleConformances) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 9f943f97a8905..0b3f42a541144 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -8571,7 +8571,7 @@ LifetimeAnnotation ParamDecl::getLifetimeAnnotation() const { auto specifier = getSpecifier(); // Copyable parameters which are consumed have eager-move semantics. if (specifier == ParamDecl::Specifier::Consuming && - !getTypeInContext()->isNoncopyable()) { + getTypeInContext()->isCopyable()) { if (getAttrs().hasAttribute()) return LifetimeAnnotation::Lexical; return LifetimeAnnotation::EagerMove; @@ -11429,7 +11429,7 @@ LifetimeAnnotation FuncDecl::getLifetimeAnnotation() const { // Copyable parameters which are consumed have eager-move semantics. if (getSelfAccessKind() == SelfAccessKind::Consuming) { auto *selfDecl = getImplicitSelfDecl(); - if (selfDecl && !selfDecl->getTypeInContext()->isNoncopyable()) { + if (selfDecl && selfDecl->getTypeInContext()->isCopyable()) { if (getAttrs().hasAttribute()) return LifetimeAnnotation::Lexical; return LifetimeAnnotation::EagerMove; diff --git a/lib/AST/Pattern.cpp b/lib/AST/Pattern.cpp index 8e1d704bf7c30..1ceb418fa1fdb 100644 --- a/lib/AST/Pattern.cpp +++ b/lib/AST/Pattern.cpp @@ -797,7 +797,7 @@ Pattern::getOwnership( 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. - if (!p->hasType() || !p->getType()->isNoncopyable()) { + if (!p->hasType() || p->getType()->isCopyable()) { break; } // TODO: An explicit `consuming` binding kind consumes regardless of diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 26dc3e4b5f277..0a6bea0cc8ba1 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -3054,7 +3054,7 @@ IsABIAccessible_t irgen::isTypeABIAccessibleIfFixedSize(IRGenModule &IGM, CanType ty) { // Copyable types currently are always ABI-accessible if they're fixed size. - if (!ty->isNoncopyable()) + if (ty->isCopyable()) return IsABIAccessible; // Check for a deinit. If this type does not define a deinit it is ABI diff --git a/lib/SIL/IR/SIL.cpp b/lib/SIL/IR/SIL.cpp index 888b535a1cb1b..d03ee74f91f7d 100644 --- a/lib/SIL/IR/SIL.cpp +++ b/lib/SIL/IR/SIL.cpp @@ -319,7 +319,7 @@ getKeyPathSupportingGenericSignature(Type ty, GenericSignature contextSig) { // If the type is already unconditionally Copyable and Escapable, we don't // need any further requirements. - if (!ty->isNoncopyable() && ty->isEscapable()) { + if (ty->isCopyable() && ty->isEscapable()) { return contextSig; } diff --git a/lib/SIL/IR/SILType.cpp b/lib/SIL/IR/SILType.cpp index 8ffb695558c65..d7be1ad3515d3 100644 --- a/lib/SIL/IR/SILType.cpp +++ b/lib/SIL/IR/SILType.cpp @@ -1239,7 +1239,7 @@ SILType SILType::addingMoveOnlyWrapperToBoxedType(const SILFunction *fn) { auto oldField = oldLayout->getFields()[0]; if (oldField.getLoweredType()->is()) return *this; - assert(!oldField.getLoweredType()->isNoncopyable() && + assert(oldField.getLoweredType()->isCopyable() && "Cannot moveonlywrapped in a moveonly type"); auto newField = SILField(SILMoveOnlyWrappedType::get(oldField.getLoweredType()), diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index bf0900a21efd0..e60bd90469826 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -128,7 +128,7 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture, contextTy, TypeExpansionContext::noOpaqueTypeArchetypesSubstitution( expansion.getResilienceExpansion())); - assert(!contextTy->isNoncopyable() && "Not implemented"); + assert(contextTy->isCopyable() && "Not implemented"); if (!props.isAddressOnly()) return CaptureKind::Constant; diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp index 98f20dbe35d97..dff7079aa9fbc 100644 --- a/lib/SILGen/SILGenDecl.cpp +++ b/lib/SILGen/SILGenDecl.cpp @@ -561,7 +561,7 @@ class LocalVariableInitialization : public SingleBufferInitialization { // If our instance type is not already @moveOnly wrapped, and it's a // no-implicit-copy parameter, wrap it. - if (!isNoImplicitCopy && !instanceType->isNoncopyable()) { + if (!isNoImplicitCopy && instanceType->isCopyable()) { if (auto *pd = dyn_cast(decl)) { isNoImplicitCopy = pd->isNoImplicitCopy(); isNoImplicitCopy |= pd->getSpecifier() == ParamSpecifier::Consuming; @@ -577,7 +577,7 @@ class LocalVariableInitialization : public SingleBufferInitialization { } } - const bool isCopyable = isNoImplicitCopy || !instanceType->isNoncopyable(); + const bool isCopyable = isNoImplicitCopy || instanceType->isCopyable(); auto boxType = SGF.SGM.Types.getContextBoxTypeForCapture( decl, instanceType, SGF.F.getGenericEnvironment(), @@ -1548,7 +1548,7 @@ SILGenFunction::emitInitializationForVarDecl(VarDecl *vd, bool forceImmutable, // If this is a 'let' initialization for a copyable non-global, set up a let // binding, which stores the initialization value into VarLocs directly. if (forceImmutable && vd->getDeclContext()->isLocalContext() && - !isa(varType) && !varType->isNoncopyable()) + !isa(varType) && varType->isCopyable()) return InitializationPtr(new LetValueInitialization(vd, *this)); // If the variable has no initial value, emit a mark_uninitialized instruction diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp index 45beb29c1323a..a201c94989b1d 100644 --- a/lib/SILGen/SILGenPattern.cpp +++ b/lib/SILGen/SILGenPattern.cpp @@ -1308,7 +1308,7 @@ void PatternMatchEmission::bindIrrefutableBorrows(const ClauseRow &row, // explicitly `borrowing`, then we can bind it as a normal copyable // value. if (named->getDecl()->getIntroducer() != VarDecl::Introducer::Borrowing - && !named->getType()->isNoncopyable()) { + && named->getType()->isCopyable()) { bindVariable(pattern, named->getDecl(), args[i], forIrrefutableRow, hasMultipleItems); } else { diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index f7fe4c546b8dc..808c59cf97443 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -387,7 +387,7 @@ static bool willHaveConfusingConsumption(Type type, ConstraintLocatorBuilder locator, ConstraintSystem &cs) { assert(type); - if (!type->isNoncopyable()) + if (type->isCopyable()) return false; /// If it's a copyable type, there's no confusion. auto loc = cs.getConstraintLocator(locator); diff --git a/lib/Sema/PlaygroundTransform.cpp b/lib/Sema/PlaygroundTransform.cpp index 997e0d1aca68d..44ac0531c2526 100644 --- a/lib/Sema/PlaygroundTransform.cpp +++ b/lib/Sema/PlaygroundTransform.cpp @@ -821,9 +821,9 @@ class Instrumenter : InstrumenterBase { if (auto *VD = dyn_cast_or_null(node.dyn_cast())) { auto interfaceTy = VD->getInterfaceType(); auto contextualTy = VD->getInnermostDeclContext()->mapTypeIntoContext(interfaceTy); - return !contextualTy->isNoncopyable(); + return contextualTy->isCopyable(); } else if (auto *E = node.dyn_cast()) { - return !E->getType()->isNoncopyable(); + return E->getType()->isCopyable(); } else { return true; } diff --git a/lib/Sema/TypeCheckInvertible.cpp b/lib/Sema/TypeCheckInvertible.cpp index db8571a165e1d..161058d0d63dc 100644 --- a/lib/Sema/TypeCheckInvertible.cpp +++ b/lib/Sema/TypeCheckInvertible.cpp @@ -253,7 +253,7 @@ static void checkInvertibleConformanceCommon(DeclContext *dc, // For a type conforming to IP, ensure that the storage conforms to IP. switch (IP) { case InvertibleProtocolKind::Copyable: - if (!type->isNoncopyable()) + if (type->isCopyable()) return false; break; case InvertibleProtocolKind::Escapable: diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp index bff6cec1bee7e..75f35bf067ee0 100644 --- a/lib/Sema/TypeCheckStmt.cpp +++ b/lib/Sema/TypeCheckStmt.cpp @@ -1268,7 +1268,7 @@ class StmtChecker : public StmtVisitor { fn->mapTypeIntoContext(nominalDecl->getDeclaredInterfaceType()); // must be noncopyable - if (!nominalType->isNoncopyable()) { + if (nominalType->isCopyable()) { ctx.Diags.diagnose(DS->getDiscardLoc(), diag::discard_wrong_context_copyable); diagnosed = true; diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index b3d7ff5430dad..854d8546da9f7 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2693,7 +2693,7 @@ bool swift::diagnoseMissingOwnership(ParamSpecifier ownership, resolution.getGenericSignature().getGenericEnvironment(), ty); - if (ty->hasError() || !ty->isNoncopyable()) + if (ty->hasError() || ty->isCopyable()) return false; // copyable types do not need ownership if (ownership != ParamSpecifier::Default)