Merge pull request #11074 from CodaFi/the-sharing-economy
Staging for __shared and __owned
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 857cda9..6c09448 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -5048,21 +5048,6 @@
return getParameterLists()[i];
}
- /// \brief If this is a method in a type or extension thereof, compute
- /// and return the type to be used for the 'self' argument of the interface
- /// type, or an empty Type() if no 'self' argument should exist. This can
- /// only be used after name binding has resolved types.
- ///
- /// \param isInitializingCtor Specifies whether we're computing the 'self'
- /// type of an initializing constructor, which accepts an instance 'self'
- /// rather than a metatype 'self'.
- ///
- /// \param wantDynamicSelf Specifies whether the 'self' type should be
- /// wrapped in a DynamicSelfType, which is the case for the 'self' parameter
- /// type inside a class method returning 'Self'.
- Type computeInterfaceSelfType(bool isInitializingCtor=false,
- bool wantDynamicSelf=false);
-
/// \brief This method returns the implicit 'self' decl.
///
/// Note that some functions don't have an implicit 'self' decl, for example,
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 97e67d3..ee079a7 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -4819,6 +4819,22 @@
bool inOut = paramTy->is<InOutType>();
return {isVariadic, autoclosure, escaping, inOut, isShared};
}
+
+/// \brief If this is a method in a type or extension thereof, compute
+/// and return a parameter to be used for the 'self' argument. The type of
+/// the parameter is the empty Type() if no 'self' argument should exist. This
+/// can only be used after name binding has resolved types.
+///
+/// \param isInitializingCtor Specifies whether we're computing the 'self'
+/// type of an initializing constructor, which accepts an instance 'self'
+/// rather than a metatype 'self'.
+///
+/// \param wantDynamicSelf Specifies whether the 'self' type should be
+/// wrapped in a DynamicSelfType, which is the case for the 'self' parameter
+/// type inside a class method returning 'Self'.
+AnyFunctionType::Param computeSelfParam(AbstractFunctionDecl *AFD,
+ bool isInitializingCtor=false,
+ bool wantDynamicSelf=false);
#define TYPE(id, parent)
#define SUGARED_TYPE(id, parent) \
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 8305984..3f2815b 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -1210,11 +1210,11 @@
ARGS(ErrorPtrTy, Int8PtrPtrTy, OpenedErrorTriplePtrTy),
ATTRS(NoUnwind))
-// void __tsan_write1(void *addr);
+// void __tsan_external_write(void *addr, void *caller_pc, void *tag);
// This is a Thread Sanitizer instrumentation entry point in compiler-rt.
-FUNCTION(TSanInoutAccess, __tsan_write1, C_CC,
+FUNCTION(TSanInoutAccess, __tsan_external_write, C_CC,
RETURNS(VoidTy),
- ARGS(Int8PtrTy),
+ ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy),
ATTRS(NoUnwind))
FUNCTION(GetKeyPath, swift_getKeyPath, C_CC,
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3a1b36a..04bf012 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2775,6 +2775,61 @@
return Ty;
}
+AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
+ bool isInitializingCtor,
+ bool wantDynamicSelf) {
+ auto *dc = AFD->getDeclContext();
+ auto &Ctx = dc->getASTContext();
+
+ // Determine the type of the container.
+ auto containerTy = dc->getDeclaredInterfaceType();
+ if (!containerTy || containerTy->hasError())
+ return AnyFunctionType::Param(ErrorType::get(Ctx), Identifier(),
+ ParameterTypeFlags());
+
+ // Determine the type of 'self' inside the container.
+ auto selfTy = dc->getSelfInterfaceType();
+ if (!selfTy || selfTy->hasError())
+ return AnyFunctionType::Param(ErrorType::get(Ctx), Identifier(),
+ ParameterTypeFlags());
+
+ bool isStatic = false;
+ bool isMutating = false;
+
+ if (auto *FD = dyn_cast<FuncDecl>(AFD)) {
+ isStatic = FD->isStatic();
+ isMutating = FD->isMutating();
+
+ if (wantDynamicSelf && FD->hasDynamicSelf())
+ selfTy = DynamicSelfType::get(selfTy, Ctx);
+ } else if (isa<ConstructorDecl>(AFD)) {
+ if (isInitializingCtor) {
+ // initializing constructors of value types always have an implicitly
+ // inout self.
+ isMutating = true;
+ } else {
+ // allocating constructors have metatype 'self'.
+ isStatic = true;
+ }
+ } else if (isa<DestructorDecl>(AFD)) {
+ // destructors of value types always have an implicitly inout self.
+ isMutating = true;
+ }
+
+ // 'static' functions have 'self' of type metatype<T>.
+ if (isStatic)
+ return AnyFunctionType::Param(MetatypeType::get(selfTy, Ctx), Identifier(),
+ ParameterTypeFlags());
+
+ // Reference types have 'self' of type T.
+ if (containerTy->hasReferenceSemantics())
+ return AnyFunctionType::Param(selfTy, Identifier(),
+ ParameterTypeFlags());
+
+ return AnyFunctionType::Param(selfTy, Identifier(),
+ ParameterTypeFlags().withInOut(isMutating));
+}
+
void UnboundGenericType::Profile(llvm::FoldingSetNodeID &ID,
GenericTypeDecl *TheDecl, Type Parent) {
ID.AddPointer(TheDecl);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index e435e39..7de5535 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2403,14 +2403,19 @@
underlying = mapTypeOutOfContext(underlying);
UnderlyingTy.setType(underlying);
- // Create a NameAliasType which will resolve to the underlying type.
- ASTContext &Ctx = getASTContext();
- auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
- aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
- ->getRecursiveProperties());
+ // FIXME -- if we already have an interface type, we're changing the
+ // underlying type. See the comment in the ProtocolDecl case of
+ // validateDecl().
+ if (!hasInterfaceType()) {
+ // Create a NameAliasType which will resolve to the underlying type.
+ ASTContext &Ctx = getASTContext();
+ auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
+ aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
+ ->getRecursiveProperties());
- // Set the interface type of this declaration.
- setInterfaceType(MetatypeType::get(aliasTy, Ctx));
+ // Set the interface type of this declaration.
+ setInterfaceType(MetatypeType::get(aliasTy, Ctx));
+ }
}
UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {
@@ -4412,61 +4417,6 @@
return { getSubscriptLoc(), ElementTy.getSourceRange().End };
}
-Type AbstractFunctionDecl::computeInterfaceSelfType(bool isInitializingCtor,
- bool wantDynamicSelf) {
- auto *dc = getDeclContext();
- auto &Ctx = dc->getASTContext();
-
- // Determine the type of the container.
- auto containerTy = dc->getDeclaredInterfaceType();
- if (!containerTy || containerTy->hasError())
- return ErrorType::get(Ctx);
-
- // Determine the type of 'self' inside the container.
- auto selfTy = dc->getSelfInterfaceType();
- if (!selfTy || selfTy->hasError())
- return ErrorType::get(Ctx);
-
- bool isStatic = false;
- bool isMutating = false;
-
- if (auto *FD = dyn_cast<FuncDecl>(this)) {
- isStatic = FD->isStatic();
- isMutating = FD->isMutating();
-
- if (wantDynamicSelf && FD->hasDynamicSelf())
- selfTy = DynamicSelfType::get(selfTy, Ctx);
- } else if (isa<ConstructorDecl>(this)) {
- if (isInitializingCtor) {
- // initializing constructors of value types always have an implicitly
- // inout self.
- isMutating = true;
- } else {
- // allocating constructors have metatype 'self'.
- isStatic = true;
- }
- } else if (isa<DestructorDecl>(this)) {
- // destructors of value types always have an implicitly inout self.
- isMutating = true;
- }
-
- // 'static' functions have 'self' of type metatype<T>.
- if (isStatic)
- return MetatypeType::get(selfTy, Ctx);
-
- // Reference types have 'self' of type T.
- if (containerTy->hasReferenceSemantics())
- return selfTy;
-
- // Mutating methods are always passed inout so we can receive the side
- // effect.
- if (isMutating)
- return InOutType::get(selfTy);
-
- // Nonmutating methods on structs and enums pass the receiver by value.
- return selfTy;
-}
-
DeclName AbstractFunctionDecl::getEffectiveFullName() const {
if (getFullName())
return getFullName();
diff --git a/lib/IRGen/IRGenFunction.cpp b/lib/IRGen/IRGenFunction.cpp
index e9a95db..1d726bf 100644
--- a/lib/IRGen/IRGenFunction.cpp
+++ b/lib/IRGen/IRGenFunction.cpp
@@ -250,7 +250,18 @@
llvm::Function *fn = cast<llvm::Function>(IGM.getTSanInoutAccessFn());
llvm::Value *castAddress = Builder.CreateBitCast(address, IGM.Int8PtrTy);
- Builder.CreateCall(fn, {castAddress});
+
+ // Passing 0 as the caller PC causes compiler-rt to get our PC.
+ llvm::Value *callerPC = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
+
+ // A magic number agreed upon with compiler-rt to indicate a modifying
+ // access.
+ const unsigned kExternalTagSwiftModifyingAccess = 0x1;
+ llvm::Value *tagValue =
+ llvm::ConstantInt::get(IGM.SizeTy, kExternalTagSwiftModifyingAccess);
+ llvm::Value *castTag = Builder.CreateIntToPtr(tagValue, IGM.Int8PtrTy);
+
+ Builder.CreateCall(fn, {castAddress, callerPC, castTag});
}
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 9973f28..845b7bd 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -511,48 +511,76 @@
void visitTopLevelParams(AbstractionPattern origType,
CanAnyFunctionType::CanParamArrayRef params,
AnyFunctionType::ExtInfo extInfo) {
- // If we don't have 'self', we don't need to do anything special.
- if (!extInfo.hasSelfParam() && !Foreign.Self.isImportAsMember()) {
- // Add any leading foreign parameters.
- maybeAddForeignParameters();
-
- if (params.empty()) {
- visit(origType, M.getASTContext().TheEmptyTupleType);
- } else {
- CanType ty = AnyFunctionType::composeInput(M.getASTContext(), params,
- /*canonicalVararg*/true)
- ->getCanonicalType();
- visit(origType, ty);
- }
- return;
- }
-
- // Okay, handle 'self'.
-
unsigned numEltTypes = params.size();
- assert(numEltTypes > 0);
unsigned numNonSelfParams = numEltTypes - 1;
-
+
// We have to declare this out here so that the lambda scope lasts for
// the duration of the loop below.
auto handleForeignSelf = [&] {
visit(origType.getTupleElementType(numNonSelfParams),
params[numNonSelfParams].getType());
};
-
+
// If we have a foreign-self, install handleSelf as the handler.
if (Foreign.Self.isInstance()) {
+ assert(numEltTypes > 0);
// This is safe because function_ref just stores a pointer to the
// existing lambda object.
HandleForeignSelf = handleForeignSelf;
}
-
- // Now we can add any leading foreign parameters.
+
+ // Add any leading foreign parameters.
maybeAddForeignParameters();
+
+ // If we have no parameters, even 'self' parameters, bail unless we need
+ // to substitute.
+ if (params.empty()) {
+ if (origType.isTypeParameter())
+ visit(origType, M.getASTContext().TheEmptyTupleType);
+ return;
+ }
+
+ assert(numEltTypes > 0);
+
+ // If we don't have 'self', we don't need to do anything special.
+ if (!extInfo.hasSelfParam() && !Foreign.Self.isImportAsMember()) {
+ CanType ty = AnyFunctionType::composeInput(M.getASTContext(), params,
+ /*canonicalVararg*/true)
+ ->getCanonicalType();
+ CanTupleType tty = dyn_cast<TupleType>(ty);
+ if (!tty || (origType.isTypeParameter() && !tty->hasInOutElement())) {
+ visit(origType, ty);
+ return;
+ }
+
+ // If the abstraction pattern is opaque, and the tuple type is
+ // materializable -- if it doesn't contain an l-value type -- then it's
+ // a valid target for substitution and we should not expand it.
+ for (auto i : indices(tty.getElementTypes())) {
+ visit(origType.getTupleElementType(i), tty.getElementType(i));
+ }
+ return;
+ }
+
+ // Okay, handle 'self'.
// Process all the non-self parameters.
for (unsigned i = 0; i != numNonSelfParams; ++i) {
- visit(origType.getTupleElementType(i), params[i].getType());
+ CanType ty = params[i].getType();
+ CanTupleType tty = dyn_cast<TupleType>(ty);
+ AbstractionPattern eltPattern = origType.getTupleElementType(i);
+ if (!tty || (eltPattern.isTypeParameter() && !tty->hasInOutElement())) {
+ visit(eltPattern, ty);
+ continue;
+ }
+
+ assert(eltPattern.isTuple());
+ // If the abstraction pattern is opaque, and the tuple type is
+ // materializable -- if it doesn't contain an l-value type -- then it's
+ // a valid target for substitution and we should not expand it.
+ for (unsigned j = 0; j < eltPattern.getNumTupleElements(); ++j) {
+ visit(eltPattern.getTupleElementType(j), tty.getElementType(j));
+ }
}
// Process the self parameter. Note that we implicitly drop self
@@ -568,15 +596,10 @@
}
void visit(AbstractionPattern origType, CanType substType) {
- // Expand tuples. But if the abstraction pattern is opaque, and
- // the tuple type is materializable -- if it doesn't contain an
- // l-value type -- then it's a valid target for substitution and
- // we should not expand it.
+ // Expand tuples.
CanTupleType substTupleTy = dyn_cast<TupleType>(substType);
- if (substTupleTy &&
- (!origType.isTypeParameter() || substTupleTy->hasInOutElement())) {
- assert(origType.isTypeParameter() ||
- origType.getNumTupleElements() == substTupleTy->getNumElements());
+ if (substTupleTy && !origType.isTypeParameter()) {
+ assert(origType.getNumTupleElements() == substTupleTy->getNumElements());
for (auto i : indices(substTupleTy.getElementTypes())) {
visit(origType.getTupleElementType(i),
substTupleTy.getElementType(i));
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index ab627d2..727353d 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -1092,8 +1092,8 @@
ArgumentSource self = [&] {
if (!baseLV.isValid()) {
return ArgumentSource();
- } else if (cast<FuncDecl>(setter.getDecl())->computeInterfaceSelfType()
- ->is<InOutType>()) {
+ } else if (computeSelfParam(cast<FuncDecl>(setter.getDecl()))
+ .getParameterFlags().isInOut()) {
return ArgumentSource(loc, std::move(baseLV));
} else {
return emitBaseValueForAccessor(SGF, loc, std::move(baseLV),
diff --git a/lib/SILGen/SILGenMaterializeForSet.cpp b/lib/SILGen/SILGenMaterializeForSet.cpp
index aa1ae8b..0f9f82e 100644
--- a/lib/SILGen/SILGenMaterializeForSet.cpp
+++ b/lib/SILGen/SILGenMaterializeForSet.cpp
@@ -435,7 +435,7 @@
}
CanType witnessSelfType =
- Witness->computeInterfaceSelfType()->getCanonicalType(
+ computeSelfParam(Witness).getType()->getCanonicalType(
GenericSig, *SGM.M.getSwiftModule());
witnessSelfType = getSubstWitnessInterfaceType(witnessSelfType);
diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp
index a74dee1..a194283 100644
--- a/lib/Sema/DerivedConformanceCodable.cpp
+++ b/lib/Sema/DerivedConformanceCodable.cpp
@@ -1068,21 +1068,23 @@
initDecl->getAttrs().add(reqAttr);
}
- Type selfType = initDecl->computeInterfaceSelfType();
- Type selfInitType = initDecl->computeInterfaceSelfType(/*init=*/true);
+ auto selfParam = computeSelfParam(initDecl);
+ auto initSelfParam = computeSelfParam(initDecl, /*init=*/true);
Type interfaceType;
Type initializerType;
if (auto sig = target->getGenericSignatureOfContext()) {
// Evaluate the below, but in a generic environment (if Self is generic).
initDecl->setGenericEnvironment(target->getGenericEnvironmentOfContext());
- interfaceType = GenericFunctionType::get(sig, selfType, innerType,
+ interfaceType = GenericFunctionType::get(sig, {selfParam}, innerType,
FunctionType::ExtInfo());
- initializerType = GenericFunctionType::get(sig, selfInitType, innerType,
+ initializerType = GenericFunctionType::get(sig, {initSelfParam}, innerType,
FunctionType::ExtInfo());
} else {
// (Self) -> (Decoder) throws -> (Self)
- interfaceType = FunctionType::get(selfType, innerType);
- initializerType = FunctionType::get(selfInitType, innerType);
+ interfaceType = FunctionType::get({selfParam}, innerType,
+ FunctionType::ExtInfo());
+ initializerType = FunctionType::get({initSelfParam}, innerType,
+ FunctionType::ExtInfo());
}
initDecl->setInterfaceType(interfaceType);
diff --git a/lib/Sema/DerivedConformanceCodingKey.cpp b/lib/Sema/DerivedConformanceCodingKey.cpp
index bac6fc5..a271c5f 100644
--- a/lib/Sema/DerivedConformanceCodingKey.cpp
+++ b/lib/Sema/DerivedConformanceCodingKey.cpp
@@ -159,26 +159,25 @@
Type retInterfaceType =
OptionalType::get(parentDC->getDeclaredInterfaceType());
Type interfaceType = FunctionType::get(interfaceArgType, retInterfaceType);
- Type selfInterfaceType = initDecl->computeInterfaceSelfType();
- Type selfInitializerInterfaceType =
- initDecl->computeInterfaceSelfType(/*init*/ true);
+ auto selfParam = computeSelfParam(initDecl);
+ auto initSelfParam = computeSelfParam(initDecl, /*init*/ true);
Type allocIfaceType;
Type initIfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
initDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
- allocIfaceType = GenericFunctionType::get(sig, selfInterfaceType,
+ allocIfaceType = GenericFunctionType::get(sig, {selfParam},
interfaceType,
FunctionType::ExtInfo());
- initIfaceType = GenericFunctionType::get(sig, selfInitializerInterfaceType,
+ initIfaceType = GenericFunctionType::get(sig, {initSelfParam},
interfaceType,
FunctionType::ExtInfo());
} else {
- allocIfaceType = FunctionType::get(selfInterfaceType,
- interfaceType);
- initIfaceType = FunctionType::get(selfInitializerInterfaceType,
- interfaceType);
+ allocIfaceType = FunctionType::get({selfParam},
+ interfaceType, FunctionType::ExtInfo());
+ initIfaceType = FunctionType::get({initSelfParam},
+ interfaceType, FunctionType::ExtInfo());
}
initDecl->setInterfaceType(allocIfaceType);
initDecl->setInitializerInterfaceType(initIfaceType);
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 245ae54..cc6e63e 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -277,7 +277,7 @@
// Compute the interface type.
Type interfaceTy;
- Type selfIfaceTy = eqDecl->computeInterfaceSelfType();
+ auto selfParam = computeSelfParam(eqDecl);
if (auto genericSig = parentDC->getGenericSignatureOfContext()) {
eqDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
@@ -288,11 +288,12 @@
auto ifaceParamsTy = TupleType::get(ifaceParamElts, C);
interfaceTy = FunctionType::get(ifaceParamsTy, boolTy,
AnyFunctionType::ExtInfo());
- interfaceTy = GenericFunctionType::get(genericSig, selfIfaceTy, interfaceTy,
+ interfaceTy = GenericFunctionType::get(genericSig, {selfParam}, interfaceTy,
AnyFunctionType::ExtInfo());
} else {
interfaceTy = FunctionType::get(paramsTy, boolTy);
- interfaceTy = FunctionType::get(selfIfaceTy, interfaceTy);
+ interfaceTy = FunctionType::get({selfParam}, interfaceTy,
+ FunctionType::ExtInfo());
}
eqDecl->setInterfaceType(interfaceTy);
@@ -419,13 +420,14 @@
// Compute the interface type of hashValue().
Type interfaceType;
- Type selfIfaceType = getterDecl->computeInterfaceSelfType();
+ auto selfParam = computeSelfParam(getterDecl);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
- interfaceType = GenericFunctionType::get(sig, selfIfaceType, methodType,
+ interfaceType = GenericFunctionType::get(sig, {selfParam}, methodType,
AnyFunctionType::ExtInfo());
} else
- interfaceType = FunctionType::get(selfIfaceType, methodType);
+ interfaceType = FunctionType::get({selfParam}, methodType,
+ AnyFunctionType::ExtInfo());
getterDecl->setInterfaceType(interfaceType);
getterDecl->setAccessibility(std::max(Accessibility::Internal,
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index 6b01759..b509bfe 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -296,26 +296,25 @@
Type retInterfaceType
= OptionalType::get(parentDC->getDeclaredInterfaceType());
Type interfaceType = FunctionType::get(interfaceArgType, retInterfaceType);
- Type selfInterfaceType = initDecl->computeInterfaceSelfType();
- Type selfInitializerInterfaceType
- = initDecl->computeInterfaceSelfType(/*init*/ true);
+ auto selfParam = computeSelfParam(initDecl);
+ auto initSelfParam = computeSelfParam(initDecl, /*init*/ true);
Type allocIfaceType;
Type initIfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
initDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
- allocIfaceType = GenericFunctionType::get(sig, selfInterfaceType,
+ allocIfaceType = GenericFunctionType::get(sig, {selfParam},
interfaceType,
FunctionType::ExtInfo());
- initIfaceType = GenericFunctionType::get(sig, selfInitializerInterfaceType,
+ initIfaceType = GenericFunctionType::get(sig, {initSelfParam},
interfaceType,
FunctionType::ExtInfo());
} else {
- allocIfaceType = FunctionType::get(selfInterfaceType,
- interfaceType);
- initIfaceType = FunctionType::get(selfInitializerInterfaceType,
- interfaceType);
+ allocIfaceType = FunctionType::get({selfParam},
+ interfaceType, FunctionType::ExtInfo());
+ initIfaceType = FunctionType::get({initSelfParam},
+ interfaceType, FunctionType::ExtInfo());
}
initDecl->setInterfaceType(allocIfaceType);
initDecl->setInitializerInterfaceType(initIfaceType);
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index 5c890bb..6e31c4d 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -160,15 +160,16 @@
// Compute the interface type of the getter.
Type interfaceType = FunctionType::get(TupleType::getEmpty(C),
propertyInterfaceType);
- Type selfInterfaceType = getterDecl->computeInterfaceSelfType();
+ auto selfParam = computeSelfParam(getterDecl);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericEnvironment(
parentDC->getGenericEnvironmentOfContext());
- interfaceType = GenericFunctionType::get(sig, selfInterfaceType,
+ interfaceType = GenericFunctionType::get(sig, {selfParam},
interfaceType,
FunctionType::ExtInfo());
} else
- interfaceType = FunctionType::get(selfInterfaceType, interfaceType);
+ interfaceType = FunctionType::get({selfParam}, interfaceType,
+ FunctionType::ExtInfo());
getterDecl->setInterfaceType(interfaceType);
getterDecl->setAccessibility(std::max(typeDecl->getFormalAccess(),
Accessibility::Internal));
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 6ed2b76..8397811 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -1268,31 +1268,29 @@
auto selfDecl = func->getImplicitSelfDecl();
// Compute the type of self.
- Type selfIfaceTy = func->computeInterfaceSelfType(/*isInitializingCtor*/true,
- /*wantDynamicSelf*/true);
- assert(selfDecl && selfIfaceTy && "Not a method");
+ auto selfParam = computeSelfParam(func, /*isInitializingCtor*/true,
+ /*wantDynamicSelf*/true);
+ assert(selfDecl && selfParam.getPlainType() && "Not a method");
// 'self' is 'let' for reference types (i.e., classes) or when 'self' is
// neither inout.
- auto specifier = selfIfaceTy->is<InOutType>()
+ auto specifier = selfParam.getParameterFlags().isInOut()
? VarDecl::Specifier::InOut
: VarDecl::Specifier::Owned;
selfDecl->setSpecifier(specifier);
- selfDecl->setInterfaceType(selfIfaceTy->getInOutObjectType());
+ selfDecl->setInterfaceType(selfParam.getPlainType());
}
/// Record the context type of 'self' after the generic environment of
/// the function has been determined.
static void recordSelfContextType(AbstractFunctionDecl *func) {
auto selfDecl = func->getImplicitSelfDecl();
- Type selfTy = func->computeInterfaceSelfType(/*isInitializingCtor*/true,
- /*wantDynamicSelf*/true);
+ auto selfParam = computeSelfParam(func, /*isInitializingCtor*/true,
+ /*wantDynamicSelf*/true);
- selfTy = func->mapTypeIntoContext(selfTy);
- // FIXME(Remove InOutType): 'computeInterfaceSelfType' should tell us if
- // we need to do this.
- if (selfTy->is<InOutType>()) {
+ auto selfTy = func->mapTypeIntoContext(selfParam.getType());
+ if (selfParam.getParameterFlags().isInOut()) {
selfDecl->setSpecifier(VarDecl::Specifier::InOut);
}
selfDecl->setType(selfTy->getInOutObjectType());
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index bb0b691..2ea8901 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -858,22 +858,12 @@
SmallVector<AnyFunctionType::Param, 4> argTy;
SmallVector<AnyFunctionType::Param, 4> initArgTy;
- if (i == e-1 && hasSelf) {
- auto ifTy = func->computeInterfaceSelfType();
- auto selfTy = AnyFunctionType::Param(ifTy->getInOutObjectType(),
- Identifier(),
- ParameterTypeFlags().withInOut(ifTy->is<InOutType>()));
-
+ if (i == e-1 && hasSelf) {
// Substitute in our own 'self' parameter.
- argTy.push_back(selfTy);
+ argTy.push_back(computeSelfParam(func));
if (initFuncTy) {
- auto ifTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/true);
-
- initArgTy.push_back(
- AnyFunctionType::Param(
- ifTy->getInOutObjectType(),
- Identifier(), ParameterTypeFlags().withInOut(ifTy->is<InOutType>())));
+ initArgTy.push_back(computeSelfParam(func, /*isInitializingCtor=*/true));
}
} else {
AnyFunctionType::decomposeInput(paramLists[e - i - 1]->getInterfaceType(Context), argTy);
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 0ebc461..b80eb73 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -3032,6 +3032,14 @@
}
if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(member)) {
+ // FIXME: If this is a protocol typealias and we haven't built the
+ // protocol's generic environment yet, do so now, to ensure the
+ // typealias's underlying type has fully resoved dependent
+ // member types.
+ if (auto *protoDecl = dyn_cast<ProtocolDecl>(aliasDecl->getDeclContext()))
+ if (protoDecl->getGenericEnvironment() == nullptr)
+ validateDecl(protoDecl);
+
if (aliasDecl->getGenericParams()) {
return UnboundGenericType::get(
aliasDecl, baseTy,
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 5283ac7..053b832 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -2651,15 +2651,15 @@
// Set the initializer interface type of the constructor.
auto allocType = ctor->getInterfaceType();
- auto selfTy = ctor->computeInterfaceSelfType(/*isInitializingCtor=*/true);
+ auto selfParam = computeSelfParam(ctor, /*isInitializingCtor=*/true);
if (auto polyFn = allocType->getAs<GenericFunctionType>()) {
ctor->setInitializerInterfaceType(
GenericFunctionType::get(polyFn->getGenericSignature(),
- selfTy, polyFn->getResult(),
+ {selfParam}, polyFn->getResult(),
polyFn->getExtInfo()));
} else {
auto fn = allocType->castTo<FunctionType>();
- ctor->setInitializerInterfaceType(FunctionType::get(selfTy,
+ ctor->setInitializerInterfaceType(FunctionType::get({selfParam},
fn->getResult(),
fn->getExtInfo()));
}
diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb
index b92ee16..d75e576 100644
--- a/stdlib/public/core/HashedCollections.swift.gyb
+++ b/stdlib/public/core/HashedCollections.swift.gyb
@@ -766,8 +766,10 @@
switch s._variantBuffer {
case .native(let buffer):
_variantBuffer = .native(buffer)
+#if _runtime(_ObjC)
case .cocoa(let owner):
_variantBuffer = .cocoa(owner)
+#endif
}
} else {
for item in sequence {
@@ -1238,17 +1240,13 @@
}
return true
+ #if _runtime(_ObjC)
case (_VariantSetBuffer.cocoa(let lhsCocoa),
_VariantSetBuffer.cocoa(let rhsCocoa)):
- #if _runtime(_ObjC)
return _stdlib_NSObject_isEqual(lhsCocoa.cocoaSet, rhsCocoa.cocoaSet)
- #else
- _sanityCheckFailure("internal error: unexpected cocoa set")
- #endif
case (_VariantSetBuffer.native(let lhsNative),
_VariantSetBuffer.cocoa(let rhsCocoa)):
- #if _runtime(_ObjC)
if lhsNative.count != rhsCocoa.count {
return false
@@ -1270,15 +1268,9 @@
return false
}
return true
- #else
- _sanityCheckFailure("internal error: unexpected cocoa set")
- #endif
case (_VariantSetBuffer.cocoa, _VariantSetBuffer.native):
- #if _runtime(_ObjC)
return rhs == lhs
- #else
- _sanityCheckFailure("internal error: unexpected cocoa set")
#endif
}
}
@@ -2622,16 +2614,12 @@
}
return true
- case (.cocoa(let lhsCocoa), .cocoa(let rhsCocoa)):
#if _runtime(_ObjC)
+ case (.cocoa(let lhsCocoa), .cocoa(let rhsCocoa)):
return _stdlib_NSObject_isEqual(
lhsCocoa.cocoaDictionary, rhsCocoa.cocoaDictionary)
- #else
- _sanityCheckFailure("internal error: unexpected cocoa dictionary")
- #endif
case (.native(let lhsNative), .cocoa(let rhsCocoa)):
- #if _runtime(_ObjC)
if lhsNative.count != rhsCocoa.count {
return false
@@ -2654,15 +2642,9 @@
continue
}
return true
- #else
- _sanityCheckFailure("internal error: unexpected cocoa dictionary")
- #endif
case (.cocoa, .native):
- #if _runtime(_ObjC)
return rhs == lhs
- #else
- _sanityCheckFailure("internal error: unexpected cocoa dictionary")
#endif
}
}
@@ -4436,10 +4418,6 @@
_sanityCheckFailure("this function should never be called")
}
}
-#else
-@_versioned
-@_fixed_layout
-internal struct _Cocoa${Self}Buffer {}
#endif
@_versioned
@@ -4448,7 +4426,9 @@
internal typealias NativeBuffer = _Native${Self}Buffer<${TypeParameters}>
internal typealias NativeIndex = _Native${Self}Index<${TypeParameters}>
+#if _runtime(_ObjC)
internal typealias CocoaBuffer = _Cocoa${Self}Buffer
+#endif
internal typealias SequenceElement = ${Sequence}
internal typealias SequenceElementWithoutLabels = ${Sequence}
internal typealias SelfType = _Variant${Self}Buffer
@@ -4459,7 +4439,9 @@
%end
case native(NativeBuffer)
+#if _runtime(_ObjC)
case cocoa(CocoaBuffer)
+#endif
@_versioned
@_transparent
@@ -4477,10 +4459,12 @@
switch self {
case .native:
return _isUnique_native(&self)
+#if _runtime(_ObjC)
case .cocoa:
// Don't consider Cocoa buffer mutable, even if it is mutable and is
// uniquely referenced.
return false
+#endif
}
}
@@ -4490,8 +4474,10 @@
switch self {
case .native(let buffer):
return buffer
+#if _runtime(_ObjC)
case .cocoa:
_sanityCheckFailure("internal error: not backed by native buffer")
+#endif
}
}
set {
@@ -4552,8 +4538,8 @@
return (reallocated: true,
capacityChanged: oldCapacity != newNativeBuffer.capacity)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
let cocoa${Self} = cocoaBuffer.cocoa${Self}
var newNativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
let oldCocoaIterator = _Cocoa${Self}Iterator(cocoa${Self})
@@ -4576,8 +4562,6 @@
self = .native(newNativeBuffer)
return (reallocated: true, capacityChanged: true)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4616,11 +4600,9 @@
case .native:
return Int(Double(asNative.capacity) /
_hashContainerDefaultMaxLoadFactorInverse)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return cocoaBuffer.count
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4639,11 +4621,9 @@
switch self {
case .native:
return ._native(asNative.startIndex)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return ._cocoa(cocoaBuffer.startIndex)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4656,11 +4636,9 @@
switch self {
case .native:
return ._native(asNative.endIndex)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return ._cocoa(cocoaBuffer.endIndex)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4674,11 +4652,9 @@
switch self {
case .native:
return ._native(asNative.index(after: i._nativeIndex))
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return ._cocoa(cocoaBuffer.index(after: i._cocoaIndex))
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4704,15 +4680,13 @@
return ._native(nativeIndex)
}
return nil
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
if let cocoaIndex = cocoaBuffer.index(forKey: anyObjectKey) {
return ._cocoa(cocoaIndex)
}
return nil
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4725,8 +4699,8 @@
switch self {
case .native:
return asNative.assertingGet(i._nativeIndex)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
%if Self == 'Set':
let anyObjectValue: AnyObject = cocoaBuffer.assertingGet(i._cocoaIndex)
let nativeValue = _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
@@ -4738,8 +4712,6 @@
let nativeValue = _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
return (nativeKey, nativeValue)
%end
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4752,14 +4724,12 @@
switch self {
case .native:
return asNative.assertingGet(key)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
// FIXME: This assumes that Key and Value are bridged verbatim.
let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
let anyObjectValue: AnyObject = cocoaBuffer.assertingGet(anyObjectKey)
return _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4788,11 +4758,9 @@
switch self {
case .native:
return asNative.maybeGet(key)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return SelfType.maybeGetFromCocoaBuffer(cocoaBuffer, forKey: key)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4846,12 +4814,10 @@
switch self {
case .native:
return nativeUpdateValue(value, forKey: key)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
migrateDataToNativeBuffer(cocoaBuffer)
return nativeUpdateValue(value, forKey: key)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4872,8 +4838,8 @@
switch self {
case .native:
return nativePointerToValue(at: i)
- case .cocoa(let cocoaStorage):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaStorage):
// We have to migrate the data to native storage before we can return a
// mutable pointer. But after we migrate, the Cocoa index becomes
// useless, so get the key first.
@@ -4885,8 +4851,6 @@
let nativeIndex = asNative.index(forKey: key)!
return nativePointerToValue(at: ._native(nativeIndex))
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4938,12 +4902,10 @@
switch self {
case .native:
return nativeInsert(value, forKey: key)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
migrateDataToNativeBuffer(cocoaBuffer)
return nativeInsert(value, forKey: key)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -4978,8 +4940,8 @@
switch self {
case .native:
return try nativeMapValues(transform)
- case .cocoa(let cocoaStorage):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaStorage):
var storage: _Variant${Self}Buffer<Key, T> = .native(
_Native${Self}Buffer<Key, T>(capacity: cocoaStorage.count))
@@ -4993,8 +4955,6 @@
}
return storage
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5042,12 +5002,10 @@
switch self {
case .native:
try nativeMerge(keysAndValues, uniquingKeysWith: combine)
- case .cocoa(let cocoaStorage):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaStorage):
migrateDataToNativeBuffer(cocoaStorage)
try nativeMerge(keysAndValues, uniquingKeysWith: combine)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5203,8 +5161,8 @@
switch self {
case .native:
return nativeRemove(at: index._nativeIndex)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
// We have to migrate the data first. But after we do so, the Cocoa
// index becomes useless, so get the key first.
//
@@ -5222,8 +5180,6 @@
%elif Self == 'Dictionary':
return (key, value._unsafelyUnwrappedUnchecked)
%end
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5237,16 +5193,14 @@
switch self {
case .native:
return nativeRemoveObject(forKey: key)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
if cocoaBuffer.maybeGet(anyObjectKey) == nil {
return nil
}
migrateDataToNativeBuffer(cocoaBuffer)
return nativeRemoveObject(forKey: key)
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5287,11 +5241,9 @@
switch self {
case .native:
nativeRemoveAll()
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
self = .native(NativeBuffer(minimumCapacity: cocoaBuffer.count))
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5304,11 +5256,9 @@
switch self {
case .native:
return asNative.count
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return cocoaBuffer.count
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5323,11 +5273,9 @@
case .native(let buffer):
return ._native(
start: asNative.startIndex, end: asNative.endIndex, buffer: buffer)
- case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
+ case .cocoa(let cocoaBuffer):
return ._cocoa(_Cocoa${Self}Iterator(cocoaBuffer.cocoa${Self}))
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
@@ -5441,17 +5389,19 @@
% end
}
-#else
-internal struct _Cocoa${Self}Index {}
#endif
internal enum ${Self}IndexRepresentation<${TypeParametersDecl}> {
typealias _Index = ${Self}Index<${TypeParameters}>
typealias _NativeIndex = _Index._NativeIndex
+#if _runtime(_ObjC)
typealias _CocoaIndex = _Index._CocoaIndex
+#endif
case _native(_NativeIndex)
+#if _runtime(_ObjC)
case _cocoa(_CocoaIndex)
+#endif
}
extension ${Self} {
@@ -5484,7 +5434,9 @@
// type for bridged NS${Self} in terms of Cocoa enumeration facilities.
internal typealias _NativeIndex = _Native${Self}Index<${TypeParameters}>
+#if _runtime(_ObjC)
internal typealias _CocoaIndex = _Cocoa${Self}Index
+#endif
%if Self == 'Set':
internal typealias Key = ${TypeParameters}
@@ -5515,8 +5467,10 @@
switch _value {
case ._native(let nativeIndex):
return nativeIndex
+#if _runtime(_ObjC)
case ._cocoa:
_sanityCheckFailure("internal error: does not contain a native index")
+#endif
}
}
@@ -5550,11 +5504,9 @@
switch (lhs._value, rhs._value) {
case (._native(let lhsNative), ._native(let rhsNative)):
return lhsNative == rhsNative
- case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
#if _runtime(_ObjC)
+ case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
return lhsCocoa == rhsCocoa
- #else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
default:
_preconditionFailure("comparing indexes from different sets")
@@ -5572,11 +5524,9 @@
switch (lhs._value, rhs._value) {
case (._native(let lhsNative), ._native(let rhsNative)):
return lhsNative < rhsNative
- case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
#if _runtime(_ObjC)
+ case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
return lhsCocoa < rhsCocoa
- #else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
default:
_preconditionFailure("comparing indexes from different sets")
@@ -5665,8 +5615,6 @@
%end
}
}
-#else
-final internal class _Cocoa${Self}Iterator {}
#endif
@_versioned
@@ -5684,7 +5632,9 @@
// state, so it should keep its own reference to the buffer.
case _native(
start: _NativeIndex, end: _NativeIndex, buffer: _NativeBuffer)
+#if _runtime(_ObjC)
case _cocoa(_Cocoa${Self}Iterator)
+#endif
}
/// An iterator over the members of a `${Self}<${TypeParameters}>`.
@@ -5743,8 +5693,10 @@
_state =
._native(start: buffer.index(after: startIndex), end: endIndex, buffer: buffer)
return result
+#if _runtime(_ObjC)
case ._cocoa:
_sanityCheckFailure("internal error: not backed by NS${Self}")
+#endif
}
}
@@ -5761,8 +5713,8 @@
switch _state {
case ._native:
return _nativeNext()
- case ._cocoa(let cocoaIterator):
#if _runtime(_ObjC)
+ case ._cocoa(let cocoaIterator):
%if Self == 'Set':
if let anyObjectElement = cocoaIterator.next() {
return _forceBridgeFromObjectiveC(anyObjectElement, Element.self)
@@ -5775,8 +5727,6 @@
}
%end
return nil
-#else
- _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
}
}
diff --git a/test/IRGen/tsan_instrumentation.sil b/test/IRGen/tsan_instrumentation.sil
index 690033a..48c952f 100644
--- a/test/IRGen/tsan_instrumentation.sil
+++ b/test/IRGen/tsan_instrumentation.sil
@@ -23,7 +23,7 @@
bb0:
%0 = global_addr @_T020tsan_instrumentation1gSiv : $*Int
%1 = builtin "tsanInoutAccess"(%0 : $*Int) : $()
-// CHECK: call void @__tsan_write1(i8* bitcast ([[GLOBAL]]* @_T020tsan_instrumentation1gSiv to i8*))
+// CHECK: call void @__tsan_external_write(i8* bitcast ([[GLOBAL]]* @_T020tsan_instrumentation1gSiv to i8*), i8* null, i8* inttoptr ({{(i32|i64)}} 1 to i8*))
%2 = tuple ()
return %2 : $()
diff --git a/test/Sanitizers/tsan-inout.swift b/test/Sanitizers/tsan-inout.swift
index b592677..6919706 100644
--- a/test/Sanitizers/tsan-inout.swift
+++ b/test/Sanitizers/tsan-inout.swift
@@ -76,7 +76,7 @@
thread: { _ = globalForGlobalStructMutatingMethod.read() },
thread: { globalForGlobalStructMutatingMethod.mutate() } )
// CHECK-LABEL: Running GlobalStructMutatingMethod
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is global
var globalForGlobalStructDifferentStoredPropertiesInout = UninstrumentedStruct()
@@ -84,7 +84,7 @@
thread: { uninstrumentedTakesInout(&globalForGlobalStructDifferentStoredPropertiesInout.storedProperty1) },
thread: { uninstrumentedTakesInout(&globalForGlobalStructDifferentStoredPropertiesInout.storedProperty2) } )
// CHECK-LABEL: Running GlobalStructDifferentStoredPropertiesInout
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is global
var globalForGlobalStructSameStoredPropertyInout = UninstrumentedStruct()
@@ -92,7 +92,7 @@
thread: { uninstrumentedTakesInout(&globalForGlobalStructSameStoredPropertyInout.storedProperty1) },
thread: { uninstrumentedTakesInout(&globalForGlobalStructSameStoredPropertyInout.storedProperty1) } )
// CHECK-LABEL: Running GlobalStructSameStoredPropertyInout
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
var globalForGlobalStructSubscriptDifferentIndexesInout = UninstrumentedStruct()
@@ -100,7 +100,7 @@
thread: { uninstrumentedTakesInout(&globalForGlobalStructSubscriptDifferentIndexesInout[0]) },
thread: { uninstrumentedTakesInout(&globalForGlobalStructSubscriptDifferentIndexesInout[1]) } )
// CHECK-LABEL: Running GlobalStructSubscriptDifferentIndexes
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is global
@@ -109,7 +109,7 @@
thread: { _ = globalForGlobalStructSubscriptDifferentIndexesGetSet[0] },
thread: { globalForGlobalStructSubscriptDifferentIndexesGetSet[1] = 12 } )
// CHECK-LABEL: Running GlobalStructSubscriptDifferentIndexesGetSet
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is global
var globalForGlobalClassGeneralMethods = UninstrumentedClass()
@@ -117,21 +117,21 @@
thread: { _ = globalForGlobalClassGeneralMethods.read() },
thread: { globalForGlobalClassGeneralMethods.mutate() } )
// CHECK-LABEL: Running GlobalClassGeneralMethods
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
var globalForGlobalClassDifferentStoredPropertiesInout = UninstrumentedClass()
testRace(name: "GlobalClassDifferentStoredPropertiesInout",
thread: { uninstrumentedTakesInout(&globalForGlobalClassDifferentStoredPropertiesInout.storedProperty1) },
thread: { uninstrumentedTakesInout(&globalForGlobalClassDifferentStoredPropertiesInout.storedProperty2) } )
// CHECK-LABEL: Running GlobalClassDifferentStoredPropertiesInout
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
var globalForGlobalClassSubscriptDifferentIndexesInout = UninstrumentedClass()
testRace(name: "GlobalClassSubscriptDifferentIndexesInout",
thread: { uninstrumentedTakesInout(&globalForGlobalClassSubscriptDifferentIndexesInout[0]) },
thread: { uninstrumentedTakesInout(&globalForGlobalClassSubscriptDifferentIndexesInout[1]) } )
// CHECK-LABEL: Running GlobalClassSubscriptDifferentIndexesInout
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
var globalForGlobalClassSameStoredPropertyInout = UninstrumentedClass()
@@ -139,7 +139,7 @@
thread: { uninstrumentedTakesInout(&globalForGlobalClassSameStoredPropertyInout.storedProperty1) },
thread: { uninstrumentedTakesInout(&globalForGlobalClassSameStoredPropertyInout.storedProperty1) } )
// CHECK-LABEL: Running GlobalClassSameStoredPropertyInout
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is heap block
// These access a global declared in the TSanUninstrumented module
@@ -147,7 +147,7 @@
thread: { uninstrumentedTakesInout(&storedGlobalInUninstrumentedModule1) },
thread: { uninstrumentedTakesInout(&storedGlobalInUninstrumentedModule1) } )
// CHECK-LABEL: Running InoutAccessToStoredGlobalInUninstrumentedModule
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is global
// These access a global declared in the TSanUninstrumented module.
@@ -165,14 +165,14 @@
thread: { uninstrumentedTakesInout(&computedGlobalInUninstrumentedModule1) },
thread: { uninstrumentedTakesInout(&computedGlobalInUninstrumentedModule1) } )
// CHECK-LABEL: Running InoutAccessToComputedGlobalInUninstrumentedModule
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
// These access a computed global declared in the TSanUninstrumented module
testRace(name: "ReadAndWriteToComputedGlobalInUninstrumentedModule",
thread: { computedGlobalInUninstrumentedModule2 = 7 },
thread: { _ = computedGlobalInUninstrumentedModule2 } )
// CHECK-LABEL: Running ReadAndWriteToComputedGlobalInUninstrumentedModule
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
@@ -183,7 +183,7 @@
thread: { _ = globalForGlobalUninstrumentedClassStoredPropertyMutatingMethod.storedStructProperty.read() },
thread: { globalForGlobalUninstrumentedClassStoredPropertyMutatingMethod.storedStructProperty.mutate() } )
// CHECK-LABEL: Running GlobalUninstrumentedClassStoredPropertyMutatingMethod
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
// Note: TSan doesn't see a race above because it doesn't see any load on the
// read side because the getter for the class property is not instrumented.
@@ -194,7 +194,7 @@
thread: { uninstrumentedTakesInout(&globalForGlobalUninstrumentedClassStoredPropertyInout.storedStructProperty.storedProperty1) },
thread: { uninstrumentedTakesInout(&globalForGlobalUninstrumentedClassStoredPropertyInout.storedStructProperty.storedProperty2) } )
// CHECK-LABEL: Running GlobalUninstrumentedClassStoredPropertyInout
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is heap block
// Note: TSan sees the race above because the inout instrumentation adds an
@@ -206,7 +206,7 @@
thread: { uninstrumentedTakesInout(&globalForGlobalUninstrumentedClassComputedPropertyInout.computedStructProperty.storedProperty1) },
thread: { uninstrumentedTakesInout(&globalForGlobalUninstrumentedClassComputedPropertyInout.computedStructProperty.storedProperty1) } )
// CHECK-LABEL: Running GlobalUninstrumentedClassComputedPropertyInout
-// CHECK-NO: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
// In the above the write in instrumented code is to the value buffer allocated
// at the call site so there is no data race if the getter and setters themselves
@@ -219,7 +219,7 @@
thread: { _ = globalForGlobalInstrumentedClassStoredPropertyMutatingMethod.storedStructProperty.read() },
thread: { globalForGlobalInstrumentedClassStoredPropertyMutatingMethod.storedStructProperty.mutate() } )
// CHECK-LABEL: Running GlobalInstrumentedClassStoredPropertyMutatingMethod
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is heap block
//
// TSan does see this above race because the getter and materializeForSet is instrumented
@@ -250,7 +250,7 @@
thread: { l.mutate() } )
}
// CHECK-LABEL: Running CapturedLocalStructMutatingMethod
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is heap block
@@ -261,7 +261,7 @@
thread: { uninstrumentedTakesInout(&l.storedProperty2) } )
}
// CHECK-LABEL: Running CapturedLocalStructDifferentStoredPropertiesInout
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is heap block
@@ -272,7 +272,7 @@
thread: { l.mutate() } )
}
// CHECK-LABEL: Running CapturedLocalClassGeneralMethods
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
func runCapturedLocalDifferentStoredPropertiesInout() {
@@ -282,7 +282,7 @@
thread: { uninstrumentedTakesInout(&l.storedProperty2) } )
}
// CHECK-LABEL: Running CapturedLocalClassDifferentStoredPropertiesInout
-// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: {{.*}} race
func runCapturedLocalSameStoredPropertyInout() {
let l = UninstrumentedClass()
@@ -291,7 +291,7 @@
thread: { uninstrumentedTakesInout(&l.storedProperty1) } )
}
// CHECK-LABEL: Running CapturedLocalClassSameStoredPropertyInout
-// CHECK: ThreadSanitizer: data race
+// CHECK: ThreadSanitizer: Swift access race
// CHECK: Location is heap block
runLocalTests()
diff --git a/validation-test/compiler_crashers/28821-isa-protocoldecl-nominal-cannot-be-a-protocol.swift b/validation-test/compiler_crashers/28821-isa-protocoldecl-nominal-cannot-be-a-protocol.swift
new file mode 100644
index 0000000..aac84e2
--- /dev/null
+++ b/validation-test/compiler_crashers/28821-isa-protocoldecl-nominal-cannot-be-a-protocol.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A{{}protocol A{func a:Self.a}typealias e:A.a
diff --git a/validation-test/compiler_crashers/28822-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift b/validation-test/compiler_crashers/28822-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
new file mode 100644
index 0000000..89bf788
--- /dev/null
+++ b/validation-test/compiler_crashers/28822-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+extension CountableRange{{}func a<a:A
+protocol A{typealias e:a{}class a
diff --git a/validation-test/compiler_crashers/28823-impl-getgraphindex-typevariables-size-out-of-bounds-index.swift b/validation-test/compiler_crashers/28823-impl-getgraphindex-typevariables-size-out-of-bounds-index.swift
new file mode 100644
index 0000000..c8ddcec
--- /dev/null
+++ b/validation-test/compiler_crashers/28823-impl-getgraphindex-typevariables-size-out-of-bounds-index.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+{{}as ManagedBuffer}{
diff --git a/validation-test/compiler_crashers/28824-hasval.swift b/validation-test/compiler_crashers/28824-hasval.swift
new file mode 100644
index 0000000..ac9769e
--- /dev/null
+++ b/validation-test/compiler_crashers/28824-hasval.swift
@@ -0,0 +1,12 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+extension CountableRange{protocol b{typealias a:RangeReplaceableCollection
+protocol P{}
+class a:RangeReplaceableCollection
diff --git a/validation-test/compiler_crashers/28825-isa-classdecl-nominaldecl-expected-a-class-here.swift b/validation-test/compiler_crashers/28825-isa-classdecl-nominaldecl-expected-a-class-here.swift
new file mode 100644
index 0000000..58385b5
--- /dev/null
+++ b/validation-test/compiler_crashers/28825-isa-classdecl-nominaldecl-expected-a-class-here.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol b:a{init(t:a}class a{class a
diff --git a/validation-test/compiler_crashers/28826-type-haserror-should-not-be-assigning-a-type-involving-errortype.swift b/validation-test/compiler_crashers/28826-type-haserror-should-not-be-assigning-a-type-involving-errortype.swift
new file mode 100644
index 0000000..83f9939
--- /dev/null
+++ b/validation-test/compiler_crashers/28826-type-haserror-should-not-be-assigning-a-type-involving-errortype.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A{{}protocol a{extension{class a<a{let d=a(class a<P
diff --git a/validation-test/compiler_crashers_2_fixed/0114-rdar33189068.swift b/validation-test/compiler_crashers_2_fixed/0114-rdar33189068.swift
new file mode 100644
index 0000000..aaa271d
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0114-rdar33189068.swift
@@ -0,0 +1,19 @@
+// RUN: %target-swift-frontend %s -typecheck
+
+struct Bar : BarProtocol {
+ typealias Element = Int
+}
+
+struct Foo: FooProtocol {
+ typealias Things = Bar
+ func thing() -> Thing {}
+}
+
+protocol BarProtocol {
+ associatedtype Element
+}
+
+protocol FooProtocol {
+ associatedtype Things: BarProtocol
+ typealias Thing = Things.Element
+}
diff --git a/validation-test/stdlib/Set.swift b/validation-test/stdlib/Set.swift
index 35b5cf9..6c6b106 100644
--- a/validation-test/stdlib/Set.swift
+++ b/validation-test/stdlib/Set.swift
@@ -129,8 +129,10 @@
switch s._variantBuffer {
case .native:
return true
+#if _runtime(_ObjC)
case .cocoa:
return false
+#endif
}
}