Merge pull request #14211 from apple/4.1-dont-hardcode-numbers-in-objc-block-sil
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ca05d11..cd2edc7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,23 @@
Swift 4.1
---------
+* [SE-0189][]
+
+ If an initializer is declared in a different module from a struct, it must
+ use `self.init(…)` or `self = …` before returning or accessing `self`.
+ Failure to do so will produce a warning in Swift 4 and an error in Swift 5.
+ This is to keep a client app from accidentally depending on a library's
+ implementation details, and matches an existing restriction for classes,
+ where cross-module initializers must be convenience initializers.
+
+ This will most commonly affect code that extends a struct imported from C.
+ However, most imported C structs are given a zeroing no-argument initializer,
+ which can be called as `self.init()` before modifying specific properties.
+
+ Swift library authors who wish to continue allowing initialization on a
+ per-member basis should explicitly declare a public memberwise initializer
+ for clients in other modules to use.
+
* [SE-0166][] / [SE-0143][]
The standard library now defines the conformances of `Optional`,
diff --git a/README.md b/README.md
index 7ef4f79..c0e977d 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@
#### macOS
-To build for macOS, you need [Xcode 9.2 beta 2](https://developer.apple.com/xcode/downloads/).
+To build for macOS, you need [Xcode 9.3 beta](https://developer.apple.com/xcode/downloads/).
The required version of Xcode changes frequently, and is often a beta release.
Check this document or the host information on <https://ci.swift.org> for the
current required version.
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index ece78b1..4048894 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1405,6 +1405,10 @@
(Type, Type, Type, Type, StringRef))
NOTE(types_not_equal_requirement,none,
"requirement specified as %0 == %1%2", (Type, Type, StringRef))
+ERROR(type_is_not_a_class,none,
+ "%0 requires that %1 be a class type", (Type, Type, Type))
+NOTE(anyobject_requirement,none,
+ "requirement specified as %0 : 'AnyObject'%2", (Type, Type, StringRef))
ERROR(non_class_cannot_conform_to_class_protocol,none,
"non-class type %0 cannot conform to class protocol %1",
(Type, Type))
diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h
index cdcbeac..5846ff7 100644
--- a/include/swift/AST/GenericSignature.h
+++ b/include/swift/AST/GenericSignature.h
@@ -147,7 +147,8 @@
/// requirements, first canonicalizing the types.
static CanGenericSignature getCanonical(
ArrayRef<GenericTypeParamType *> params,
- ArrayRef<Requirement> requirements);
+ ArrayRef<Requirement> requirements,
+ bool skipValidation = false);
/// Retrieve the generic parameters.
ArrayRef<GenericTypeParamType *> getGenericParams() const {
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 197a12b..688f2a2 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -670,6 +670,16 @@
/// with a class type.
bool mayHaveSuperclass();
+ /// Determine whether this type satisfies a class layout constraint, written
+ /// `T: AnyObject` in the source.
+ ///
+ /// A class layout constraint is satisfied when we have a single retainable
+ /// pointer as the representation, which includes:
+ /// - @objc existentials
+ /// - class constrained archetypes
+ /// - classes
+ bool satisfiesClassConstraint();
+
/// \brief Determine whether this type can be used as a base type for AST
/// name lookup, which is the case for nominal types, protocol compositions
/// and archetypes.
diff --git a/include/swift/IDE/CodeCompletion.h b/include/swift/IDE/CodeCompletion.h
index 509b125..be9461d 100644
--- a/include/swift/IDE/CodeCompletion.h
+++ b/include/swift/IDE/CodeCompletion.h
@@ -856,14 +856,17 @@
: public SimpleCachingCodeCompletionConsumer {
llvm::raw_ostream &OS;
bool IncludeKeywords;
+ bool IncludeComments;
public:
- PrintingCodeCompletionConsumer(llvm::raw_ostream &OS, bool IncludeKeywords = true)
- : OS(OS), IncludeKeywords(IncludeKeywords) {
- }
+ PrintingCodeCompletionConsumer(llvm::raw_ostream &OS,
+ bool IncludeKeywords = true,
+ bool IncludeComments = true)
+ : OS(OS),
+ IncludeKeywords(IncludeKeywords),
+ IncludeComments(IncludeComments) {}
- void handleResults(
- MutableArrayRef<CodeCompletionResult *> Results) override;
+ void handleResults(MutableArrayRef<CodeCompletionResult *> Results) override;
};
/// \brief Create a factory for code completion callbacks.
diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h
index 64273b8..4637e5a 100644
--- a/include/swift/SIL/TypeLowering.h
+++ b/include/swift/SIL/TypeLowering.h
@@ -259,14 +259,6 @@
enum class LoweringStyle { Shallow, Deep };
- /// Given the result of the expansion heuristic,
- /// return appropriate lowering style.
- static LoweringStyle getLoweringStyle(bool shouldExpand) {
- if (shouldExpand)
- return TypeLowering::LoweringStyle::Deep;
- return TypeLowering::LoweringStyle::Shallow;
- }
-
//===--------------------------------------------------------------------===//
// DestroyValue
//===--------------------------------------------------------------------===//
@@ -843,7 +835,8 @@
/// The ABI compatible relation is not symmetric on function types -- while
/// T and T! are both subtypes of each other, a calling convention conversion
/// of T! to T always requires a thunk.
- ABIDifference checkForABIDifferences(SILType type1, SILType type2);
+ ABIDifference checkForABIDifferences(SILType type1, SILType type2,
+ bool thunkOptionals = true);
/// \brief Same as above but for SIL function types.
ABIDifference checkFunctionForABIDifferences(SILFunctionType *fnTy1,
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 540f55b..7b79351 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -4182,8 +4182,8 @@
return false;
}
-/// Return true if this stored property needs to be accessed with getters and
-/// setters for Objective-C.
+/// Return true if this stored property has a getter and
+/// setter that are accessible from Objective-C.
bool AbstractStorageDecl::hasForeignGetterAndSetter() const {
if (auto override = getOverriddenDecl())
return override->hasForeignGetterAndSetter();
@@ -4204,9 +4204,11 @@
// Imported accessors are foreign and only have objc entry points.
if (hasClangNode())
return true;
- // Otherwise, we only dispatch by @objc if the declaration is dynamic or
- // NSManaged.
- return isDynamic() || getAttrs().hasAttribute<NSManagedAttr>();
+ // Otherwise, we only dispatch by @objc if the declaration is dynamic,
+ // NSManaged, or dispatched through an ObjC protocol.
+ return isDynamic()
+ || getAttrs().hasAttribute<NSManagedAttr>()
+ || (isa<ProtocolDecl>(getDeclContext()) && isProtocolRequirement());
}
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index e40b849..5121262 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -150,7 +150,8 @@
CanGenericSignature GenericSignature::getCanonical(
ArrayRef<GenericTypeParamType *> params,
- ArrayRef<Requirement> requirements) {
+ ArrayRef<Requirement> requirements,
+ bool skipValidation) {
// Canonicalize the parameters and requirements.
SmallVector<GenericTypeParamType*, 8> canonicalParams;
canonicalParams.reserve(params.size());
@@ -172,10 +173,14 @@
reqt.getLayoutConstraint()));
}
+ (void)skipValidation;
auto canSig = get(canonicalParams, canonicalRequirements,
/*isKnownCanonical=*/true);
#ifndef NDEBUG
+ if (skipValidation)
+ return CanGenericSignature(canSig);
+
PrettyStackTraceGenericSignature debugStack("canonicalizing", canSig);
// Check that the signature is canonical.
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index caf1d6a..1604066 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -3026,6 +3026,12 @@
TypeDecl *nestedTypeDecl;
SmallVector<TypeDecl *, 4> concreteDecls;
if (auto assocType = depMemTy->getAssocType()) {
+ // Check whether this associated type references a protocol to which
+ // the base conforms. If not, it's unresolved.
+ if (baseEquivClass->conformsTo.find(assocType->getProtocol())
+ == baseEquivClass->conformsTo.end())
+ return ResolvedType::forUnresolved(baseEquivClass);
+
nestedTypeDecl = assocType;
} else {
nestedTypeDecl =
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index 0c15ad8..af9f491 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -530,8 +530,9 @@
if (Loader)
resolveLazyInfo();
- if (TypeWitnesses.find(assocType) != TypeWitnesses.end()) {
- return true;
+ auto found = TypeWitnesses.find(assocType);
+ if (found != TypeWitnesses.end()) {
+ return !found->getSecond().first.isNull();
}
if (resolver) {
PrettyStackTraceRequirement trace("resolving", this, assocType);
@@ -556,24 +557,25 @@
if (known != TypeWitnesses.end())
return known->second;
- // If this conformance is in a state where it is inferring type witnesses,
- // check tentative witnesses.
- if (getState() == ProtocolConformanceState::CheckingTypeWitnesses) {
- // If there is a tentative-type-witness function, use it.
- if (options.getTentativeTypeWitness) {
- if (Type witnessType =
- Type(options.getTentativeTypeWitness(this, assocType)))
- return { witnessType, nullptr };
- }
+ // If there is a tentative-type-witness function, use it.
+ if (options.getTentativeTypeWitness) {
+ if (Type witnessType =
+ Type(options.getTentativeTypeWitness(this, assocType)))
+ return { witnessType, nullptr };
+ }
- // Otherwise, we fail; this is the only case in which we can return a
- // null type.
+ // If this conformance is in a state where it is inferring type witnesses but
+ // we didn't find anything, fail.
+ if (getState() == ProtocolConformanceState::CheckingTypeWitnesses) {
return { Type(), nullptr };
}
// Otherwise, resolve the type witness.
PrettyStackTraceRequirement trace("resolving", this, assocType);
assert(resolver && "Unable to resolve type witness");
+
+ // Block recursive resolution of this type witness.
+ TypeWitnesses[assocType] = { Type(), nullptr };
resolver->resolveTypeWitness(this, assocType);
known = TypeWitnesses.find(assocType);
@@ -586,7 +588,9 @@
TypeDecl *typeDecl) const {
assert(getProtocol() == cast<ProtocolDecl>(assocType->getDeclContext()) &&
"associated type in wrong protocol");
- assert(TypeWitnesses.count(assocType) == 0 && "Type witness already known");
+ assert((TypeWitnesses.count(assocType) == 0 ||
+ TypeWitnesses[assocType].first.isNull()) &&
+ "Type witness already known");
assert((!isComplete() || isInvalid()) && "Conformance already complete?");
assert(!type->hasArchetype() && "type witnesses must be interface types");
TypeWitnesses[assocType] = std::make_pair(type, typeDecl);
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 161a98c..51b6cd8 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1445,6 +1445,10 @@
return is<DynamicSelfType>();
}
+bool TypeBase::satisfiesClassConstraint() {
+ return mayHaveSuperclass() || isObjCExistentialType();
+}
+
Type TypeBase::getSuperclass() {
auto *nominalDecl = getAnyNominal();
auto *classDecl = dyn_cast_or_null<ClassDecl>(nominalDecl);
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 1d2e21e..bcc9180 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -1466,12 +1466,17 @@
// invalid, it can't be the same thing twice in a row, and it has to come
// from an actual buffer, so we make a fake buffer and just use a counter.
if (!Impl.DummyImportBuffer.isValid()) {
+ clang::SourceLocation includeLoc =
+ srcMgr.getLocForStartOfFile(srcMgr.getMainFileID());
+ // Zero offset is reserved for the bridging header. Increase the offset
+ // so that headers from the bridging header are considered as coming
+ // before headers that are imported from swift code.
+ includeLoc = includeLoc.getLocWithOffset(1);
Impl.DummyImportBuffer = srcMgr.createFileID(
llvm::make_unique<ZeroFilledMemoryBuffer>(
256*1024, StringRef(Implementation::moduleImportBufferName)),
clang::SrcMgr::C_User,
- /*LoadedID*/0, /*LoadedOffset*/0,
- srcMgr.getLocForStartOfFile(srcMgr.getMainFileID()));
+ /*LoadedID*/0, /*LoadedOffset*/0, includeLoc);
}
clang::SourceLocation clangImportLoc
= srcMgr.getLocForStartOfFile(Impl.DummyImportBuffer)
diff --git a/lib/ClangImporter/ImportEnumInfo.cpp b/lib/ClangImporter/ImportEnumInfo.cpp
index f9ac7cc..3037af6 100644
--- a/lib/ClangImporter/ImportEnumInfo.cpp
+++ b/lib/ClangImporter/ImportEnumInfo.cpp
@@ -308,6 +308,10 @@
// Don't use importFullName() here, we want to ignore the swift_name
// and swift_private attributes.
StringRef enumNameStr = decl->getName();
+ if (enumNameStr.empty())
+ enumNameStr = decl->getTypedefNameForAnonDecl()->getName();
+ assert(!enumNameStr.empty() && "should have been classified as Constants");
+
StringRef commonWithEnum = getCommonPluralPrefix(checkPrefix, enumNameStr);
size_t delta = commonPrefix.size() - checkPrefix.size();
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index e20b9c0..b220649 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -5509,6 +5509,11 @@
Result->getCompletionString()->getName(NameOs);
OS << "; name=" << Name;
+ StringRef comment = Result->getBriefDocComment();
+ if (IncludeComments && !comment.empty()) {
+ OS << "; comment=" << comment;
+ }
+
OS << "\n";
}
OS << "End completions\n";
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index febbc27..da39354 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -1686,16 +1686,25 @@
}
static std::unique_ptr<llvm::SetVector<Expr*>>
- findConcatenatedExpressions(ResolvedRangeInfo Info, ASTContext &Ctx) {
- if (Info.Kind != RangeKind::SingleExpression
- && Info.Kind != RangeKind::PartOfExpression)
- return nullptr;
+findConcatenatedExpressions(ResolvedRangeInfo Info, ASTContext &Ctx) {
+ Expr *E = nullptr;
- // FIXME: We should always have a valid node.
- if (Info.ContainedNodes.empty())
+ switch (Info.Kind) {
+ case RangeKind::SingleExpression:
+ // FIXME: the range info kind should imply non-empty list.
+ if (!Info.ContainedNodes.empty())
+ E = Info.ContainedNodes[0].get<Expr*>();
+ else
+ return nullptr;
+ break;
+ case RangeKind::PartOfExpression:
+ E = Info.CommonExprParent;
+ break;
+ default:
return nullptr;
+ }
- Expr *E = Info.ContainedNodes[0].get<Expr*>();
+ assert(E);
struct StringInterpolationExprFinder: public SourceEntityWalker {
std::unique_ptr<llvm::SetVector<Expr*>> Bucket = llvm::
@@ -1719,6 +1728,9 @@
bool walkToExprPre(Expr *E) {
if (E->isImplicit())
return true;
+ // FIXME: we should have ErrorType instead of null.
+ if (E->getType().isNull())
+ return true;
auto ExprType = E->getType()->getNominalOrBoundGenericNominal();
//Only binary concatenation operators should exist in expression
if (E->getKind() == ExprKind::Binary) {
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index b172a1e..5cd796d 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -192,8 +192,8 @@
ContainerType = SAE->getBase()->getType();
}
} else if (auto ME = dyn_cast<MemberRefExpr>(E)) {
- SourceLoc DotLoc = ME->getDotLoc();
- if (DotLoc.isValid() && DotLoc.getAdvancedLoc(1) == LocToResolve) {
+ SourceLoc MemberLoc = ME->getNameLoc().getBaseNameLoc();
+ if (MemberLoc.isValid() && MemberLoc == LocToResolve) {
ContainerType = ME->getBase()->getType();
}
}
diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp
index bd7bdfa..6cf7384 100644
--- a/lib/IRGen/GenBuiltin.cpp
+++ b/lib/IRGen/GenBuiltin.cpp
@@ -198,6 +198,11 @@
// At that stage, the function name GV used by the profiling pass is hidden.
// Fix the intrinsic call here by pointing it to the correct GV.
if (IID == llvm::Intrinsic::instrprof_increment) {
+ // If we import profiling intrinsics from a swift module but profiling is
+ // not enabled, ignore the increment.
+ if (!IGF.getSILModule().getOptions().GenerateProfile)
+ return;
+
// Extract the PGO function name.
auto *NameGEP = cast<llvm::User>(args.claimNext());
auto *NameGV = dyn_cast<llvm::GlobalVariable>(NameGEP->stripPointerCasts());
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index dfd6b5a..786c344 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -258,6 +258,8 @@
{
IRGenFunction IGF(IGM, layoutFn);
+ if (IGM.DebugInfo)
+ IGM.DebugInfo->emitArtificialFunction(IGF, layoutFn);
// Unmarshal the generic environment from the argument buffer.
auto parameters = IGF.collectParameters();
auto args = parameters.claimNext();
@@ -509,6 +511,9 @@
{
IRGenFunction IGF(IGM, initFn);
+ if (IGM.DebugInfo)
+ IGM.DebugInfo->emitArtificialFunction(IGF, initFn);
+
auto params = IGF.collectParameters();
// Pointer to the argument packet passed into swift_getKeyPath
auto src = params.claimNext();
diff --git a/lib/IRGen/StructLayout.cpp b/lib/IRGen/StructLayout.cpp
index 003caf3..a71bd64 100644
--- a/lib/IRGen/StructLayout.cpp
+++ b/lib/IRGen/StructLayout.cpp
@@ -215,6 +215,7 @@
if (eltTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
addEmptyElement(elt);
// If the element type is empty, it adds nothing.
+ NextNonFixedOffsetIndex++;
return false;
}
// TODO: consider using different layout rules.
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 3376344..5981cd2 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -2311,9 +2311,18 @@
if (inst->isTypeDependentOperand(*use))
continue;
switch (inst->getKind()) {
+ case SILInstructionKind::MarkDependenceInst:
+ break;
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst:
+ // Non-Mutating set pattern that allows a inout (that can't really
+ // write back.
+ if (auto *AI = dyn_cast<ApplyInst>(inst)) {
+ if (isa<PointerToThinFunctionInst>(AI->getCallee())) {
+ break;
+ }
+ }
if (isConsumingOrMutatingApplyUse(use))
return true;
else
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index 7c0b2ca..6dc9a84 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -2259,7 +2259,8 @@
/// Given that type1 is known to be a subtype of type2, check if the two
/// types have the same calling convention representation.
TypeConverter::ABIDifference
-TypeConverter::checkForABIDifferences(SILType type1, SILType type2) {
+TypeConverter::checkForABIDifferences(SILType type1, SILType type2,
+ bool thunkOptionals) {
// Unwrap optionals, but remember that we did.
bool type1WasOptional = false;
bool type2WasOptional = false;
@@ -2272,15 +2273,23 @@
type2 = object;
}
- // Forcing IUOs always requires a thunk.
- if (type1WasOptional && !type2WasOptional)
- return ABIDifference::NeedsThunk;
+ bool optionalityChange;
+ if (thunkOptionals) {
+ // Forcing IUOs always requires a thunk.
+ if (type1WasOptional && !type2WasOptional)
+ return ABIDifference::NeedsThunk;
- // Except for the above case, we should not be making a value less optional.
-
- // If we're introducing a level of optionality, only certain types are
- // ABI-compatible -- check below.
- bool optionalityChange = (!type1WasOptional && type2WasOptional);
+ // Except for the above case, we should not be making a value less optional.
+
+ // If we're introducing a level of optionality, only certain types are
+ // ABI-compatible -- check below.
+ optionalityChange = (!type1WasOptional && type2WasOptional);
+ } else {
+ // We haven't implemented codegen for optional thunking at all levels
+ // (particularly objc_blocks at depth). Just accept ABI compatibility
+ // in either direction in these cases.
+ optionalityChange = type1WasOptional != type2WasOptional;
+ }
// If the types are identical and there was no optionality change,
// we're done.
@@ -2290,10 +2299,8 @@
// Classes, class-constrained archetypes, and pure-ObjC existential types
// all have single retainable pointer representation; optionality change
// is allowed.
- if ((type1.getSwiftRValueType()->mayHaveSuperclass() ||
- type1.getSwiftRValueType()->isObjCExistentialType()) &&
- (type2.getSwiftRValueType()->mayHaveSuperclass() ||
- type2.getSwiftRValueType()->isObjCExistentialType()))
+ if (type1.getSwiftRValueType()->satisfiesClassConstraint() &&
+ type2.getSwiftRValueType()->satisfiesClassConstraint())
return ABIDifference::Trivial;
// Function parameters are ABI compatible if their differences are
@@ -2387,7 +2394,8 @@
return ABIDifference::NeedsThunk;
if (checkForABIDifferences(result1.getSILStorageType(),
- result2.getSILStorageType())
+ result2.getSILStorageType(),
+ /*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift)
!= ABIDifference::Trivial)
return ABIDifference::NeedsThunk;
}
@@ -2402,7 +2410,8 @@
return ABIDifference::NeedsThunk;
if (checkForABIDifferences(error1.getSILStorageType(),
- error2.getSILStorageType())
+ error2.getSILStorageType(),
+ /*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift)
!= ABIDifference::Trivial)
return ABIDifference::NeedsThunk;
}
@@ -2418,7 +2427,8 @@
std::swap(param1, param2);
if (checkForABIDifferences(param1.getSILStorageType(),
- param2.getSILStorageType())
+ param2.getSILStorageType(),
+ /*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift)
!= ABIDifference::Trivial)
return ABIDifference::NeedsThunk;
}
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 43cfbc7..f351e62 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -2766,12 +2766,13 @@
auto *vd = cast<ParamDecl>(dre->getDecl());
ManagedValue selfValue;
+ Scope S(SGF, loc);
+ Optional<FormalEvaluationScope> FES;
// If we have not exclusively borrowed self, we need to do so now.
if (SGF.SelfInitDelegationState == SILGenFunction::WillExclusiveBorrowSelf) {
// We need to use a full scope here to ensure that any underlying
// "normal cleanup" borrows are cleaned up.
- Scope S(SGF, loc);
- selfValue = S.popPreservingValue(SGF.emitRValueAsSingleValue(dre));
+ selfValue = SGF.emitRValueAsSingleValue(dre);
} else {
// If we already exclusively borrowed self, then we need to emit self
// using formal evaluation primitives.
@@ -2781,6 +2782,7 @@
// This needs to be inlined since there is a Formal Evaluation Scope
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
+ FES.emplace(SGF);
selfValue =
SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
AccessKind::Read, dre->getAccessSemantics());
@@ -2789,9 +2791,7 @@
selfValue.getLValueAddress(), ctx)
.getAsSingleValue(SGF, loc);
}
- assert(selfValue && !selfValue.hasCleanup());
- // Check if we need to perform a conversion here.
return SGF.B.createValueMetatype(loc, metaTy, selfValue.getValue());
}
@@ -2807,7 +2807,6 @@
SGFContext::AllowImmediatePlusZero).getValue();
return B.createExistentialMetatype(loc, metaTy, base);
}
-
SILType metaTy = getLoweredLoadableType(CanMetatypeType::get(baseTy));
// If the lowered metatype has a thick representation, we need to derive it
// dynamically from the instance.
@@ -2829,7 +2828,6 @@
return S.popPreservingValue(B.createValueMetatype(loc, metaTy, base))
.getValue();
}
-
// Otherwise, ignore the base and return the static thin metatype.
emitIgnoredExpr(baseExpr);
return B.createMetatype(loc, metaTy);
diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
index 24adca7..20f2eab 100644
--- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
@@ -295,6 +295,8 @@
} else {
Node->pointsTo = pointsTo;
}
+ // Update use-points if the use-point information is already calculated.
+ pointsTo->mergeUsePoints(Node);
}
// Add all adjacent nodes to the WorkList.
diff --git a/lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp b/lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp
index 3d8267f..235ec2b 100644
--- a/lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp
+++ b/lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp
@@ -112,8 +112,11 @@
// retain_value %new : $*T
IsTake_t IsTake = CA->isTakeOfSrc();
if (IsTake_t::IsNotTake == IsTake) {
- TL.emitLoweredCopyValue(Builder, CA->getLoc(), New,
- TypeLowering::getLoweringStyle(expand));
+ if (expand) {
+ TL.emitLoweredCopyValueDeep(Builder, CA->getLoc(), New);
+ } else {
+ TL.emitCopyValue(Builder, CA->getLoc(), New);
+ }
}
// If we are not initializing:
@@ -121,8 +124,11 @@
// *or*
// release_value %old : $*T
if (Old) {
- TL.emitLoweredDestroyValue(Builder, CA->getLoc(), Old,
- TypeLowering::getLoweringStyle(expand));
+ if (expand) {
+ TL.emitLoweredDestroyValueDeep(Builder, CA->getLoc(), Old);
+ } else {
+ TL.emitDestroyValue(Builder, CA->getLoc(), Old);
+ }
}
}
@@ -155,8 +161,11 @@
LoadInst *LI = Builder.createLoad(DA->getLoc(), Addr,
LoadOwnershipQualifier::Unqualified);
auto &TL = Module.getTypeLowering(Type);
- TL.emitLoweredDestroyValue(Builder, DA->getLoc(), LI,
- TypeLowering::getLoweringStyle(expand));
+ if (expand) {
+ TL.emitLoweredDestroyValueDeep(Builder, DA->getLoc(), LI);
+ } else {
+ TL.emitDestroyValue(Builder, DA->getLoc(), LI);
+ }
}
++NumExpand;
diff --git a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp
index 1dfc54d..b0e98bb 100644
--- a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp
+++ b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp
@@ -350,8 +350,12 @@
bool expand = shouldExpand(DAI->getModule(),
DAI->getOperand()->getType().getObjectType());
- TL.emitLoweredDestroyValue(Builder, DAI->getLoc(), NewValue,
- Lowering::TypeLowering::getLoweringStyle(expand));
+ if (expand) {
+ TL.emitLoweredDestroyValueDeep(Builder, DAI->getLoc(), NewValue);
+ } else {
+ TL.emitDestroyValue(Builder, DAI->getLoc(), NewValue);
+ }
+
DAI->eraseFromParent();
}
diff --git a/lib/SILOptimizer/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp
index 5c5ef11..d85ebb0 100644
--- a/lib/SILOptimizer/Utils/Local.cpp
+++ b/lib/SILOptimizer/Utils/Local.cpp
@@ -1457,8 +1457,10 @@
} else if (isConditional) {
SILBasicBlock *CastSuccessBB = Inst->getFunction()->createBasicBlock();
CastSuccessBB->createPHIArgument(SILBridgedTy, ValueOwnershipKind::Owned);
- NewI = Builder.createCheckedCastBranch(Loc, false, Load, SILBridgedTy,
- CastSuccessBB, ConvFailBB);
+ auto *CCBI = Builder.createCheckedCastBranch(Loc, false, Load,
+ SILBridgedTy, CastSuccessBB, ConvFailBB);
+ NewI = CCBI;
+ splitEdge(CCBI, /* EdgeIdx to ConvFailBB */ 1);
Builder.setInsertionPoint(CastSuccessBB);
SrcOp = CastSuccessBB->getArgument(0);
} else {
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 0a755f1..d5ac9b7 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -321,6 +321,85 @@
return true;
}
+/// Determine whether the given type refers to a non-final class (or
+/// dynamic self of one).
+static bool isNonFinalClass(Type type) {
+ if (auto dynamicSelf = type->getAs<DynamicSelfType>())
+ type = dynamicSelf->getSelfType();
+
+ if (auto classDecl = type->getClassOrBoundGenericClass())
+ return !classDecl->isFinal();
+
+ if (auto archetype = type->getAs<ArchetypeType>())
+ if (auto super = archetype->getSuperclass())
+ return isNonFinalClass(super);
+
+ return false;
+}
+
+// Non-required constructors may not be not inherited. Therefore when
+// constructing a class object, either the metatype must be statically
+// derived (rather than an arbitrary value of metatype type) or the referenced
+// constructor must be required.
+static bool
+diagnoseInvalidDynamicConstructorReferences(ConstraintSystem &cs,
+ Expr *base,
+ DeclNameLoc memberRefLoc,
+ ConstructorDecl *ctorDecl,
+ bool SuppressDiagnostics) {
+ auto &tc = cs.getTypeChecker();
+ auto baseTy = cs.getType(base)->getRValueType();
+ auto instanceTy = baseTy->getRValueInstanceType();
+
+ bool isStaticallyDerived =
+ base->isStaticallyDerivedMetatype(
+ [&](const Expr *expr) -> Type {
+ return cs.getType(expr);
+ });
+
+ // 'super.' is always OK
+ if (isa<SuperRefExpr>(base))
+ return true;
+
+ // 'self.' reference with concrete type is OK
+ if (isa<DeclRefExpr>(base) &&
+ cast<DeclRefExpr>(base)->getDecl()->getBaseName() == tc.Context.Id_self &&
+ !baseTy->is<ArchetypeType>())
+ return true;
+
+ // FIXME: The "hasClangNode" check here is a complete hack.
+ if (isNonFinalClass(instanceTy) &&
+ !isStaticallyDerived &&
+ !ctorDecl->hasClangNode() &&
+ !(ctorDecl->isRequired() ||
+ ctorDecl->getDeclContext()->getAsProtocolOrProtocolExtensionContext())) {
+ if (SuppressDiagnostics)
+ return false;
+
+ tc.diagnose(memberRefLoc, diag::dynamic_construct_class, instanceTy)
+ .highlight(base->getSourceRange());
+ auto ctor = cast<ConstructorDecl>(ctorDecl);
+ tc.diagnose(ctorDecl, diag::note_nonrequired_initializer,
+ ctor->isImplicit(), ctor->getFullName());
+ // Constructors cannot be called on a protocol metatype, because there is no
+ // metatype to witness it.
+ } else if (isa<ConstructorDecl>(ctorDecl) &&
+ baseTy->is<MetatypeType>() &&
+ instanceTy->isExistentialType()) {
+ if (SuppressDiagnostics)
+ return false;
+
+ if (isStaticallyDerived) {
+ tc.diagnose(memberRefLoc, diag::construct_protocol_by_name, instanceTy)
+ .highlight(base->getSourceRange());
+ } else {
+ tc.diagnose(memberRefLoc, diag::construct_protocol_value, baseTy)
+ .highlight(base->getSourceRange());
+ }
+ }
+ return true;
+}
+
namespace {
/// \brief Rewrites an expression by applying the solution of a constraint
@@ -825,12 +904,12 @@
if (auto baseMeta = baseTy->getAs<AnyMetatypeType>()) {
baseIsInstance = false;
baseTy = baseMeta->getInstanceType();
+
// If the member is a constructor, verify that it can be legally
// referenced from this base.
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
- cs.setExprTypes(base);
- if (!tc.diagnoseInvalidDynamicConstructorReferences(base, memberLoc,
- baseMeta, ctor, SuppressDiagnostics))
+ if (!diagnoseInvalidDynamicConstructorReferences(cs, base, memberLoc,
+ ctor, SuppressDiagnostics))
return nullptr;
}
}
@@ -1402,6 +1481,7 @@
}
auto subscript = cast<SubscriptDecl>(choice.getDecl());
+ cs.TC.requestMemberLayout(subscript);
auto &tc = cs.getTypeChecker();
auto baseTy = cs.getType(base)->getRValueType();
@@ -2461,6 +2541,13 @@
ConstructorDecl *ctor,
FunctionRefKind functionRefKind,
Type openedType) {
+
+ // If the member is a constructor, verify that it can be legally
+ // referenced from this base.
+ if (!diagnoseInvalidDynamicConstructorReferences(cs, base, nameLoc,
+ ctor, SuppressDiagnostics))
+ return nullptr;
+
// If the subexpression is a metatype, build a direct reference to the
// constructor.
if (cs.getType(base)->is<AnyMetatypeType>()) {
@@ -6805,67 +6892,6 @@
return literal;
}
-/// Determine whether the given type refers to a non-final class (or
-/// dynamic self of one).
-static bool isNonFinalClass(Type type) {
- if (auto dynamicSelf = type->getAs<DynamicSelfType>())
- type = dynamicSelf->getSelfType();
-
- if (auto classDecl = type->getClassOrBoundGenericClass())
- return !classDecl->isFinal();
-
- if (auto archetype = type->getAs<ArchetypeType>())
- if (auto super = archetype->getSuperclass())
- return isNonFinalClass(super);
-
- return false;
-}
-
-// Non-required constructors may not be not inherited. Therefore when
-// constructing a class object, either the metatype must be statically
-// derived (rather than an arbitrary value of metatype type) or the referenced
-// constructor must be required.
-bool
-TypeChecker::diagnoseInvalidDynamicConstructorReferences(Expr *base,
- DeclNameLoc memberRefLoc,
- AnyMetatypeType *metaTy,
- ConstructorDecl *ctorDecl,
- bool SuppressDiagnostics) {
- auto ty = metaTy->getInstanceType();
-
- // FIXME: The "hasClangNode" check here is a complete hack.
- if (isNonFinalClass(ty) &&
- !base->isStaticallyDerivedMetatype() &&
- !ctorDecl->hasClangNode() &&
- !(ctorDecl->isRequired() ||
- ctorDecl->getDeclContext()->getAsProtocolOrProtocolExtensionContext())) {
- if (SuppressDiagnostics)
- return false;
-
- diagnose(memberRefLoc, diag::dynamic_construct_class, ty)
- .highlight(base->getSourceRange());
- auto ctor = cast<ConstructorDecl>(ctorDecl);
- diagnose(ctorDecl, diag::note_nonrequired_initializer,
- ctor->isImplicit(), ctor->getFullName());
- // Constructors cannot be called on a protocol metatype, because there is no
- // metatype to witness it.
- } else if (isa<ConstructorDecl>(ctorDecl) &&
- isa<MetatypeType>(metaTy) &&
- ty->isExistentialType()) {
- if (SuppressDiagnostics)
- return false;
-
- if (base->isStaticallyDerivedMetatype()) {
- diagnose(memberRefLoc, diag::construct_protocol_by_name, ty)
- .highlight(base->getSourceRange());
- } else {
- diagnose(memberRefLoc, diag::construct_protocol_value, metaTy)
- .highlight(base->getSourceRange());
- }
- }
- return true;
-}
-
Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
ConstraintLocatorBuilder locator) {
TypeChecker &tc = cs.getTypeChecker();
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index b63727a..26f8448 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1329,14 +1329,7 @@
if (auto layoutConstraint = layout.getLayoutConstraint()) {
if (layoutConstraint->isClass()) {
if (kind == ConstraintKind::ConformsTo) {
- // Conformance to AnyObject is defined by having a single
- // retainable pointer representation:
- //
- // - @objc existentials
- // - class constrained archetypes
- // - classes
- if (!type1->isObjCExistentialType() &&
- !type1->mayHaveSuperclass())
+ if (!type1->satisfiesClassConstraint())
return SolutionKind::Error;
} else {
// Subtype relation to AnyObject also allows class-bound
@@ -3938,8 +3931,11 @@
if (!choices[i].isDecl()) {
return SolutionKind::Error;
}
+ auto storage = dyn_cast<AbstractStorageDecl>(choices[i].getDecl());
+ if (!storage) {
+ return SolutionKind::Error;
+ }
- auto storage = cast<AbstractStorageDecl>(choices[i].getDecl());
if (!storage->isSettable(DC)) {
// A non-settable component makes the key path read-only, unless
// a reference-writable component shows up later.
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index ca5f5b9..73244f0 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -954,6 +954,29 @@
return { valueType, valueType };
}
+static NominalTypeDecl *getInnermostConformingDC(TypeChecker &TC,
+ DeclContext *DC,
+ ProtocolDecl *protocol) {
+ do {
+ if (DC->isTypeContext()) {
+ auto *NTD = DC->getAsNominalTypeOrNominalTypeExtensionContext();
+ auto type = NTD->getDeclaredType();
+
+ ConformanceCheckOptions options;
+ options |= ConformanceCheckFlags::InExpression;
+ options |= ConformanceCheckFlags::SuppressDependencyTracking;
+ options |= ConformanceCheckFlags::SkipConditionalRequirements;
+
+ auto result =
+ TC.conformsToProtocol(type, protocol, NTD->getDeclContext(), options);
+
+ if (result)
+ return NTD;
+ }
+ } while ((DC = DC->getParent()));
+
+ return nullptr;
+}
/// Bind type variables for archetypes that are determined from
/// context.
///
@@ -1015,8 +1038,18 @@
// parameters, or because this generic parameter was constrained
// away into a concrete type.
if (found != replacements.end()) {
+ Type contextTy;
+
+ if (genericEnv) {
+ contextTy = genericEnv->mapTypeIntoContext(paramTy);
+ } else {
+ auto *protocol = parentDC->getAsProtocolOrProtocolExtensionContext();
+ auto conformingDC = getInnermostConformingDC(cs.TC, cs.DC, protocol);
+ assert(conformingDC);
+ contextTy = conformingDC->getDeclaredTypeInContext();
+ }
+
auto typeVar = found->second;
- auto contextTy = genericEnv->mapTypeIntoContext(paramTy);
cs.addConstraint(ConstraintKind::Bind, typeVar, contextTy,
locatorPtr);
}
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index ab4641d..20af9bd 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -2827,9 +2827,7 @@
bool TypeChecker::isSubstitutableFor(Type type, ArchetypeType *archetype,
DeclContext *dc) {
- if (archetype->requiresClass() &&
- !type->mayHaveSuperclass() &&
- !type->isObjCExistentialType())
+ if (archetype->requiresClass() && !type->satisfiesClassConstraint())
return false;
if (auto superclass = archetype->getSuperclass()) {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 4fe7cd9..d6bcc3c 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4876,8 +4876,15 @@
llvm::errs() << "Requirement signature: ";
requirementsSig->print(llvm::errs());
llvm::errs() << "\n";
+
+ // Note: One cannot canonicalize a requirement signature, because
+ // requirement signatures are necessarily missing requirements.
llvm::errs() << "Canonical requirement signature: ";
- requirementsSig->getCanonicalSignature()->print(llvm::errs());
+ auto canRequirementSig =
+ GenericSignature::getCanonical(requirementsSig->getGenericParams(),
+ requirementsSig->getRequirements(),
+ /*skipValidation=*/true);
+ canRequirementSig->print(llvm::errs());
llvm::errs() << "\n";
}
}
@@ -9152,7 +9159,8 @@
// appropriate.
if (auto objcName = objcAttr->getName()) {
if (isa<ClassDecl>(D) || isa<ProtocolDecl>(D) || isa<VarDecl>(D)
- || isa<EnumDecl>(D) || isa<EnumElementDecl>(D)) {
+ || isa<EnumDecl>(D) || isa<EnumElementDecl>(D)
+ || isa<ExtensionDecl>(D)) {
// Types and properties can only have nullary
// names. Complain and recover by chopping off everything
// after the first name.
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index e100ab9..68fbc6a 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -366,6 +366,8 @@
TypeSubstitutionFn substitutions) {
llvm::SmallPtrSet<GenericTypeParamType *, 2> knownGenericParams;
for (auto type : types) {
+ if (type.isNull()) continue;
+
type.visit([&](Type type) {
if (auto gp = type->getAs<GenericTypeParamType>()) {
knownGenericParams.insert(
@@ -1373,12 +1375,16 @@
break;
}
- case RequirementKind::Layout: {
- // TODO: Statically check if a the first type
- // conforms to the layout constraint, once we
- // support such static checks.
- continue;
- }
+ case RequirementKind::Layout:
+ // TODO: Statically check other layout constraints, once they can
+ // be spelled in Swift.
+ if (req.getLayoutConstraint()->isClass() &&
+ !firstType->satisfiesClassConstraint()) {
+ diagnostic = diag::type_is_not_a_class;
+ diagnosticNote = diag::anyobject_requirement;
+ requirementFailure = true;
+ }
+ break;
case RequirementKind::Superclass:
// Superclass requirements.
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index d20e1db..38227c5 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1796,8 +1796,8 @@
// If we already recoded this type witness, there's nothing to do.
if (Conformance->hasTypeWitness(assocType)) {
- assert(Conformance->getTypeWitness(assocType, nullptr)
- ->isEqual(type) && "Conflicting type witness deductions");
+ assert(Conformance->getTypeWitness(assocType, nullptr)->isEqual(type) &&
+ "Conflicting type witness deductions");
return;
}
@@ -2656,8 +2656,12 @@
auto *depTy = DependentMemberType::get(proto->getSelfInterfaceType(),
assocType);
+ if (type->hasError())
+ return ErrorType::get(tc.Context);
+
Type contextType = type->hasTypeParameter() ? dc->mapTypeIntoContext(type)
: type;
+
if (auto superclass = genericSig->getSuperclassBound(depTy)) {
if (!superclass->isExactSuperclassOf(contextType))
return superclass;
@@ -2688,11 +2692,9 @@
}
}
- if (genericSig->requiresClass(depTy)) {
- if (!contextType->isObjCExistentialType() &&
- !contextType->mayHaveSuperclass())
- return CheckTypeWitnessResult(tc.Context.getAnyObjectType());
- }
+ if (genericSig->requiresClass(depTy) &&
+ !contextType->satisfiesClassConstraint())
+ return CheckTypeWitnessResult(tc.Context.getAnyObjectType());
// Success!
return CheckTypeWitnessResult();
@@ -2747,6 +2749,16 @@
}
}
+ // If there are no viable witnesses, and all nonviable candidates came from
+ // protocol extensions, treat this as "missing".
+ if (viable.empty() &&
+ std::find_if(nonViable.begin(), nonViable.end(),
+ [](const std::pair<TypeDecl *, CheckTypeWitnessResult> &x) {
+ return x.first->getDeclContext()
+ ->getAsProtocolOrProtocolExtensionContext() == nullptr;
+ }) == nonViable.end())
+ return ResolveWitnessResult::Missing;
+
// If there is a single viable candidate, form a substitution for it.
if (viable.size() == 1) {
auto interfaceType = viable.front().second;
@@ -2781,7 +2793,8 @@
[nonViable](NormalProtocolConformance *conformance) {
auto &diags = conformance->getDeclContext()->getASTContext().Diags;
for (auto candidate : nonViable) {
- if (candidate.first->getDeclaredInterfaceType()->hasError())
+ if (candidate.first->getDeclaredInterfaceType()->hasError() ||
+ candidate.second.isError())
continue;
diags.diagnose(
diff --git a/lib/Sema/TypeCheckProtocol.h b/lib/Sema/TypeCheckProtocol.h
index 375dd9d..d4cf20d 100644
--- a/lib/Sema/TypeCheckProtocol.h
+++ b/lib/Sema/TypeCheckProtocol.h
@@ -78,7 +78,9 @@
bool isConformanceRequirement() const {
return Requirement->isExistentialType();
}
-
+ bool isError() const {
+ return Requirement->is<ErrorType>();
+ }
explicit operator bool() const { return !Requirement.isNull(); }
};
diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp
index 055318d..45bd357 100644
--- a/lib/Sema/TypeCheckProtocolInference.cpp
+++ b/lib/Sema/TypeCheckProtocolInference.cpp
@@ -818,7 +818,7 @@
if (auto failed = checkTypeWitness(tc, dc, proto, assocType, defaultType)) {
// Record the failure, if we haven't seen one already.
- if (!failedDefaultedAssocType) {
+ if (!failedDefaultedAssocType && !failed.isError()) {
failedDefaultedAssocType = defaultedAssocType;
failedDefaultedWitness = defaultType;
failedDefaultedResult = failed;
@@ -1680,6 +1680,9 @@
diags.diagnose(assocType, diag::bad_associated_type_deduction,
assocType->getFullName(), proto->getFullName());
for (const auto &failed : failedSet) {
+ if (failed.Result.isError())
+ continue;
+
diags.diagnose(failed.Witness,
diag::associated_type_deduction_witness_failed,
failed.Requirement->getFullName(),
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 1e439ef..e6ab389 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -223,8 +223,7 @@
Type dynamicType,
Type valueType) {
// We can only bridge from class or Objective-C existential types.
- if (!dynamicType->isObjCExistentialType() &&
- !dynamicType->mayHaveSuperclass())
+ if (!dynamicType->satisfiesClassConstraint())
return Type();
// If the value type cannot be bridged, we're done.
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 6a746ef..0a1d1da 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -2483,15 +2483,6 @@
/// Diagnose assigning variable to itself.
bool diagnoseSelfAssignment(const Expr *E);
- /// When referencing a class initializer, check that the base expression is
- /// either a static metatype or that the initializer is 'required'.
- bool
- diagnoseInvalidDynamicConstructorReferences(Expr *base,
- DeclNameLoc memberRefLoc,
- AnyMetatypeType *metaTy,
- ConstructorDecl *ctorDecl,
- bool SuppressDiagnostics);
-
/// Builds a string representing a "default" generic argument list for
/// \p typeDecl. In general, this means taking the bound of each generic
/// parameter. The \p getPreferredType callback can be used to provide a
diff --git a/stdlib/public/SDK/ARKit/ARKit.swift b/stdlib/public/SDK/ARKit/ARKit.swift
index a2baa6a..6e77654 100644
--- a/stdlib/public/SDK/ARKit/ARKit.swift
+++ b/stdlib/public/SDK/ARKit/ARKit.swift
@@ -27,6 +27,10 @@
/** Tracking is limited due to a lack of features visible to the camera. */
case insufficientFeatures
+
+ /** Tracking is limited due to a relocalization in progress. */
+ @available(iOS, introduced: 11.3)
+ case relocalizing
}
/** Tracking is not available. */
@@ -49,10 +53,20 @@
case .limited:
let reason: TrackingState.Reason
- switch __trackingStateReason {
- case .initializing: reason = .initializing
- case .excessiveMotion: reason = .excessiveMotion
- default: reason = .insufficientFeatures
+ if #available(iOS 11.3, *) {
+ switch __trackingStateReason {
+ case .initializing: reason = .initializing
+ case .relocalizing: reason = .relocalizing
+ case .excessiveMotion: reason = .excessiveMotion
+ default: reason = .insufficientFeatures
+ }
+ }
+ else {
+ switch __trackingStateReason {
+ case .initializing: reason = .initializing
+ case .excessiveMotion: reason = .excessiveMotion
+ default: reason = .insufficientFeatures
+ }
}
return .limited(reason)
@@ -105,3 +119,38 @@
return Array(buffer)
}
}
+
+@available(iOS, introduced: 11.3)
+extension ARPlaneGeometry {
+ /**
+ The mesh vertices of the geometry.
+ */
+ @nonobjc public var vertices: [vector_float3] {
+ let buffer = UnsafeBufferPointer(start: __vertices, count: Int(__vertexCount))
+ return Array(buffer)
+ }
+
+ /**
+ The texture coordinates of the geometry.
+ */
+ @nonobjc public var textureCoordinates: [vector_float2] {
+ let buffer = UnsafeBufferPointer(start: __textureCoordinates, count: Int(__textureCoordinateCount))
+ return Array(buffer)
+ }
+
+ /**
+ The triangle indices of the geometry.
+ */
+ @nonobjc public var triangleIndices: [Int16] {
+ let buffer = UnsafeBufferPointer(start: __triangleIndices, count: Int(triangleCount * 3))
+ return Array(buffer)
+ }
+
+ /**
+ The vertices of the geometry's outermost boundary.
+ */
+ @nonobjc public var boundaryVertices: [vector_float3] {
+ let buffer = UnsafeBufferPointer(start: __boundaryVertices, count: Int(__boundaryVertexCount))
+ return Array(buffer)
+ }
+}
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index 6919b52..6fe3b29 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -139,23 +139,26 @@
} else {
var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: range.count, alignment: MemoryLayout<UInt>.alignment)
defer { buffer.deallocate() }
+
let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
var enumerated = 0
d.enumerateBytes { (ptr, byteRange, stop) in
- if NSIntersectionRange(sliceRange, byteRange).length > 0 {
- let lower = Swift.max(byteRange.location, sliceRange.location)
- let upper = Swift.min(byteRange.location + byteRange.length, sliceRange.location + sliceRange.length)
- let offset = lower - byteRange.location
- let effectiveRange = NSRange(location: lower, length: upper - lower)
- if effectiveRange == sliceRange {
- memcpy(buffer.baseAddress!, ptr, effectiveRange.length)
+ if byteRange.upperBound - _offset < range.lowerBound {
+ // before the range that we are looking for...
+ } else if byteRange.lowerBound - _offset > range.upperBound {
+ stop.pointee = true // we are past the range in question so we need to stop
+ } else {
+ // the byteRange somehow intersects the range in question that we are looking for...
+ let lower = Swift.max(byteRange.lowerBound - _offset, range.lowerBound)
+ let upper = Swift.min(byteRange.upperBound - _offset, range.upperBound)
+
+ let len = upper - lower
+ memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr.advanced(by: lower - (byteRange.lowerBound - _offset)), len)
+ enumerated += len
+
+ if upper == range.upperBound {
stop.pointee = true
- } else {
- memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr, effectiveRange.length)
}
- enumerated += byteRange.length
- } else if sliceRange.location + sliceRange.length < byteRange.location {
- stop.pointee = true
}
}
return try apply(UnsafeRawBufferPointer(buffer))
@@ -170,22 +173,26 @@
} else {
var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: range.count, alignment: MemoryLayout<UInt>.alignment)
defer { buffer.deallocate() }
+
let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
var enumerated = 0
d.enumerateBytes { (ptr, byteRange, stop) in
- if NSIntersectionRange(sliceRange, byteRange).length > 0 {
- let lower = Swift.max(byteRange.location, sliceRange.location)
- let upper = Swift.min(byteRange.location + byteRange.length, sliceRange.location + sliceRange.length)
- let effectiveRange = NSRange(location: lower, length: upper - lower)
- if effectiveRange == sliceRange {
- memcpy(buffer.baseAddress!, ptr, effectiveRange.length)
+ if byteRange.upperBound - _offset < range.lowerBound {
+ // before the range that we are looking for...
+ } else if byteRange.lowerBound - _offset > range.upperBound {
+ stop.pointee = true // we are past the range in question so we need to stop
+ } else {
+ // the byteRange somehow intersects the range in question that we are looking for...
+ let lower = Swift.max(byteRange.lowerBound - _offset, range.lowerBound)
+ let upper = Swift.min(byteRange.upperBound - _offset, range.upperBound)
+
+ let len = upper - lower
+ memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr.advanced(by: lower - (byteRange.lowerBound - _offset)), len)
+ enumerated += len
+
+ if upper == range.upperBound {
stop.pointee = true
- } else {
- memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr, effectiveRange.length)
}
- enumerated += byteRange.length
- } else if sliceRange.location + sliceRange.length < byteRange.location {
- stop.pointee = true
}
}
return try apply(UnsafeRawBufferPointer(buffer))
diff --git a/stdlib/public/core/FlatMap.swift b/stdlib/public/core/FlatMap.swift
index 43f37f7..ff1bad5 100644
--- a/stdlib/public/core/FlatMap.swift
+++ b/stdlib/public/core/FlatMap.swift
@@ -60,7 +60,8 @@
///
/// - Complexity: O(1)
@inline(__always)
- @available(*, deprecated, renamed: "compactMap(_:)")
+ @available(*, deprecated, renamed: "compactMap(_:)",
+ message: "Please use compactMap(_:) for the case where closure returns an optional value")
public func flatMap<ElementOfResult>(
_ transform: @escaping (Elements.Element) -> ElementOfResult?
) -> LazyMapSequence<
@@ -123,7 +124,8 @@
/// collection as its argument and returns an optional value.
///
/// - Complexity: O(1)
- @available(*, deprecated, renamed: "compactMap(_:)")
+ @available(*, deprecated, renamed: "compactMap(_:)",
+ message: "Please use compactMap(_:) for the case where closure returns an optional value")
@_inlineable // FIXME(sil-serialize-all)
public func flatMap<ElementOfResult>(
_ transform: @escaping (Elements.Element) -> ElementOfResult?
diff --git a/stdlib/public/core/ImplicitlyUnwrappedOptional.swift b/stdlib/public/core/ImplicitlyUnwrappedOptional.swift
index b3be8c2..7d9e540 100644
--- a/stdlib/public/core/ImplicitlyUnwrappedOptional.swift
+++ b/stdlib/public/core/ImplicitlyUnwrappedOptional.swift
@@ -49,3 +49,48 @@
self = .none
}
}
+
+#if _runtime(_ObjC)
+extension ImplicitlyUnwrappedOptional : _ObjectiveCBridgeable {
+ @_inlineable // FIXME(sil-serialize-all)
+ public func _bridgeToObjectiveC() -> AnyObject {
+ switch self {
+ case .none:
+ _preconditionFailure("Attempt to bridge an implicitly unwrapped optional containing nil")
+
+ case .some(let x):
+ return Swift._bridgeAnythingToObjectiveC(x)
+ }
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public static func _forceBridgeFromObjectiveC(
+ _ x: AnyObject,
+ result: inout ImplicitlyUnwrappedOptional<Wrapped>?
+ ) {
+ result = Swift._forceBridgeFromObjectiveC(x, Wrapped.self)
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public static func _conditionallyBridgeFromObjectiveC(
+ _ x: AnyObject,
+ result: inout ImplicitlyUnwrappedOptional<Wrapped>?
+ ) -> Bool {
+ let bridged: Wrapped? =
+ Swift._conditionallyBridgeFromObjectiveC(x, Wrapped.self)
+ if let value = bridged {
+ result = value
+ }
+
+ return false
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public static func _unconditionallyBridgeFromObjectiveC(_ source: AnyObject?)
+ -> Wrapped! {
+ var result: ImplicitlyUnwrappedOptional<Wrapped>?
+ _forceBridgeFromObjectiveC(source!, result: &result)
+ return result!
+ }
+}
+#endif
diff --git a/stdlib/public/core/OutputStream.swift b/stdlib/public/core/OutputStream.swift
index 1d60d5c..ac7eaf5 100644
--- a/stdlib/public/core/OutputStream.swift
+++ b/stdlib/public/core/OutputStream.swift
@@ -624,7 +624,7 @@
}
/// A hook for playgrounds to print through.
-public var _playgroundPrintHook : ((String) -> Void)? = {_ in () }
+public var _playgroundPrintHook : ((String) -> Void)? = nil
@_fixed_layout // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/SequenceAlgorithms.swift.gyb b/stdlib/public/core/SequenceAlgorithms.swift.gyb
index f18ee13..3be97b0 100644
--- a/stdlib/public/core/SequenceAlgorithms.swift.gyb
+++ b/stdlib/public/core/SequenceAlgorithms.swift.gyb
@@ -783,7 +783,8 @@
/// - Complexity: O(*m* + *n*), where *m* is the length of this sequence
/// and *n* is the length of the result.
@inline(__always)
- @available(*, deprecated, renamed: "compactMap(_:)")
+ @available(*, deprecated, renamed: "compactMap(_:)",
+ message: "Please use compactMap(_:) for the case where closure returns an optional value")
public func flatMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {
diff --git a/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb b/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb
index f8404ea..54a9b46 100644
--- a/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb
+++ b/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb
@@ -448,7 +448,8 @@
return try _compactMap(transform)
}
- @available(*, deprecated, renamed: "compactMap(_:)")
+ @available(*, deprecated, renamed: "compactMap(_:)",
+ message: "Please use compactMap(_:) for the case where closure returns an optional value")
@inline(__always)
public func flatMap(
_ transform: (Element) throws -> String?
diff --git a/test/ClangImporter/Inputs/enum-error.h b/test/ClangImporter/Inputs/enum-error.h
index b22dd08..342600d 100644
--- a/test/ClangImporter/Inputs/enum-error.h
+++ b/test/ClangImporter/Inputs/enum-error.h
@@ -19,4 +19,10 @@
OtherC,
};
+extern NSString *TypedefOnlyErrorDomain;
+typedef enum __attribute__((ns_error_domain(TypedefOnlyErrorDomain))) {
+ TypedefOnlyErrorBadness
+} TypedefOnlyError;
+
+
TestError getErr();
diff --git a/test/ClangImporter/enum-error.swift b/test/ClangImporter/enum-error.swift
index babf82f..262d407 100644
--- a/test/ClangImporter/enum-error.swift
+++ b/test/ClangImporter/enum-error.swift
@@ -21,6 +21,11 @@
return other.code
}
+func testImportsCorrectly() {
+ _ = TypedefOnlyError.badness
+ _ = TypedefOnlyError.Code.badness
+}
+
func testError() {
let testErrorNSError = NSError(domain: TestErrorDomain,
code: Int(TestError.TENone.rawValue),
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index a431c54..9940e2b 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -234,8 +234,8 @@
// <rdar://problem/21553065> Spurious diagnostic: '_' can only appear in a pattern or on the left side of an assignment
protocol r21553065Protocol {}
-class r21553065Class<T : AnyObject> {}
-_ = r21553065Class<r21553065Protocol>() // expected-error {{'r21553065Protocol' is not convertible to 'AnyObject'}}
+class r21553065Class<T : AnyObject> {} // expected-note{{requirement specified as 'T' : 'AnyObject'}}
+_ = r21553065Class<r21553065Protocol>() // expected-error {{'r21553065Class' requires that 'r21553065Protocol' be a class type}}
// Type variables not getting erased with nested closures
struct Toe {
diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift
index 8e9ae7d..6fd0152 100644
--- a/test/Constraints/generics.swift
+++ b/test/Constraints/generics.swift
@@ -265,7 +265,9 @@
struct FullyGeneric<Foo> {} // expected-note 11 {{'Foo' declared as parameter to type 'FullyGeneric'}} expected-note 1 {{generic type 'FullyGeneric' declared here}}
struct AnyClassBound<Foo: AnyObject> {} // expected-note {{'Foo' declared as parameter to type 'AnyClassBound'}} expected-note {{generic type 'AnyClassBound' declared here}}
+// expected-note@-1{{requirement specified as 'Foo' : 'AnyObject'}}
struct AnyClassBound2<Foo> where Foo: AnyObject {} // expected-note {{'Foo' declared as parameter to type 'AnyClassBound2'}}
+// expected-note@-1{{requirement specified as 'Foo' : 'AnyObject' [with Foo = Any]}}
struct ProtoBound<Foo: SubProto> {} // expected-note {{'Foo' declared as parameter to type 'ProtoBound'}} expected-note {{generic type 'ProtoBound' declared here}}
struct ProtoBound2<Foo> where Foo: SubProto {} // expected-note {{'Foo' declared as parameter to type 'ProtoBound2'}}
@@ -301,11 +303,11 @@
_ = FullyGeneric<Any>()
_ = AnyClassBound() // expected-error {{generic parameter 'Foo' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{20-20=<AnyObject>}}
- _ = AnyClassBound<Any>() // expected-error {{'Any' is not convertible to 'AnyObject'}}
+ _ = AnyClassBound<Any>() // expected-error {{'AnyClassBound' requires that 'Any' be a class type}}
_ = AnyClassBound<AnyObject>()
_ = AnyClassBound2() // expected-error {{generic parameter 'Foo' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{21-21=<AnyObject>}}
- _ = AnyClassBound2<Any>() // expected-error {{'Any' is not convertible to 'AnyObject'}}
+ _ = AnyClassBound2<Any>() // expected-error {{'AnyClassBound2' requires that 'Any' be a class type}}
_ = AnyClassBound2<AnyObject>()
_ = ProtoBound() // expected-error {{generic parameter 'Foo' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{17-17=<<#Foo: SubProto#>>}}
diff --git a/test/Constraints/same_types.swift b/test/Constraints/same_types.swift
index b22ae3b..210c8de 100644
--- a/test/Constraints/same_types.swift
+++ b/test/Constraints/same_types.swift
@@ -1,7 +1,7 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown
protocol Fooable {
- associatedtype Foo
+ associatedtype Foo // expected-note{{protocol requires nested type 'Foo'; do you want to add it?}}
var foo: Foo { get }
}
@@ -148,7 +148,7 @@
struct Brunch<U : Fooable> where U.Foo == X {}
-struct BadFooable : Fooable {
+struct BadFooable : Fooable { // expected-error{{type 'BadFooable' does not conform to protocol 'Fooable'}}
typealias Foo = DoesNotExist // expected-error{{use of undeclared type 'DoesNotExist'}}
var foo: Foo { while true {} }
}
diff --git a/test/DebugInfo/keypath.swift b/test/DebugInfo/keypath.swift
new file mode 100644
index 0000000..96df16b
--- /dev/null
+++ b/test/DebugInfo/keypath.swift
@@ -0,0 +1,18 @@
+// RUN: %target-swift-frontend -g -emit-ir %s | %FileCheck %s
+
+public struct Gen<Value> {
+ public private(set) var value: Value
+ public func use<Subject>(keyPath: WritableKeyPath<Value, Subject>) {
+ }
+}
+
+// This used to assert.
+
+// CHECK: distinct !DISubprogram(linkageName: "keypath_set", {{.*}} flags: DIFlagArtificial
+extension Gen where Value : MutableCollection, Value.Index : Hashable {
+ public var dontAssert: Int {
+ var i = value.startIndex
+ use(keyPath: \.[i])
+ return 0
+ }
+}
diff --git a/test/Driver/temp-files.swift b/test/Driver/temp-files.swift
index d1a5197..bc8b9d7 100644
--- a/test/Driver/temp-files.swift
+++ b/test/Driver/temp-files.swift
@@ -11,18 +11,18 @@
// EMPTY-NOT: .{{(o|swiftmodule|swiftdoc)}}
// RUN: %empty-directory(%t) && %empty-directory(%t/tmp) && touch %t/tmp/dummy
-// RUN: env TMPDIR=%t/tmp/ %swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main2 -emit-module-path %t/main2.swiftmodule
+// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main2 -emit-module-path %t/main2.swiftmodule
// RUN: ls %t/main2
// RUN: ls %t/main2.swiftmodule
// RUN: ls %t/tmp | %FileCheck -check-prefix=EMPTY %s
// RUN: %empty-directory(%t) && %empty-directory(%t/tmp) && touch %t/tmp/dummy
-// RUN: env TMPDIR=%t/tmp/ %swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main3 -g
+// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main3 -g
// RUN: ls %t/main3
// RUN: ls %t/tmp | %FileCheck -check-prefix=EMPTY %s
// RUN: %empty-directory(%t) && %empty-directory(%t/tmp) && touch %t/tmp/dummy
-// RUN: env TMPDIR=%t/tmp/ %swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main4 -emit-module-path %t/main4.swiftmodule -g
+// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main4 -emit-module-path %t/main4.swiftmodule -g
// RUN: ls %t/main4
// RUN: ls %t/main4.swiftmodule
// RUN: ls %t | %FileCheck -check-prefix=MAIN4-%target-object-format %s
@@ -33,7 +33,7 @@
// RUN: %empty-directory(%t) && %empty-directory(%t/tmp) && touch %t/tmp/dummy
// RUN: echo "{\"%s\": {\"object\": \"%t/main5.o\"}}" > %t.json
-// RUN: env TMPDIR=%t/tmp/ %swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main5 -output-file-map %t.json -g
+// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main5 -output-file-map %t.json -g
// RUN: ls %t/main5
// RUN: ls %t/main5.o
// RUN: ls %t | %FileCheck -check-prefix=MAIN5-%target-object-format %s
@@ -43,7 +43,7 @@
// MAIN5-elf-NOT: .dSYM
// RUN: %empty-directory(%t) && %empty-directory(%t/tmp) && touch %t/tmp/dummy
-// RUN: env TMPDIR=%t/tmp/ %swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main6 -g -save-temps
+// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -target %target-triple -sdk %sdk -module-cache-path %t -emit-executable %s -o %t/main6 -g -save-temps
// RUN: ls %t/main6
// RUN: ls %t | %FileCheck -check-prefix=MAIN6-%target-object-format %s
// RUN: ls %t/tmp | %FileCheck -check-prefix=SAVE-TEMPS %s
diff --git a/test/Executable/Inputs/arc_36509461.h b/test/Executable/Inputs/arc_36509461.h
new file mode 100644
index 0000000..48820f8
--- /dev/null
+++ b/test/Executable/Inputs/arc_36509461.h
@@ -0,0 +1,11 @@
+
+#ifndef ARC36509461_H
+#define ARC36509461_H
+
+#include <stdbool.h>
+
+typedef bool (^fake_apply_t)(const char *key, id value);
+
+bool fake_apply(id obj, fake_apply_t applier);
+
+#endif
diff --git a/test/Executable/Inputs/arc_36509461.m b/test/Executable/Inputs/arc_36509461.m
new file mode 100644
index 0000000..b88b1f3
--- /dev/null
+++ b/test/Executable/Inputs/arc_36509461.m
@@ -0,0 +1,6 @@
+
+#import "arc_36509461.h"
+
+bool fake_apply(id obj, fake_apply_t applier) {
+ return false;
+}
diff --git a/test/Executable/arc_36509461.swift b/test/Executable/arc_36509461.swift
new file mode 100644
index 0000000..37da207
--- /dev/null
+++ b/test/Executable/arc_36509461.swift
@@ -0,0 +1,55 @@
+// RUN: %empty-directory(%T)
+// RUN: %target-clang -x objective-c -c %S/Inputs/arc_36509461.m -o %T/arc_36509461.m.o
+// RUN: %target-swift-frontend -c -O -import-objc-header %S/Inputs/arc_36509461.h -sanitize=address %s -o %T/arc_36509461.swift.o
+// RUN: %target-build-swift %T/arc_36509461.m.o %T/arc_36509461.swift.o -sanitize=address -o %t
+// RUN: %t
+
+// REQUIRES: executable_test
+// REQUIRES: asan_runtime
+// REQUIRES: objc_interop
+
+import Foundation
+
+struct FakeUUID {
+ var bigTuple: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
+
+ init() {
+ bigTuple = (0, 0, 0, 0, 0, 0, 0, 0)
+ }
+}
+
+struct Record {
+ let name: String
+ let uuid: FakeUUID
+ let storage: NSObject
+
+ init(storage: NSObject, name: String, uuid: FakeUUID) {
+ self.name = name
+ self.uuid = uuid
+ self.storage = storage
+ }
+
+ func copy() -> Record {
+ let copiedNSObject = NSObject()
+
+ fake_apply(self.storage) { (key, value) -> Bool in
+ let x = copiedNSObject
+ return true
+ }
+
+ var record = Record(storage: copiedNSObject, name: self.name, uuid: self.uuid)
+ return record
+ }
+}
+
+@inline(never)
+func foo(record: Record) -> Record {
+ return record.copy()
+}
+
+func main() {
+ let record = Record(storage: NSObject(), name: "", uuid: FakeUUID())
+ _ = foo(record: record)
+}
+
+main()
diff --git a/test/Generics/class_constraint.swift b/test/Generics/class_constraint.swift
new file mode 100644
index 0000000..473a4d8
--- /dev/null
+++ b/test/Generics/class_constraint.swift
@@ -0,0 +1,27 @@
+// RUN: %target-typecheck-verify-swift
+
+struct X<T: AnyObject> { } // expected-note 4{{requirement specified as 'T' : 'AnyObject'}}
+
+class C { }
+struct S { }
+
+protocol P { }
+
+let okay0: X<C>
+
+struct Y<T: AnyObject> {
+ let okay1: X<T>
+}
+
+struct Y2<T: C> {
+ let okay2: X<T>
+}
+
+let bad0: X<C & P> // expected-error{{'X' requires that 'C & P' be a class type}}
+let bad1: X<P> // expected-error{{'X' requires that 'P' be a class type}}
+let bad2: X<S> // expected-error{{'X' requires that 'S' be a class type}}
+
+struct Z<U> {
+ let bad3: X<U> // expected-error{{'X' requires that 'U' be a class type}}
+}
+
diff --git a/test/Generics/existential_restrictions.swift b/test/Generics/existential_restrictions.swift
index d109ccf..b13ca76 100644
--- a/test/Generics/existential_restrictions.swift
+++ b/test/Generics/existential_restrictions.swift
@@ -53,7 +53,7 @@
class GOP<T : OP> {}
class GCP<T : CP> {}
class GSP<T : SP> {}
-class GAO<T : AnyObject> {}
+class GAO<T : AnyObject> {} // expected-note 2{{requirement specified as 'T' : 'AnyObject'}}
func blackHole(_ t: Any) {}
@@ -61,9 +61,9 @@
blackHole(GP<P>()) // expected-error{{using 'P' as a concrete type conforming to protocol 'P' is not supported}}
blackHole(GOP<OP>())
blackHole(GCP<CP>()) // expected-error{{using 'CP' as a concrete type conforming to protocol 'CP' is not supported}}
- blackHole(GAO<P>()) // expected-error{{'P' is not convertible to 'AnyObject'}}
+ blackHole(GAO<P>()) // expected-error{{'GAO' requires that 'P' be a class type}}
blackHole(GAO<OP>())
- blackHole(GAO<CP>()) // expected-error{{'CP' is not convertible to 'AnyObject'}}
+ blackHole(GAO<CP>()) // expected-error{{'GAO' requires that 'CP' be a class type}}
blackHole(GSP<SP>()) // expected-error{{'SP' cannot be used as a type conforming to protocol 'SP' because 'SP' has static requirements}}
blackHole(GAO<AnyObject>())
}
diff --git a/test/IDE/clang-importing/Inputs/bridge.h b/test/IDE/clang-importing/Inputs/bridge.h
new file mode 100644
index 0000000..920e7aa
--- /dev/null
+++ b/test/IDE/clang-importing/Inputs/bridge.h
@@ -0,0 +1 @@
+@import somemod1;
diff --git a/test/IDE/clang-importing/Inputs/somemod1/module.modulemap b/test/IDE/clang-importing/Inputs/somemod1/module.modulemap
new file mode 100644
index 0000000..fa34272
--- /dev/null
+++ b/test/IDE/clang-importing/Inputs/somemod1/module.modulemap
@@ -0,0 +1,3 @@
+module somemod1 {
+ header "somemod1.h"
+}
diff --git a/test/IDE/clang-importing/Inputs/somemod1/somemod1.h b/test/IDE/clang-importing/Inputs/somemod1/somemod1.h
new file mode 100644
index 0000000..33d4e32
--- /dev/null
+++ b/test/IDE/clang-importing/Inputs/somemod1/somemod1.h
@@ -0,0 +1,5 @@
+/// some_func11 is cool function.
+void some_func11(void);
+
+/// some_func12 is cool function.
+void some_func12(void);
diff --git a/test/IDE/clang-importing/Inputs/somemod2/module.modulemap b/test/IDE/clang-importing/Inputs/somemod2/module.modulemap
new file mode 100644
index 0000000..aa7bebb
--- /dev/null
+++ b/test/IDE/clang-importing/Inputs/somemod2/module.modulemap
@@ -0,0 +1,3 @@
+module somemod2 {
+ header "somemod2.h"
+}
diff --git a/test/IDE/clang-importing/Inputs/somemod2/somemod2.h b/test/IDE/clang-importing/Inputs/somemod2/somemod2.h
new file mode 100644
index 0000000..9eea1ee
--- /dev/null
+++ b/test/IDE/clang-importing/Inputs/somemod2/somemod2.h
@@ -0,0 +1,5 @@
+/// some_func21 is cool function.
+void some_func21(void);
+
+/// some_func22 is cool function.
+void some_func22(void);
diff --git a/test/IDE/clang-importing/complete_with_clang_comments.swift b/test/IDE/clang-importing/complete_with_clang_comments.swift
new file mode 100644
index 0000000..dfa17fa
--- /dev/null
+++ b/test/IDE/clang-importing/complete_with_clang_comments.swift
@@ -0,0 +1,12 @@
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TOP -code-completion-comments=true \
+// RUN: -import-objc-header %S/Inputs/bridge.h -I %S/Inputs/somemod1 -I %S/Inputs/somemod2 | %FileCheck %s -check-prefix=CHECK-TOP
+
+// REQUIRES: objc_interop
+
+import somemod2
+
+#^TOP^#
+// CHECK-TOP: name=some_func11(); comment=some_func11 is cool function.
+// CHECK-TOP: name=some_func12(); comment=some_func12 is cool function.
+// CHECK-TOP: name=some_func21(); comment=some_func21 is cool function.
+// CHECK-TOP: name=some_func22(); comment=some_func22 is cool function.
diff --git a/test/IRGen/coverage_ignored.swift b/test/IRGen/coverage_ignored.swift
new file mode 100644
index 0000000..c2c5193
--- /dev/null
+++ b/test/IRGen/coverage_ignored.swift
@@ -0,0 +1,7 @@
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -profile-generate -emit-sil -o %t.sil
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -emit-ir -o - | %FileCheck %s
+
+// CHECK-NOT: llvm.instrprof
+// CHECK-NOT: profc
+func foo() {}
+foo()
diff --git a/test/IRGen/generic_structs.swift b/test/IRGen/generic_structs.swift
index 1d593e7..a825a23 100644
--- a/test/IRGen/generic_structs.swift
+++ b/test/IRGen/generic_structs.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -primary-file %s -emit-ir
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK-%target-ptrsize
struct A<T1, T2>
{
@@ -25,3 +25,35 @@
struct Bar<A1, A2> {
}
+
+public protocol Proto { }
+
+public struct EmptyStruct {}
+
+public struct GenericStruct<T : Proto> {
+ var empty: EmptyStruct = EmptyStruct()
+ var dummy: Int = 0
+ var opt: Optional<T> = nil
+
+ public init() {}
+}
+
+// CHECK-32-LABEL: define{{.*}} swiftcc void @_T015generic_structs13GenericStructVACyxGycfC
+// CHECK-32: [[TYPE:%.*]] = call %swift.type* @_T015generic_structs13GenericStructVMa(%swift.type* %T, i8** %T.Proto)
+// CHECK-32: [[PTR:%.*]] = bitcast %swift.type* [[TYPE]] to i32*
+// CHECK-32: [[FIELDOFFSETS:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 2
+// CHECK-32: [[FIELDOFFSET:%.*]] = getelementptr inbounds i32, i32* [[FIELDOFFSETS]], i32 2
+// CHECK-32: [[OFFSET:%.*]] = load i32, i32* [[FIELDOFFSET]]
+// CHECK-32: [[ADDROFOPT:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 [[OFFSET]]
+// CHECK-32: [[OPTPTR:%.*]] = bitcast i8* [[ADDROFOPT]] to %TSq*
+// CHECK-32: call %TSq* @_T015generic_structsytWb3_(%TSq* {{.*}}, %TSq* [[OPTPTR]]
+
+// CHECK-64-LABEL: define{{.*}} swiftcc void @_T015generic_structs13GenericStructVACyxGycfC
+// CHECK-64: [[TYPE:%.*]] = call %swift.type* @_T015generic_structs13GenericStructVMa(%swift.type* %T, i8** %T.Proto)
+// CHECK-64: [[PTR:%.*]] = bitcast %swift.type* [[TYPE]] to i64*
+// CHECK-64: [[FIELDOFFSETS:%.*]] = getelementptr inbounds i64, i64* [[PTR]], i64 2
+// CHECK-64: [[FIELDOFFSET:%.*]] = getelementptr inbounds i64, i64* [[FIELDOFFSETS]], i32 2
+// CHECK-64: [[OFFSET:%.*]] = load i64, i64* [[FIELDOFFSET]]
+// CHECK-64: [[ADDROFOPT:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[OFFSET]]
+// CHECK-64: [[OPTPTR:%.*]] = bitcast i8* [[ADDROFOPT]] to %TSq*
+// CHECK-64: call %TSq* @_T015generic_structsytWb3_(%TSq* {{.*}}, %TSq* [[OPTPTR]]
diff --git a/test/Interpreter/class_resilience.swift b/test/Interpreter/class_resilience.swift
index 1572fb7..99bdbb3 100644
--- a/test/Interpreter/class_resilience.swift
+++ b/test/Interpreter/class_resilience.swift
@@ -16,7 +16,7 @@
// RUN: %target-build-swift-dylib(%t/libresilient_class_wmo.%target-dylib-extension) -Xfrontend -enable-resilience %S/../Inputs/resilient_class.swift -emit-module -emit-module-path %t/resilient_class.swiftmodule -module-name resilient_class -I%t -L%t -lresilient_struct_wmo -whole-module-optimization
// RUN: %target-codesign %t/libresilient_class_wmo.%target-dylib-extension
-// RUN: %target-build-swift %s -L %t -I %t -lresilient_struct -lresilient_class -o %t/main -Xlinker -rpath -Xlinker %t
+// RUN: %target-build-swift %s -L %t -I %t -lresilient_struct_wmo -lresilient_class_wmo -o %t/main -Xlinker -rpath -Xlinker %t
// RUN: %target-run %t/main %t/libresilient_struct_wmo.%target-dylib-extension %t/libresilient_class_wmo.%target-dylib-extension
diff --git a/test/Interpreter/conditional_conformances_warning.swift b/test/Interpreter/conditional_conformances_warning.swift
index 37a0d49..6b3695d 100644
--- a/test/Interpreter/conditional_conformances_warning.swift
+++ b/test/Interpreter/conditional_conformances_warning.swift
@@ -1,6 +1,7 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %target-build-swift %s -o %t/a.out
// RUN: %target-run %t/a.out 2>&1 | %FileCheck %s -check-prefix=CHECK_WARNINGS
+// REQUIRES: executable_test
protocol P {
func foo()
}
diff --git a/test/Interpreter/field_offset_generic.swift b/test/Interpreter/field_offset_generic.swift
new file mode 100644
index 0000000..ccbf194
--- /dev/null
+++ b/test/Interpreter/field_offset_generic.swift
@@ -0,0 +1,27 @@
+// RUN: %target-run-simple-swift | %FileCheck %s
+// REQUIRES: executable_test
+
+public protocol Proto { }
+
+public struct MyImpl: Proto { }
+
+public struct EmptyStruct {}
+
+private struct GenericStruct<T : Proto> {
+ var empty: EmptyStruct = EmptyStruct()
+ var dummy: Int = 0
+ var opt: Optional<T> = nil
+
+ init() {
+ }
+}
+
+public func test() {
+ let s = GenericStruct<MyImpl>()
+ assert(s.dummy == 0, "Expecting dummy == 0")
+ assert(s.opt == nil, "Expecting opt == nil")
+ // CHECK: dummy: 0
+ print("dummy: \(s.dummy)")
+}
+
+test()
diff --git a/test/Interpreter/objc_runtime_visible.swift b/test/Interpreter/objc_runtime_visible.swift
index 63d1509..af79a34 100644
--- a/test/Interpreter/objc_runtime_visible.swift
+++ b/test/Interpreter/objc_runtime_visible.swift
@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
-// RUN: %clang %target-cc-options -isysroot %sdk -fobjc-arc %S/Inputs/objc_runtime_visible.m -fmodules -nodefaultlibs -lc -dynamiclib -o %t/libobjc_runtime_visible.dylib -install_name @executable_path/libobjc_runtime_visible.dylib
+// RUN: %target-clang %target-cc-options -isysroot %sdk -fobjc-arc %S/Inputs/objc_runtime_visible.m -fmodules -nodefaultlibs -lc -dynamiclib -o %t/libobjc_runtime_visible.dylib -install_name @executable_path/libobjc_runtime_visible.dylib
// RUN: %target-codesign %t/libobjc_runtime_visible.dylib
// RUN: nm -g %t/libobjc_runtime_visible.dylib | %FileCheck %s
// RUN: %target-build-swift -import-objc-header %S/Inputs/objc_runtime_visible.h %t/libobjc_runtime_visible.dylib %s -o %t/main
diff --git a/test/SILGen/Inputs/objc_bridged_block_optionality_diff.h b/test/SILGen/Inputs/objc_bridged_block_optionality_diff.h
new file mode 100644
index 0000000..4932e2a
--- /dev/null
+++ b/test/SILGen/Inputs/objc_bridged_block_optionality_diff.h
@@ -0,0 +1,8 @@
+@import Foundation;
+
+#pragma clang assume_nonnull begin
+typedef void (^HandlerBlock)(NSString *(^message)(void));
+#pragma clang assume_nonnull end
+
+/// Default handler for logging.
+extern HandlerBlock TheHandlerBlock;
diff --git a/test/SILGen/keypaths_objc.swift b/test/SILGen/keypaths_objc.swift
index 90b29fc..c6d027f 100644
--- a/test/SILGen/keypaths_objc.swift
+++ b/test/SILGen/keypaths_objc.swift
@@ -76,3 +76,15 @@
_ = \NSObject.dynamic
}
+
+@objc protocol ObjCProto {
+ var objcRequirement: Int { get set }
+}
+
+// CHECK-LABEL: sil hidden @{{.*}}ProtocolRequirement
+func objcProtocolRequirement<T: ObjCProto>(_: T) {
+ // CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign
+ _ = \T.objcRequirement
+ // CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign
+ _ = \ObjCProto.objcRequirement
+}
diff --git a/test/SILGen/metatype_in_init_delegation.swift b/test/SILGen/metatype_in_init_delegation.swift
new file mode 100644
index 0000000..4ac6f0b
--- /dev/null
+++ b/test/SILGen/metatype_in_init_delegation.swift
@@ -0,0 +1,12 @@
+// RUN: %target-swift-frontend -emit-silgen -verify %s
+// REQUIRES: objc_interop
+
+import Foundation
+import CoreData
+
+@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
+class Foo : NSManagedObject {
+ convenience init(context: NSManagedObjectContext, value: Int) {
+ self.init(entity: type(of: self).entity(), insertInto: context)
+ }
+}
diff --git a/test/SILGen/objc_bridged_block_optionality_diff.swift b/test/SILGen/objc_bridged_block_optionality_diff.swift
new file mode 100644
index 0000000..079a142
--- /dev/null
+++ b/test/SILGen/objc_bridged_block_optionality_diff.swift
@@ -0,0 +1,6 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s -import-objc-header %S/Inputs/objc_bridged_block_optionality_diff.h -verify
+// REQUIRES: objc_interop
+import Foundation
+
+TheHandlerBlock = { x in () }
+
diff --git a/test/SILGen/protocol_extensions.swift b/test/SILGen/protocol_extensions.swift
index 37d1fbc..6920b92 100644
--- a/test/SILGen/protocol_extensions.swift
+++ b/test/SILGen/protocol_extensions.swift
@@ -813,7 +813,7 @@
// rdar://problem/21370992 - delegation from an initializer in a
// protocol extension to an @objc initializer in a class.
class ObjCInitClass {
- @objc init() { }
+ @objc required init() { }
}
protocol ProtoDelegatesToObjC { }
diff --git a/test/SILGen/protocols.swift b/test/SILGen/protocols.swift
index 171acba..de3788c 100644
--- a/test/SILGen/protocols.swift
+++ b/test/SILGen/protocols.swift
@@ -415,6 +415,27 @@
// CHECK: [[TEMPORARY:%.*]] = address_to_pointer [[TEMPORARY_ADDR]] : $*Int to $Builtin.RawPointer
// CHECK: apply [[CALLBACK]]<T>
+public struct Val {
+ public var x: Int = 0
+}
+
+public protocol Proto {
+ var val: Val { get nonmutating set}
+}
+
+public func test(_ p: Proto) {
+ p.val.x += 1
+}
+
+// CHECK-LABEL: sil @_T09protocols4test{{.*}}: $@convention(thin) (@in Proto) -> ()
+// CHECK: [[OPEN:%.*]] = open_existential_addr immutable_access
+// CHECK: [[MAT:%.*]] = witness_method $@opened("{{.*}}") Proto, #Proto.val!materializeForSet
+// CHECK: [[BUF:%.*]] = apply [[MAT]]
+// CHECK: [[WB:%.*]] = pointer_to_thin_function
+// This use looks like it is mutating but really is not. We use to assert in the SIL verifier.
+// CHECK: apply [[WB]]{{.*}}({{.*}}[[OPEN]]
+// CHECK: return
+
// CHECK-LABEL: sil_witness_table hidden ClassWithGetter: PropertyWithGetter module protocols {
// CHECK-NEXT: method #PropertyWithGetter.a!getter.1: {{.*}} : @_T09protocols15ClassWithGetterCAA08PropertycD0A2aDP1aSivgTW
// CHECK-NEXT: }
diff --git a/test/SILOptimizer/bridged_casts_crash.sil b/test/SILOptimizer/bridged_casts_crash.sil
new file mode 100644
index 0000000..cffcaa5
--- /dev/null
+++ b/test/SILOptimizer/bridged_casts_crash.sil
@@ -0,0 +1,45 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -performance-constant-propagation %s | %FileCheck %s
+
+// REQUIRES: objc_interop
+
+sil_stage canonical
+
+import Builtin
+import Swift
+import Foundation
+
+class TestObjCKeyTy : NSObject {
+ override init()
+}
+struct TestBridgedKeyTy : _ObjectiveCBridgeable {
+ func _bridgeToObjectiveC() -> TestObjCKeyTy
+ static func _forceBridgeFromObjectiveC(_ x: TestObjCKeyTy, result: inout TestBridgedKeyTy?)
+ static func _conditionallyBridgeFromObjectiveC(_ x: TestObjCKeyTy, result: inout TestBridgedKeyTy?) -> Bool
+ static func _unconditionallyBridgeFromObjectiveC(_ source: TestObjCKeyTy?) -> TestBridgedKeyTy
+}
+
+// Test that we don't crash in the verifier because of a critical edge
+
+// CHECK-LABEL: testit
+// CHECK: checked_cast_br
+sil @testit : $@convention(thin) (@owned NSObject) -> () {
+bb0(%0 : $NSObject):
+ %73 = alloc_stack $NSObject
+ store %0 to %73 : $*NSObject
+ %75 = alloc_stack $Optional<TestBridgedKeyTy>
+ %76 = init_enum_data_addr %75 : $*Optional<TestBridgedKeyTy>, #Optional.some!enumelt.1
+ %77 = load %73 : $*NSObject
+ checked_cast_addr_br take_always NSObject in %73 : $*NSObject to TestBridgedKeyTy in %76 : $*TestBridgedKeyTy, bb1, bb2
+
+bb1:
+ br bb3
+
+bb2:
+ br bb3
+
+bb3:
+ dealloc_stack %75 : $*Optional<TestBridgedKeyTy>
+ dealloc_stack %73 : $*NSObject
+ %r = tuple ()
+ return %r : $()
+}
diff --git a/test/SILOptimizer/licm.sil b/test/SILOptimizer/licm.sil
index 705ff1d..08cde42 100644
--- a/test/SILOptimizer/licm.sil
+++ b/test/SILOptimizer/licm.sil
@@ -268,3 +268,51 @@
%52 = tuple ()
return %52 : $()
}
+
+
+sil @get_unknown_value : $@convention(thin) () -> Builtin.Int32
+sil @get_unknown_value2 : $@convention(thin) () -> Builtin.Int32
+
+sil @callee : $@convention(thin) (@inout Builtin.Int32) -> () {
+bb0(%0 : $*Builtin.Int32):
+ %1 = function_ref @get_unknown_value : $@convention(thin) () -> Builtin.Int32
+ %2 = apply %1() : $@convention(thin) () -> Builtin.Int32
+ store %2 to %0 : $*Builtin.Int32
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+sil @use_value : $@convention(thin) (Builtin.Int32) -> ()
+
+// Check if escape analysis figures out that the alloc_stack escapes to callee.
+//
+// CHECK-LABEL: sil @dont_hoist_aliased_load
+// CHECK: bb2:
+// CHECK-NEXT: apply
+// CHECK-NEXT: load
+// CHECK-NEXT: apply
+sil @dont_hoist_aliased_load : $@convention(thin) () -> () {
+bb0:
+ %0 = alloc_stack $Builtin.Int32
+ %1 = integer_literal $Builtin.Int32, 0
+ %3 = function_ref @callee : $@convention(thin) (@inout Builtin.Int32) -> ()
+ %5 = function_ref @use_value : $@convention(thin) (Builtin.Int32) -> ()
+ %unknown_value_fn = function_ref @get_unknown_value2 : $@convention(thin) () -> Builtin.Int32
+ store %1 to %0 : $*Builtin.Int32
+ br bb1(%0 : $*Builtin.Int32)
+
+bb1(%phi1 : $*Builtin.Int32):
+ br bb2
+
+bb2:
+ apply %3(%0) : $@convention(thin) (@inout Builtin.Int32) -> ()
+ %4 = load %phi1 : $*Builtin.Int32
+ %6 = apply %unknown_value_fn() : $@convention(thin) () -> Builtin.Int32
+ %33 = builtin "cmp_eq_Int32"(%4 : $Builtin.Int32, %6 : $Builtin.Int32) : $Builtin.Int1
+ cond_br %33, bb2, bb3
+
+bb3:
+ %9999 = tuple()
+ dealloc_stack %0 : $*Builtin.Int32
+ return %9999 : $()
+}
diff --git a/test/SILOptimizer/loweraggregateinstrs.sil b/test/SILOptimizer/loweraggregateinstrs.sil
index 600c963..db385d1 100644
--- a/test/SILOptimizer/loweraggregateinstrs.sil
+++ b/test/SILOptimizer/loweraggregateinstrs.sil
@@ -1,5 +1,9 @@
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -enable-expand-all %s -lower-aggregate-instrs | %FileCheck %s
+// This file makes sure that the mechanics of expanding aggregate instructions
+// work. With that in mind, we expand all structs here ignoring code-size
+// trade-offs.
+
sil_stage canonical
import Swift
diff --git a/test/SILOptimizer/loweraggregateinstrs_codesize.sil b/test/SILOptimizer/loweraggregateinstrs_codesize.sil
new file mode 100644
index 0000000..3f0aae1
--- /dev/null
+++ b/test/SILOptimizer/loweraggregateinstrs_codesize.sil
@@ -0,0 +1,126 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -lower-aggregate-instrs | %FileCheck %s
+
+// This file makes sure that given the current code-size metric we properly
+// expand operations for small structs and not for large structs in a consistent
+// way for all operations we expand.
+
+sil_stage canonical
+
+import Swift
+import Builtin
+
+class C1 {
+ var data : Builtin.Int64
+ init()
+}
+
+class C2 {
+ var data : Builtin.FPIEEE32
+ init()
+}
+
+class C3 {
+ var data : Builtin.FPIEEE64
+ init()
+}
+
+struct S2 {
+ var cls1 : C1
+ var cls2 : C2
+ var trivial : Builtin.FPIEEE32
+}
+
+struct S {
+ var trivial : Builtin.Int64
+ var cls : C3
+ var inner_struct : S2
+}
+
+enum E {
+ case NoElement()
+ case TrivialElement(Builtin.Int64)
+ case ReferenceElement(C1)
+ case StructNonTrivialElt(S)
+ case TupleNonTrivialElt((Builtin.Int64, S, C3))
+}
+
+// This struct is larger than our current code-size limit (> 6 leaf nodes).
+struct LargeStruct {
+ var trivial1 : Builtin.Int64
+ var cls : S
+ var trivial2 : Builtin.Int64
+ var trivial3 : Builtin.Int64
+}
+
+///////////
+// Tests //
+///////////
+
+// This test makes sure that we /do not/ expand retain_value, release_value and
+// promote copy_addr/destroy_value to non-expanded retain_value, release_value.
+// CHECK-LABEL: sil @large_struct_test : $@convention(thin) (@owned LargeStruct, @in LargeStruct) -> () {
+// CHECK: bb0([[ARG0:%.*]] : $LargeStruct, [[ARG1:%.*]] : $*LargeStruct):
+// CHECK: retain_value [[ARG0]]
+// CHECK: release_value [[ARG0]]
+// CHECK: [[ALLOC_STACK:%.*]] = alloc_stack $LargeStruct
+// CHECK: [[LOADED_ARG1:%.*]] = load [[ARG1]]
+// CHECK: [[LOADED_OLD_VAL:%.*]] = load [[ALLOC_STACK]]
+// CHECK: retain_value [[LOADED_ARG1]]
+// CHECK: release_value [[LOADED_OLD_VAL]]
+// CHECK: store [[LOADED_ARG1]] to [[ALLOC_STACK]]
+// CHECK: [[LOADED_ARG1:%.*]] = load [[ARG1]]
+// CHECK: release_value [[LOADED_ARG1]]
+// CHECK: dealloc_stack [[ALLOC_STACK]]
+// CHECK: } // end sil function 'large_struct_test'
+sil @large_struct_test : $@convention(thin) (@owned LargeStruct, @in LargeStruct) -> () {
+bb0(%0 : $LargeStruct, %1 : $*LargeStruct):
+ retain_value %0 : $LargeStruct
+ release_value %0 : $LargeStruct
+ %2 = alloc_stack $LargeStruct
+ copy_addr %1 to %2 : $*LargeStruct
+ destroy_addr %1 : $*LargeStruct
+ dealloc_stack %2 : $*LargeStruct
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// CHECK-LABEL: sil @small_struct_test : $@convention(thin) (@owned S2, @in S2) -> () {
+// CHECK: bb0([[ARG0:%.*]] : $S2, [[ARG1:%.*]] : $*S2):
+// CHECK: [[ARG0cls1:%.*]] = struct_extract [[ARG0]] : $S2, #S2.cls1
+// CHECK: strong_retain [[ARG0cls1]] : $C1
+// CHECK: [[ARG0cls2:%.*]] = struct_extract [[ARG0]] : $S2, #S2.cls2
+// CHECK: strong_retain [[ARG0cls2]] : $C2
+// CHECK: [[ARG0cls1:%.*]] = struct_extract [[ARG0]] : $S2, #S2.cls1
+// CHECK: strong_release [[ARG0cls1]] : $C1
+// CHECK: [[ARG0cls2:%.*]] = struct_extract [[ARG0]] : $S2, #S2.cls2
+// CHECK: strong_release [[ARG0cls2]] : $C2
+//
+// CHECK: [[ALLOC_STACK:%.*]] = alloc_stack $S2
+// CHECK: [[LOADED_ARG1:%.*]] = load [[ARG1]]
+// CHECK: [[LOADED_OLDVALUE:%.*]] = load [[ALLOC_STACK]]
+// CHECK: [[LOADED_ARG1cls1:%.*]] = struct_extract [[LOADED_ARG1]] : $S2, #S2.cls1
+// CHECK: strong_retain [[LOADED_ARG1cls1]] : $C1
+// CHECK: [[LOADED_ARG1cls2:%.*]] = struct_extract [[LOADED_ARG1]] : $S2, #S2.cls2
+// CHECK: strong_retain [[LOADED_ARG1cls2]] : $C2
+// CHECK: [[LOADED_OLDVALUEcls1:%.*]] = struct_extract [[LOADED_OLDVALUE]] : $S2, #S2.cls1
+// CHECK: strong_release [[LOADED_OLDVALUEcls1]] : $C1
+// CHECK: [[LOADED_OLDVALUEcls2:%.*]] = struct_extract [[LOADED_OLDVALUE]] : $S2, #S2.cls2
+// CHECK: strong_release [[LOADED_OLDVALUEcls2]] : $C2
+//
+// CHECK: [[LOADED_ARG1:%.*]] = load [[ARG1]]
+// CHECK: [[LOADED_ARG1cls1:%.*]] = struct_extract [[LOADED_ARG1]] : $S2, #S2.cls1
+// CHECK: strong_release [[LOADED_ARG1cls1]] : $C1
+// CHECK: [[LOADED_ARG1cls2:%.*]] = struct_extract [[LOADED_ARG1]] : $S2, #S2.cls2
+// CHECK: strong_release [[LOADED_ARG1cls2]] : $C2
+// CHECK: } // end sil function 'small_struct_test'
+sil @small_struct_test : $@convention(thin) (@owned S2, @in S2) -> () {
+bb0(%0 : $S2, %1 : $*S2):
+ retain_value %0 : $S2
+ release_value %0 : $S2
+ %2 = alloc_stack $S2
+ copy_addr %1 to %2 : $*S2
+ destroy_addr %1 : $*S2
+ dealloc_stack %2 : $*S2
+ %9999 = tuple()
+ return %9999 : $()
+}
diff --git a/test/SILOptimizer/mem2reg.sil b/test/SILOptimizer/mem2reg.sil
index be9a350..0529921 100644
--- a/test/SILOptimizer/mem2reg.sil
+++ b/test/SILOptimizer/mem2reg.sil
@@ -3,6 +3,29 @@
import Builtin
import Swift
+//////////////////
+// Declarations //
+//////////////////
+
+class Klass {}
+
+struct SmallCodesizeStruct {
+ var cls1 : Klass
+ var cls2 : Klass
+}
+
+struct LargeCodesizeStruct {
+ var s1: SmallCodesizeStruct
+ var s2: SmallCodesizeStruct
+ var s3: SmallCodesizeStruct
+ var s4: SmallCodesizeStruct
+ var s5: SmallCodesizeStruct
+}
+
+///////////
+// Tests //
+///////////
+
// CHECK-LABEL: sil @store_only_allocas
// CHECK-NOT: alloc_stack
// CHECK: return
@@ -356,3 +379,36 @@
%4 = tuple ()
return %4 : $()
}
+
+// Make sure that we do expand destroy_addr appropriately for code-size
+// trade-offs.
+// CHECK-LABEL: sil @large_struct_test : $@convention(thin) (@owned LargeCodesizeStruct) -> () {
+// CHECK: bb0([[ARG0:%.*]] : $LargeCodesizeStruct):
+// CHECK: release_value [[ARG0]]
+// CHECK: } // end sil function 'large_struct_test'
+sil @large_struct_test : $@convention(thin) (@owned LargeCodesizeStruct) -> () {
+bb0(%0 : $LargeCodesizeStruct):
+ %1 = alloc_stack $LargeCodesizeStruct
+ store %0 to %1 : $*LargeCodesizeStruct
+ destroy_addr %1 : $*LargeCodesizeStruct
+ dealloc_stack %1 : $*LargeCodesizeStruct
+ %7 = tuple ()
+ return %7 : $()
+}
+
+// CHECK-LABEL: sil @small_struct_test : $@convention(thin) (@owned SmallCodesizeStruct) -> () {
+// CHECK: bb0([[ARG0:%.*]] : $SmallCodesizeStruct):
+// CHECK: [[ARG0cls1:%.*]] = struct_extract [[ARG0]]
+// CHECK: strong_release [[ARG0cls1]]
+// CHECK: [[ARG0cls2:%.*]] = struct_extract [[ARG0]]
+// CHECK: strong_release [[ARG0cls2]]
+// CHECK: } // end sil function 'small_struct_test'
+sil @small_struct_test : $@convention(thin) (@owned SmallCodesizeStruct) -> () {
+bb0(%0 : $SmallCodesizeStruct):
+ %1 = alloc_stack $SmallCodesizeStruct
+ store %0 to %1 : $*SmallCodesizeStruct
+ destroy_addr %1 : $*SmallCodesizeStruct
+ dealloc_stack %1 : $*SmallCodesizeStruct
+ %7 = tuple ()
+ return %7 : $()
+}
diff --git a/test/SourceKit/CursorInfo/cursor_generics.swift b/test/SourceKit/CursorInfo/cursor_generics.swift
index e0a898f..d10ea0b 100644
--- a/test/SourceKit/CursorInfo/cursor_generics.swift
+++ b/test/SourceKit/CursorInfo/cursor_generics.swift
@@ -9,6 +9,16 @@
fatalError()
}
+// rdar://problem/36871908
+class MyType<T> {
+ let test: Bool = false
+ let items: [Int] = []
+ func myMethod() {
+ if test {}
+ for i in items {}
+ }
+}
+
// RUN: %sourcekitd-test -req=cursor -pos=1:10 %s -- %s | %FileCheck -check-prefix=CHECK1 %s
// CHECK1: <Declaration>func testGenerics<T>(x: <Type usr="s:15cursor_generics12testGenericsyx1x_tlF1TL_xmfp">T</Type>)</Declaration>
@@ -19,3 +29,11 @@
// RUN: %sourcekitd-test -req=cursor -pos=8:16 %s -- %s | %FileCheck -check-prefix=CHECK3 %s
// CHECK3: source.lang.swift.decl.generic_type_param
// CHECK3: <Declaration>A</Declaration>
+
+// RUN: %sourcekitd-test -req=cursor -pos=17:8 %s -- %s | %FileCheck -check-prefix=CHECK4 %s
+// CHECK4: source.lang.swift.ref.var.instance
+// CHECK4: <Declaration>let test: <Type usr="s:Sb">Bool</Type></Declaration>
+
+// RUN: %sourcekitd-test -req=cursor -pos=18:14 %s -- %s | %FileCheck -check-prefix=CHECK5 %s
+// CHECK5: source.lang.swift.ref.var.instance
+// CHECK5: <Declaration>let items: [<Type usr="s:Si">Int</Type>]</Declaration>
diff --git a/test/SourceKit/CursorInfo/cursor_no_cancel.swift b/test/SourceKit/CursorInfo/cursor_no_cancel.swift
index 451e3a7..80f157e 100644
--- a/test/SourceKit/CursorInfo/cursor_no_cancel.swift
+++ b/test/SourceKit/CursorInfo/cursor_no_cancel.swift
@@ -44,3 +44,6 @@
// RANGE: source.lang.swift.range.singleexpression
// RANGE: source.lang.swift.range.singleexpression
// RANGE: source.lang.swift.range.singleexpression
+
+// FIXME: this crashes very infrequently in CI
+// REQUIRES: disabled
\ No newline at end of file
diff --git a/test/SourceKit/CursorInfo/rdar_35819975.swift b/test/SourceKit/CursorInfo/rdar_35819975.swift
new file mode 100644
index 0000000..880489a
--- /dev/null
+++ b/test/SourceKit/CursorInfo/rdar_35819975.swift
@@ -0,0 +1,13 @@
+// Checks that we don't crash
+// RUN: %sourcekitd-test -req=cursor -pos=10:5 %s -- %s | %FileCheck %s
+// RUN: %sourcekitd-test -req=cursor -pos=11:11 %s -- %s | %FileCheck --check-prefix=CHECK2 %s
+// CHECK: source.lang.swift.ref.class
+// CHECK2: source.lang.swift.ref.function.constructor
+
+class Bar<T> {
+ class Inner {}
+ func foo() {
+ Inner()
+ Inner.init()
+ }
+}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index d96a358..bc96ac2 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -32,6 +32,9 @@
@objc extension PlainStruct { } // expected-error{{'@objc' can only be applied to an extension of a class}}{{1-7=}}
+class FáncyName {}
+@objc (FancyName) extension FáncyName {}
+
@objc
var subject_globalVar: Int // expected-error {{@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes}}
diff --git a/test/decl/ext/protocol.swift b/test/decl/ext/protocol.swift
index 36af2df..1425c51 100644
--- a/test/decl/ext/protocol.swift
+++ b/test/decl/ext/protocol.swift
@@ -267,6 +267,22 @@
func f4(x: NestedNominal) {}
}
+// rdar://problem/21991470 & https://bugs.swift.org/browse/SR-5022
+class NonPolymorphicInit {
+ init() { } // expected-note {{selected non-required initializer 'init()'}}
+}
+
+protocol EmptyProtocol { }
+
+// The diagnostic is not very accurate, but at least we reject this.
+
+extension EmptyProtocol where Self : NonPolymorphicInit {
+ init(string: String) {
+ self.init()
+ // expected-error@-1 {{constructing an object of class type 'Self' with a metatype value must use a 'required' initializer}}
+ }
+}
+
// ----------------------------------------------------------------------------
// Using protocol extensions to satisfy requirements
// ----------------------------------------------------------------------------
diff --git a/test/decl/nested/type_in_function.swift b/test/decl/nested/type_in_function.swift
index ab62acb..a0c6fde 100644
--- a/test/decl/nested/type_in_function.swift
+++ b/test/decl/nested/type_in_function.swift
@@ -23,7 +23,7 @@
}
protocol Racoon {
- associatedtype Stripes
+ associatedtype Stripes // expected-note{{protocol requires nested type 'Stripes'; do you want to add it?}}
}
// Types inside generic functions -- not supported yet
@@ -117,7 +117,7 @@
}
func middleFunction() {
- struct ConformingType : Racoon {
+ struct ConformingType : Racoon { // expected-error{{type 'ConformingType' does not conform to protocol 'Racoon'}}
// expected-error@-1 {{type 'ConformingType' cannot be nested in generic function 'middleFunction()'}}
typealias Stripes = A
}
diff --git a/test/decl/protocol/req/associated_type_inference.swift b/test/decl/protocol/req/associated_type_inference.swift
index 5954131..187b2d0 100644
--- a/test/decl/protocol/req/associated_type_inference.swift
+++ b/test/decl/protocol/req/associated_type_inference.swift
@@ -469,3 +469,34 @@
protocol Q17 : P17 where T == Int { }
struct S17 : Q17 { }
+
+// Typealiases from protocol extensions should not inhibit associated type
+// inference.
+protocol P18 {
+ associatedtype A
+}
+
+protocol P19 : P18 {
+ associatedtype B
+}
+
+extension P18 where Self: P19 {
+ typealias A = B
+}
+
+struct X18<A> : P18 { }
+
+// rdar://problem/16316115
+protocol HasAssoc {
+ associatedtype Assoc
+}
+
+struct DefaultAssoc {}
+
+protocol RefinesAssocWithDefault: HasAssoc {
+ associatedtype Assoc = DefaultAssoc
+}
+
+struct Foo: RefinesAssocWithDefault {
+}
+
diff --git a/test/expr/unary/keypath/keypath.swift b/test/expr/unary/keypath/keypath.swift
index 2498292..e7e6f63 100644
--- a/test/expr/unary/keypath/keypath.swift
+++ b/test/expr/unary/keypath/keypath.swift
@@ -485,6 +485,20 @@
}
}
+// SR-6744
+func sr6744() {
+ struct ABC {
+ let value: Int
+ func value(adding i: Int) -> Int { return value + i }
+ }
+
+ let abc = ABC(value: 0)
+ func get<T>(for kp: KeyPath<ABC, T>) -> T {
+ return abc[keyPath: kp]
+ }
+ _ = get(for: \.value)
+}
+
func testSyntaxErrors() { // expected-note{{}}
_ = \. ; // expected-error{{expected member name following '.'}}
_ = \.a ;
diff --git a/test/refactoring/RefactoringKind/crashers.swift b/test/refactoring/RefactoringKind/crashers.swift
new file mode 100644
index 0000000..e0e46af
--- /dev/null
+++ b/test/refactoring/RefactoringKind/crashers.swift
@@ -0,0 +1,11 @@
+// rdar://36755861
+func doit(_: ()->()) {}
+struct S {}
+func foo() {
+ doit {
+ let s = S()
+ }
+}
+
+// RUN: %refactor -source-filename %s -pos=6:5 -end-pos=6:13 | %FileCheck %s -check-prefix=CHECK1
+// CHECK1: Action begins
diff --git a/test/stdlib/FlatMapDeprecation.swift b/test/stdlib/FlatMapDeprecation.swift
index 4567b2b..8408733 100644
--- a/test/stdlib/FlatMapDeprecation.swift
+++ b/test/stdlib/FlatMapDeprecation.swift
@@ -3,30 +3,30 @@
func flatMapOnSequence<
S : Sequence
>(xs: S, f: (S.Element) -> S.Element?) {
- _ = xs.flatMap(f) // expected-warning {{deprecated}} expected-note {{compactMap}}
+ _ = xs.flatMap(f) // expected-warning {{'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value}} expected-note {{compactMap}}
}
func flatMapOnLazySequence<
S : LazySequenceProtocol
>(xs: S, f: (S.Element) -> S.Element?) {
- _ = xs.flatMap(f) // expected-warning {{deprecated}} expected-note {{compactMap}}
+ _ = xs.flatMap(f) // expected-warning {{'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value}} expected-note {{compactMap}}
}
func flatMapOnLazyCollection<
C : LazyCollectionProtocol
>(xs: C, f: (C.Element) -> C.Element?) {
- _ = xs.flatMap(f) // expected-warning {{deprecated}} expected-note {{compactMap}}
+ _ = xs.flatMap(f) // expected-warning {{'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value}} expected-note {{compactMap}}
}
func flatMapOnLazyBidirectionalCollection<
C : LazyCollectionProtocol & BidirectionalCollection
>(xs: C, f: (C.Element) -> C.Element?)
where C.Elements : BidirectionalCollection {
- _ = xs.flatMap(f) // expected-warning {{deprecated}} expected-note {{compactMap}}
+ _ = xs.flatMap(f) // expected-warning {{'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value}} expected-note {{compactMap}}
}
func flatMapOnCollectinoOfStrings<
C : Collection
>(xs: C, f: (C.Element) -> String?) {
- _ = xs.flatMap(f) // expected-warning {{deprecated}} expected-note {{compactMap}}
+ _ = xs.flatMap(f) // expected-warning {{'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value}} expected-note {{compactMap}}
}
diff --git a/test/stdlib/TestData.swift b/test/stdlib/TestData.swift
index 6910166..117b432 100644
--- a/test/stdlib/TestData.swift
+++ b/test/stdlib/TestData.swift
@@ -1,3 +1,4 @@
+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
@@ -3721,6 +3722,25 @@
}
expectEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
}
+
+ func test_byte_access_of_discontiguousData() {
+ var d = DispatchData.empty
+ let bytes: [UInt8] = [0, 1, 2, 3, 4, 5]
+ for _ in 0..<3 {
+ bytes.withUnsafeBufferPointer {
+ d.append($0)
+ }
+ }
+ let ref = d as AnyObject
+ let data = ref as! Data
+
+ let cnt = data.count - 4
+ let t = data.dropFirst(4).withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in
+ return Data(bytes: bytes, count: cnt)
+ }
+
+ expectEqual(Data(bytes: [4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5]), t)
+ }
}
#if !FOUNDATION_XCTEST
@@ -4037,6 +4057,7 @@
DataTests.test("test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
DataTests.test("test_validateMutation_slice_customBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_customBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
DataTests.test("test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
+DataTests.test("test_byte_access_of_discontiguousData") { TestData().test_byte_access_of_discontiguousData() }
// XCTest does not have a crash detection, whereas lit does
DataTests.test("bounding failure subdata") {
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
index a96492b..7d1a749 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
@@ -694,7 +694,6 @@
static bool passCursorInfoForDecl(SourceFile* SF,
const ValueDecl *VD,
const ModuleDecl *MainModule,
- const Type Ty,
const Type ContainerTy,
bool IsRef,
bool RetrieveRefactoring,
@@ -710,7 +709,7 @@
return true;
SmallString<64> SS;
- auto BaseType = findBaseTypeForReplacingArchetype(VD, Ty);
+ auto BaseType = findBaseTypeForReplacingArchetype(VD, ContainerTy);
bool InSynthesizedExtension = false;
if (BaseType) {
if (auto Target = BaseType->getAnyNominal()) {
@@ -1293,11 +1292,17 @@
CompInvok, Receiver);
return;
case CursorInfoKind::ValueRef: {
- ValueDecl *VD = CursorInfo.CtorTyRef ? CursorInfo.CtorTyRef : CursorInfo.ValueD;
+ ValueDecl *VD = CursorInfo.ValueD;
+ Type ContainerType = CursorInfo.ContainerType;
+ if (CursorInfo.CtorTyRef) {
+ // Treat constructor calls, e.g. MyType(), as the type itself,
+ // rather than its constructor.
+ VD = CursorInfo.CtorTyRef;
+ ContainerType = Type();
+ }
bool Failed = passCursorInfoForDecl(&AstUnit->getPrimarySourceFile(),
VD, MainModule,
- CursorInfo.ContainerType,
- CursorInfo.ContainerType,
+ ContainerType,
CursorInfo.IsRef,
Actionables,
CursorInfo,
@@ -1589,7 +1594,7 @@
// FIXME: Should pass the main module for the interface but currently
// it's not necessary.
passCursorInfoForDecl(
- /*SourceFile*/nullptr, Entity.Dcl, /*MainModule*/ nullptr, Type(),
+ /*SourceFile*/nullptr, Entity.Dcl, /*MainModule*/ nullptr,
Type(), Entity.IsRef, Actionables, ResolvedCursorInfo(),
/*OrigBufferID=*/None, SourceLoc(),
{}, *this, Invok, {}, Receiver);
@@ -1780,7 +1785,7 @@
}
bool Failed =
passCursorInfoForDecl(/*SourceFile*/nullptr, VD, MainModule, selfTy,
- Type(), /*IsRef=*/false, false, ResolvedCursorInfo(),
+ /*IsRef=*/false, false, ResolvedCursorInfo(),
BufferID, SourceLoc(), {}, Lang, CompInvok,
PreviousASTSnaps, Receiver);
if (Failed) {
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 3933c91..2b21474 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -396,6 +396,12 @@
llvm::cl::cat(Category),
llvm::cl::init(true));
+static llvm::cl::opt<bool>
+CodeCompletionComments("code-completion-comments",
+ llvm::cl::desc("Include comments in code completion results"),
+ llvm::cl::cat(Category),
+ llvm::cl::init(false));
+
static llvm::cl::opt<std::string>
DebugClientDiscriminator("debug-client-discriminator",
llvm::cl::desc("A discriminator to prefer in lookups"),
@@ -671,7 +677,8 @@
StringRef SecondSourceFileName,
StringRef CodeCompletionToken,
bool CodeCompletionDiagnostics,
- bool CodeCompletionKeywords) {
+ bool CodeCompletionKeywords,
+ bool CodeCompletionComments) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
llvm::MemoryBuffer::getFile(SourceFilename);
if (!FileBufOrErr) {
@@ -712,7 +719,7 @@
// Create a CodeCompletionConsumer.
std::unique_ptr<ide::CodeCompletionConsumer> Consumer(
new ide::PrintingCodeCompletionConsumer(
- llvm::outs(), CodeCompletionKeywords));
+ llvm::outs(), CodeCompletionKeywords, CodeCompletionComments));
// Create a factory for code completion callbacks that will feed the
// Consumer.
@@ -2961,7 +2968,8 @@
}
ide::PrintingCodeCompletionConsumer Consumer(
- llvm::outs(), options::CodeCompletionKeywords);
+ llvm::outs(), options::CodeCompletionKeywords,
+ options::CodeCompletionComments);
for (StringRef filename : options::InputFilenames) {
auto resultsOpt = ide::OnDiskCodeCompletionCache::getFromFile(filename);
if (!resultsOpt) {
@@ -3153,7 +3161,8 @@
options::SecondSourceFilename,
options::CodeCompletionToken,
options::CodeCompletionDiagnostics,
- options::CodeCompletionKeywords);
+ options::CodeCompletionKeywords,
+ options::CodeCompletionComments);
break;
case ActionType::REPLCodeCompletion:
diff --git a/validation-test/Sema/type_checker_perf/slow/rdar23620262.swift b/validation-test/Sema/type_checker_perf/slow/rdar23620262.swift
index ab2d767..6acc38e 100644
--- a/validation-test/Sema/type_checker_perf/slow/rdar23620262.swift
+++ b/validation-test/Sema/type_checker_perf/slow/rdar23620262.swift
@@ -1,5 +1,6 @@
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
// REQUIRES: tools-release,no_asserts
+// REQUIRES: disabled-rdar35803518
let a: [Double] = []
_ = a.map { $0 - 1.0 }
diff --git a/validation-test/compiler_crashers_2_fixed/0138-rdar36449760.swift b/validation-test/compiler_crashers_2_fixed/0138-rdar36449760.swift
new file mode 100644
index 0000000..114d5b8
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0138-rdar36449760.swift
@@ -0,0 +1,41 @@
+// RUN: not %target-swift-frontend %s -typecheck
+
+protocol A {
+ var question: String { get }
+
+ struct B {
+ var answer: Int = 42
+
+ func foo(a: A) {
+ _ = a.question
+ }
+ }
+}
+
+class C : A {
+ var question: String = "ultimate question"
+
+ func foo() -> B {}
+ func bar() -> A.B {}
+ func baz(b: B) {
+ _ = b.answer
+ }
+}
+
+class D : A {
+ var question: String = ""
+
+ struct E {
+ func baz(b: B) {
+ _ = b.answer
+ }
+ }
+}
+
+class F<T> : A {
+ var question: String = ""
+
+ func foo(b: B) {
+ _ = b.answer
+ }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0138-rdar36453271.swift b/validation-test/compiler_crashers_2_fixed/0138-rdar36453271.swift
new file mode 100644
index 0000000..580ea9e
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0138-rdar36453271.swift
@@ -0,0 +1,13 @@
+// RUN: %target-swift-frontend %s -emit-ir -o 0
+
+extension Slice where Base == UnsafeBufferPointer<UInt16> {
+ var rebased: UnsafeBufferPointer<UInt16> {
+ return UnsafeBufferPointer(rebasing: self)
+ }
+}
+
+extension Slice where Base == UnsafeMutableBufferPointer<UInt16> {
+ var rebased: UnsafeMutableBufferPointer<UInt16> {
+ return UnsafeMutableBufferPointer(rebasing: self)
+ }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0140-sr6746.swift b/validation-test/compiler_crashers_2_fixed/0140-sr6746.swift
new file mode 100644
index 0000000..5388e11
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0140-sr6746.swift
@@ -0,0 +1,8 @@
+// RUN: not %target-swift-frontend %s -typecheck
+struct Foo: Strideable {
+ // typealias Stride = Int
+ let x: Int
+
+ func distance(to other: Foo) -> Foo.Stride { return abs(other.x - x) }
+ func advanced(by n: Foo.Stride) -> Foo { return Foo(x: x + n) }
+}
diff --git a/validation-test/compiler_crashers/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift b/validation-test/compiler_crashers_fixed/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
similarity index 85%
rename from validation-test/compiler_crashers/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
rename to validation-test/compiler_crashers_fixed/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
index 81e2b26..c19a806 100644
--- a/validation-test/compiler_crashers/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
+++ b/validation-test/compiler_crashers_fixed/28769-conformance-gettypewitness-assoctype-nullptr-isequal-type-conflicting-type-witne.swift
@@ -5,6 +5,6 @@
// 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
+
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{{}func a{}typealias e}struct A:P{typealias e:Self.a{}typealias e:Self.a{}typealias e:P
diff --git a/validation-test/compiler_crashers/28854-known-typewitnesses-end-didnt-resolve-witness.swift b/validation-test/compiler_crashers_fixed/28854-known-typewitnesses-end-didnt-resolve-witness.swift
similarity index 84%
rename from validation-test/compiler_crashers/28854-known-typewitnesses-end-didnt-resolve-witness.swift
rename to validation-test/compiler_crashers_fixed/28854-known-typewitnesses-end-didnt-resolve-witness.swift
index e2bee9f..c20988b 100644
--- a/validation-test/compiler_crashers/28854-known-typewitnesses-end-didnt-resolve-witness.swift
+++ b/validation-test/compiler_crashers_fixed/28854-known-typewitnesses-end-didnt-resolve-witness.swift
@@ -5,8 +5,8 @@
// 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
+
+// RUN: not %target-swift-frontend %s -emit-ir
@objc protocol A
{
typealias a