diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f10e1dfedc304..5144f32e57edc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -129,6 +129,8 @@ jobs: sudo xcode-select --switch /Applications/Xcode_12.2.app/Contents/Developer/ xcodebuild -version ./utils/webassembly/ci.sh + env: + SKIP_XCODE_VERSION_CHECK: 1 # Skip upstream update the compatible Xcode version - name: Upload macOS installable archive uses: actions/upload-artifact@v1 with: diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index f63860100e928..8f6ca9158bf60 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -98,6 +98,7 @@ set(SWIFT_BENCH_MODULES single-source/Hash single-source/Histogram single-source/HTTP2StateMachine + single-source/IndexPathTest single-source/InsertCharacter single-source/IntegerParsing single-source/Integrate diff --git a/benchmark/single-source/IndexPathTest.swift b/benchmark/single-source/IndexPathTest.swift new file mode 100644 index 0000000000000..c85d5392d3c80 --- /dev/null +++ b/benchmark/single-source/IndexPathTest.swift @@ -0,0 +1,134 @@ +//===--- IndexPathTest.swift ----------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import Foundation +import TestsUtils + +let size = 200 +let increasingIndexPath = indexPath(size) +let decreasingIndexPath = indexPath(size, reversed: true) +let increasingMaxMiddleIndexPath = indexPath(size, middle: size + 1) +let increasingMinMiddleIndexPath = indexPath(size, middle: -1) +let tags: [BenchmarkCategory] = [.validation, .api, .IndexPath] + +public let IndexPathTest = [ + BenchmarkInfo( + name: "IndexPath.Subscript.Mutation", + runFunction: run_IndexPathSubscriptMutation, + tags: tags, + setUpFunction: { blackHole(increasingIndexPath) }), + BenchmarkInfo( + name: "IndexPath.Subscript.Range.Mutation", + runFunction: run_IndexPathSubscriptRangeMutation, + tags: tags, + setUpFunction: { blackHole(increasingIndexPath) }), + BenchmarkInfo( + name: "IndexPath.Max", + runFunction: run_IndexPathMax, + tags: tags, + setUpFunction: { + blackHole(decreasingIndexPath) + blackHole(increasingMaxMiddleIndexPath) + blackHole(increasingIndexPath) + }), + BenchmarkInfo( + name: "IndexPath.Min", + runFunction: run_IndexPathMin, + tags: tags, + setUpFunction: { + blackHole(increasingIndexPath) + blackHole(increasingMinMiddleIndexPath) + blackHole(decreasingIndexPath) + }), +] + +func indexPath(_ size: Int, reversed: Bool = false) -> IndexPath { + let indexes = Array(0.. IndexPath { + var indexes = Array(0.. Void +) { + for _ in 0.. TheSILTypes; std::unique_ptr DiagVerifier; + /// A cache describing the set of inter-module dependencies that have been queried. + /// Null if not present. + std::unique_ptr ModDepCache; + /// Null if no tracker. std::unique_ptr DepTracker; /// If there is no stats output directory by the time the @@ -487,6 +491,8 @@ class CompilerInstance { DependencyTracker *getDependencyTracker() { return DepTracker.get(); } const DependencyTracker *getDependencyTracker() const { return DepTracker.get(); } + ModuleDependenciesCache *getModuleDependencyCache() { return ModDepCache.get(); } + UnifiedStatsReporter *getStatsReporter() const { return Stats.get(); } /// Retrieve the main module containing the files being compiled. @@ -552,6 +558,7 @@ class CompilerInstance { bool setUpVirtualFileSystemOverlays(); void setUpLLVMArguments(); void setUpDiagnosticOptions(); + void setUpModuleDependencyCacheIfNeeded(); bool setUpModuleLoaders(); bool setUpInputs(); bool setUpASTContextIfNeeded(); diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index d77f977c47714..96725a6fb90ab 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -292,6 +292,12 @@ class FrontendOptions { /// any merge-modules jobs. bool EnableExperimentalCrossModuleIncrementalBuild = false; + /// Best effort to output a .swiftmodule regardless of any compilation + /// errors. SIL generation and serialization is skipped entirely when there + /// are errors. The resulting serialized AST may include errors types and + /// skip nodes entirely, depending on the errors involved. + bool AllowModuleWithCompilerErrors = false; + /// The different modes for validating TBD against the LLVM IR. enum class TBDValidationMode { Default, ///< Do the default validation for the current platform. diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 5bd469453947b..2a8a412f046a1 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -779,4 +779,9 @@ def experimental_skip_all_function_bodies: Flag<["-"], "experimental-skip-all-function-bodies">, HelpText<"Skip type-checking function bodies and all SIL generation">; +def experimental_allow_module_with_compiler_errors: + Flag<["-"], "experimental-allow-module-with-compiler-errors">, + Flags<[HelpHidden]>, + HelpText<"Attempt to output .swiftmodule, regardless of compilation errors">; + } // end let Flags = [FrontendOption, NoDriverOption, HelpHidden] diff --git a/include/swift/Runtime/Concurrent.h b/include/swift/Runtime/Concurrent.h index 11c382eb3de5e..60fe54e9e7cdd 100644 --- a/include/swift/Runtime/Concurrent.h +++ b/include/swift/Runtime/Concurrent.h @@ -624,6 +624,69 @@ struct ConcurrentReadableHashMap { /// is stored inline. We work around this contradiction by considering the /// first index to always be occupied with a value that never matches any key. struct IndexStorage { + using RawType = uintptr_t; + + RawType Value; + + static constexpr uintptr_t log2(uintptr_t x) { + return x <= 1 ? 0 : log2(x >> 1) + 1; + } + + static constexpr uintptr_t InlineIndexBits = 4; + static constexpr uintptr_t InlineIndexMask = 0xF; + static constexpr uintptr_t InlineCapacity = + sizeof(RawType) * CHAR_BIT / InlineIndexBits; + static constexpr uintptr_t InlineCapacityLog2 = log2(InlineCapacity); + + // Indices can be stored in different ways, depending on how big they need + // to be. The index mode is stored in the bottom two bits of Value. The + // meaning of the rest of Value depends on the mode. + enum class IndexMode { + // Value is treated as an array of four-bit integers, storing the indices. + // The first element overlaps with the mode, and is never used. + Inline, + + // The rest of Value holds a pointer to storage. The first byte of this + // storage holds the log2 of the storage capacity. The storage is treated + // as an array of 8, 16, or 32-bit integers. The first element overlaps + // with the capacity, and is never used. + Array8, + Array16, + Array32, + }; + + IndexStorage() : Value(0) {} + IndexStorage(RawType value) : Value(value) {} + IndexStorage(void *ptr, unsigned indexSize, uint8_t capacityLog2) { + assert(capacityLog2 > InlineCapacityLog2); + IndexMode mode; + switch (indexSize) { + case sizeof(uint8_t): + mode = IndexMode::Array8; + break; + case sizeof(uint16_t): + mode = IndexMode::Array16; + break; + case sizeof(uint32_t): + mode = IndexMode::Array32; + break; + default: + swift_unreachable("unknown index size"); + } + Value = reinterpret_cast(ptr) | static_cast(mode); + *reinterpret_cast(ptr) = capacityLog2; + } + + bool valueIsPointer() { return Value & 3; } + + void *pointer() { + if (valueIsPointer()) + return (void *)(Value & (RawType)~3); + return nullptr; + } + + IndexMode indexMode() { return IndexMode(Value & 3); } + // Index size is variable based on capacity, either 8, 16, or 32 bits. // // This is somewhat conservative. We could have, for example, a capacity of @@ -631,18 +694,6 @@ struct ConcurrentReadableHashMap { // indices. However, taking advantage of this would require reallocating // the index storage when the element count crossed a threshold, which is // more complex, and the advantages are minimal. This keeps it simple. - // - // The first byte of the storage is the log 2 of the capacity. The remaining - // storage is then an array of 8, 16, or 32 bit integers, depending on the - // capacity number. This union allows us to access the capacity, and then - // access the rest of the storage by taking the address of one of the - // IndexZero members and indexing into it (always avoiding index 0). - union { - uint8_t CapacityLog2; - std::atomic IndexZero8; - std::atomic IndexZero16; - std::atomic IndexZero32; - }; // Get the size, in bytes, of the index needed for the given capacity. static unsigned indexSize(uint8_t capacityLog2) { @@ -653,46 +704,66 @@ struct ConcurrentReadableHashMap { return sizeof(uint32_t); } - unsigned indexSize() { return indexSize(CapacityLog2); } + uint8_t getCapacityLog2() { + if (auto *ptr = pointer()) + return *reinterpret_cast(ptr); + return InlineCapacityLog2; + } - static IndexStorage *allocate(size_t capacityLog2) { + static IndexStorage allocate(size_t capacityLog2) { assert(capacityLog2 > 0); size_t capacity = 1UL << capacityLog2; - auto *ptr = reinterpret_cast( - calloc(capacity, indexSize(capacityLog2))); + unsigned size = indexSize(capacityLog2); + auto *ptr = calloc(capacity, size); if (!ptr) swift::crash("Could not allocate memory."); - ptr->CapacityLog2 = capacityLog2; - return ptr; + return IndexStorage(ptr, size, capacityLog2); } unsigned loadIndexAt(size_t i, std::memory_order order) { assert(i > 0 && "index zero is off-limits, used to store capacity"); - - switch (indexSize()) { - case sizeof(uint8_t): - return (&IndexZero8)[i].load(order); - case sizeof(uint16_t): - return (&IndexZero16)[i].load(order); - case sizeof(uint32_t): - return (&IndexZero32)[i].load(order); - default: - swift_unreachable("unknown index size"); + assert(i < (1 << getCapacityLog2()) && + "index is off the end of the indices"); + + switch (indexMode()) { + case IndexMode::Inline: + return (Value >> (i * InlineIndexBits)) & InlineIndexMask; + case IndexMode::Array8: + return ((std::atomic *)pointer())[i].load(order); + case IndexMode::Array16: + return ((std::atomic *)pointer())[i].load(order); + case IndexMode::Array32: + return ((std::atomic *)pointer())[i].load(order); } } - void storeIndexAt(unsigned value, size_t i, std::memory_order order) { + void storeIndexAt(std::atomic *inlineStorage, unsigned value, + size_t i, std::memory_order order) { assert(i > 0 && "index zero is off-limits, used to store capacity"); - - switch (indexSize()) { - case sizeof(uint8_t): - return (&IndexZero8)[i].store(value, order); - case sizeof(uint16_t): - return (&IndexZero16)[i].store(value, order); - case sizeof(uint32_t): - return (&IndexZero32)[i].store(value, order); - default: - swift_unreachable("unknown index size"); + assert(i < (1 << getCapacityLog2()) && + "index is off the end of the indices"); + + switch (indexMode()) { + case IndexMode::Inline: { + assert(value == (value & InlineIndexMask) && "value is too big to fit"); + auto shift = i * InlineIndexBits; + assert((Value & (InlineIndexMask << shift)) == 0 && + "can't overwrite an existing index"); + assert(Value == inlineStorage->load(std::memory_order_relaxed) && + "writing with a stale IndexStorage"); + auto newStorage = Value | ((RawType)value << shift); + inlineStorage->store(newStorage, order); + break; + } + case IndexMode::Array8: + ((std::atomic *)pointer())[i].store(value, order); + break; + case IndexMode::Array16: + ((std::atomic *)pointer())[i].store(value, order); + break; + case IndexMode::Array32: + ((std::atomic *)pointer())[i].store(value, order); + break; } } }; @@ -753,7 +824,11 @@ struct ConcurrentReadableHashMap { std::atomic Elements{nullptr}; /// The array of indices. - std::atomic Indices{nullptr}; + /// + /// This has to be stored as a IndexStorage::RawType instead of a IndexStorage + /// because some of our targets don't support interesting structs as atomic + /// types. See also MetadataCache::TrackingInfo which uses the same technique. + std::atomic Indices{0}; /// The writer lock, which must be taken before any mutation of the table. MutexTy WriterLock; @@ -798,18 +873,17 @@ struct ConcurrentReadableHashMap { /// returning the new array with all existing indices copied into it. This /// operation performs a rehash, so that the indices are in the correct /// location in the new array. - IndexStorage *resize(IndexStorage *indices, uint8_t indicesCapacityLog2, - ElemTy *elements) { - // Double the size. Start with 16 (fits into 16-byte malloc - // bucket), which is 2^4. - size_t newCapacityLog2 = indices ? indicesCapacityLog2 + 1 : 4; + IndexStorage resize(IndexStorage indices, uint8_t indicesCapacityLog2, + ElemTy *elements) { + // Double the size. + size_t newCapacityLog2 = indicesCapacityLog2 + 1; size_t newMask = (1UL << newCapacityLog2) - 1; - IndexStorage *newIndices = IndexStorage::allocate(newCapacityLog2); + IndexStorage newIndices = IndexStorage::allocate(newCapacityLog2); size_t indicesCount = 1UL << indicesCapacityLog2; for (size_t i = 1; i < indicesCount; i++) { - unsigned index = indices->loadIndexAt(i, std::memory_order_relaxed); + unsigned index = indices.loadIndexAt(i, std::memory_order_relaxed); if (index == 0) continue; @@ -819,15 +893,16 @@ struct ConcurrentReadableHashMap { size_t newI = hash & newMask; // Index 0 is unusable (occupied by the capacity), so always skip it. while (newI == 0 || - newIndices->loadIndexAt(newI, std::memory_order_relaxed) != 0) { + newIndices.loadIndexAt(newI, std::memory_order_relaxed) != 0) { newI = (newI + 1) & newMask; } - newIndices->storeIndexAt(index, newI, std::memory_order_relaxed); + newIndices.storeIndexAt(nullptr, index, newI, std::memory_order_relaxed); } - Indices.store(newIndices, std::memory_order_release); + Indices.store(newIndices.Value, std::memory_order_release); - FreeListNode::add(&FreeList, indices); + if (auto *ptr = indices.pointer()) + FreeListNode::add(&FreeList, ptr); return newIndices; } @@ -838,12 +913,10 @@ struct ConcurrentReadableHashMap { /// of the new element would be stored. template static std::pair - find(const KeyTy &key, IndexStorage *indices, size_t elementCount, + find(const KeyTy &key, IndexStorage indices, size_t elementCount, ElemTy *elements) { - if (!indices) - return {nullptr, 0}; auto hash = hash_value(key); - auto indicesMask = (1UL << indices->CapacityLog2) - 1; + auto indicesMask = (1UL << indices.getCapacityLog2()) - 1; auto i = hash & indicesMask; while (true) { @@ -851,7 +924,7 @@ struct ConcurrentReadableHashMap { if (i == 0) i++; - auto index = indices->loadIndexAt(i, std::memory_order_acquire); + auto index = indices.loadIndexAt(i, std::memory_order_acquire); // Element indices are 1-based, 0 means no entry. if (index == 0) return {nullptr, i}; @@ -884,12 +957,12 @@ struct ConcurrentReadableHashMap { /// Readers take a snapshot of the hash map, then work with the snapshot. class Snapshot { ConcurrentReadableHashMap *Map; - IndexStorage *Indices; + IndexStorage Indices; ElemTy *Elements; size_t ElementCount; public: - Snapshot(ConcurrentReadableHashMap *map, IndexStorage *indices, + Snapshot(ConcurrentReadableHashMap *map, IndexStorage indices, ElemTy *elements, size_t elementCount) : Map(map), Indices(indices), Elements(elements), ElementCount(elementCount) {} @@ -905,7 +978,7 @@ struct ConcurrentReadableHashMap { /// Search for an element matching the given key. Returns a pointer to the /// found element, or nullptr if no matching element exists. template const ElemTy *find(const KeyTy &key) { - if (!Indices || !ElementCount || !Elements) + if (!Indices.Value || !ElementCount || !Elements) return nullptr; return ConcurrentReadableHashMap::find(key, Indices, ElementCount, Elements) @@ -937,7 +1010,7 @@ struct ConcurrentReadableHashMap { // pointer can just mean a concurrent insert that triggered a resize of the // elements array. This is harmless aside from a small performance hit, and // should not happen often. - IndexStorage *indices; + IndexStorage indices; size_t elementCount; ElementStorage *elements; ElementStorage *elements2; @@ -972,11 +1045,8 @@ struct ConcurrentReadableHashMap { void getOrInsert(KeyTy key, const Call &call) { ScopedLockTy guard(WriterLock); - auto *indices = Indices.load(std::memory_order_relaxed); - if (!indices) - indices = resize(indices, 0, nullptr); - - auto indicesCapacityLog2 = indices->CapacityLog2; + auto indices = IndexStorage{Indices.load(std::memory_order_relaxed)}; + auto indicesCapacityLog2 = indices.getCapacityLog2(); auto elementCount = ElementCount.load(std::memory_order_relaxed); auto *elements = Elements.load(std::memory_order_relaxed); auto *elementsPtr = elements ? elements->data() : nullptr; @@ -1012,8 +1082,8 @@ struct ConcurrentReadableHashMap { assert(hash_value(key) == hash_value(*element) && "Element must have the same hash code as its key."); ElementCount.store(elementCount + 1, std::memory_order_release); - indices->storeIndexAt(elementCount + 1, found.second, - std::memory_order_release); + indices.storeIndexAt(&Indices, elementCount + 1, found.second, + std::memory_order_release); } deallocateFreeListIfSafe(); @@ -1024,16 +1094,17 @@ struct ConcurrentReadableHashMap { void clear() { ScopedLockTy guard(WriterLock); - auto *indices = Indices.load(std::memory_order_relaxed); + IndexStorage indices = Indices.load(std::memory_order_relaxed); auto *elements = Elements.load(std::memory_order_relaxed); // Order doesn't matter here, snapshots will gracefully handle any field // being NULL/0 while the others are not. - Indices.store(nullptr, std::memory_order_relaxed); + Indices.store(0, std::memory_order_relaxed); ElementCount.store(0, std::memory_order_relaxed); Elements.store(nullptr, std::memory_order_relaxed); - FreeListNode::add(&FreeList, indices); + if (auto *ptr = indices.pointer()) + FreeListNode::add(&FreeList, ptr); FreeListNode::add(&FreeList, elements); deallocateFreeListIfSafe(); diff --git a/include/swift/SIL/MemAccessUtils.h b/include/swift/SIL/MemAccessUtils.h index 2b01282935a2e..9439d50db3044 100644 --- a/include/swift/SIL/MemAccessUtils.h +++ b/include/swift/SIL/MemAccessUtils.h @@ -1239,6 +1239,7 @@ inline Operand *getAccessProjectionOperand(SingleValueInstruction *svi) { case SILInstructionKind::TupleElementAddrInst: case SILInstructionKind::IndexAddrInst: case SILInstructionKind::TailAddrInst: + case SILInstructionKind::InitEnumDataAddrInst: // open_existential_addr and unchecked_take_enum_data_addr are problematic // because they both modify memory and are access projections. Ideally, they // would not be casts, but will likely be eliminated with opaque values. diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h index d814335e3f2f0..0e786cd2ff202 100644 --- a/include/swift/SIL/SILValue.h +++ b/include/swift/SIL/SILValue.h @@ -92,6 +92,10 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, /// have. struct ValueOwnershipKind { enum innerty : uint8_t { + /// A value used to signal that two merged ValueOwnershipKinds were + /// incompatible. + Invalid = 0, + /// A SILValue with `Unowned` ownership kind is an independent value that /// has a lifetime that is only guaranteed to last until the next program /// visible side-effect. To maintain the lifetime of an unowned value, it @@ -156,7 +160,10 @@ struct ValueOwnershipKind { return Value == b; } - Optional merge(ValueOwnershipKind RHS) const; + /// Returns true if this ValueOwnershipKind is not invalid. + explicit operator bool() const { return Value != Invalid; } + + ValueOwnershipKind merge(ValueOwnershipKind RHS) const; /// Given that there is an aggregate value (like a struct or enum) with this /// ownership kind, and a subobject of type Proj is being projected from the @@ -172,6 +179,8 @@ struct ValueOwnershipKind { /// kinds. UseLifetimeConstraint getForwardingLifetimeConstraint() const { switch (Value) { + case ValueOwnershipKind::Invalid: + llvm_unreachable("Invalid ownership doesnt have a lifetime constraint!"); case ValueOwnershipKind::None: case ValueOwnershipKind::Guaranteed: case ValueOwnershipKind::Unowned: @@ -188,7 +197,7 @@ struct ValueOwnershipKind { /// The reason why we do not compare directy is to allow for /// ValueOwnershipKind::None to merge into other forms of ValueOwnershipKind. bool isCompatibleWith(ValueOwnershipKind other) const { - return merge(other).hasValue(); + return bool(merge(other)); } /// Returns isCompatibleWith(other.getOwnershipKind()). @@ -197,16 +206,14 @@ struct ValueOwnershipKind { /// dependencies. bool isCompatibleWith(SILValue other) const; - template - static Optional merge(RangeTy &&r) { - auto initial = Optional(ValueOwnershipKind::None); - return accumulate( - std::forward(r), initial, - [](Optional acc, ValueOwnershipKind x) { - if (!acc) - return acc; - return acc.getValue().merge(x); - }); + template static ValueOwnershipKind merge(RangeTy &&r) { + auto initial = ValueOwnershipKind::None; + return accumulate(std::forward(r), initial, + [](ValueOwnershipKind acc, ValueOwnershipKind x) { + if (!acc) + return acc; + return acc.merge(x); + }); } StringRef asString() const; diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index ab2aed06d0079..4bf95087852b2 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -98,7 +98,8 @@ class ExtendedValidationInfo { unsigned IsSIB : 1; unsigned IsTestable : 1; unsigned ResilienceStrategy : 2; - unsigned IsImplicitDynamicEnabled: 1; + unsigned IsImplicitDynamicEnabled : 1; + unsigned IsAllowModuleWithCompilerErrorsEnabled : 1; } Bits; public: ExtendedValidationInfo() : Bits() {} @@ -138,6 +139,12 @@ class ExtendedValidationInfo { void setResilienceStrategy(ResilienceStrategy resilience) { Bits.ResilienceStrategy = unsigned(resilience); } + bool isAllowModuleWithCompilerErrorsEnabled() { + return Bits.IsAllowModuleWithCompilerErrorsEnabled; + } + void setAllowModuleWithCompilerErrorsEnabled(bool val) { + Bits.IsAllowModuleWithCompilerErrorsEnabled = val; + } }; /// Returns info about the serialized AST in the given data. diff --git a/lib/AST/PlatformKind.cpp b/lib/AST/PlatformKind.cpp index f0f72ab2675c2..1684f363d8272 100644 --- a/lib/AST/PlatformKind.cpp +++ b/lib/AST/PlatformKind.cpp @@ -89,6 +89,8 @@ static bool isPlatformActiveForTarget(PlatformKind Platform, return Target.isWatchOS(); case PlatformKind::OpenBSD: return Target.isOSOpenBSD(); + case PlatformKind::Windows: + return Target.isOSWindows(); case PlatformKind::none: llvm_unreachable("handled above"); } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 71963672fb54e..6fae528d3e961 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -1977,6 +1977,10 @@ PlatformAvailability::PlatformAvailability(const LangOptions &langOpts) deprecatedAsUnavailableMessage = ""; break; + case PlatformKind::Windows: + deprecatedAsUnavailableMessage = ""; + break; + case PlatformKind::none: break; } @@ -2012,6 +2016,9 @@ bool PlatformAvailability::isPlatformRelevant(StringRef name) const { case PlatformKind::OpenBSD: return name == "openbsd"; + case PlatformKind::Windows: + return name == "windows"; + case PlatformKind::none: return false; } @@ -2055,6 +2062,10 @@ bool PlatformAvailability::treatDeprecatedAsUnavailable( case PlatformKind::OpenBSD: // No deprecation filter on OpenBSD return false; + + case PlatformKind::Windows: + // No deprecation filter on Windows + return false; } llvm_unreachable("Unexpected platform"); diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 478be8572806a..1c4e5febdb17e 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -217,6 +217,7 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies); Opts.UseSharedResourceFolder = !Args.hasArg(OPT_use_static_resource_dir); Opts.DisableBuildingInterface = Args.hasArg(OPT_disable_building_interface); + Opts.AllowModuleWithCompilerErrors = Args.hasArg(OPT_experimental_allow_module_with_compiler_errors); computeImportObjCHeaderOptions(); computeImplicitImportModuleNames(OPT_import_module, /*isTestable=*/false); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3d9b88affe940..d1f671d02cb9e 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -683,6 +683,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.DisableAvailabilityChecking = true; } + if (FrontendOpts.AllowModuleWithCompilerErrors) { + Opts.AllowModuleWithCompilerErrors = true; + } + return HadError || UnsupportedOS || UnsupportedArch; } diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index e57731ed88490..205683f9e0a02 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -321,11 +321,22 @@ void CompilerInstance::setupDependencyTrackerIfNeeded() { DepTracker = std::make_unique(*collectionMode); } +void CompilerInstance::setUpModuleDependencyCacheIfNeeded() { + const auto &Invocation = getInvocation(); + const auto &opts = Invocation.getFrontendOptions(); + if (opts.RequestedAction == FrontendOptions::ActionType::ScanDependencies || + opts.RequestedAction == FrontendOptions::ActionType::ScanClangDependencies) { + ModDepCache = std::make_unique(); + } +} + bool CompilerInstance::setup(const CompilerInvocation &Invok) { Invocation = Invok; setupDependencyTrackerIfNeeded(); + setUpModuleDependencyCacheIfNeeded(); + // If initializing the overlay file system fails there's no sense in // continuing because the compiler will read the wrong files. if (setUpVirtualFileSystemOverlays()) @@ -1147,7 +1158,8 @@ bool CompilerInstance::performSILProcessing(SILModule *silModule) { return runSILCrossModuleEliminatorPass(*silModule); } - if (performMandatorySILPasses(Invocation, silModule)) + if (performMandatorySILPasses(Invocation, silModule) && + !Invocation.getFrontendOptions().AllowModuleWithCompilerErrors) return true; { diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index dd88c593508f2..944895b28230f 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -1789,11 +1789,13 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) { assert(ctx.getLoadedModules().begin()->second == Instance.getMainModule()); } - // Verify the AST for all the modules we've loaded. - ctx.verifyAllLoadedModules(); + if (!opts.AllowModuleWithCompilerErrors) { + // Verify the AST for all the modules we've loaded. + ctx.verifyAllLoadedModules(); - // Verify generic signatures if we've been asked to. - verifyGenericSignaturesIfNeeded(Invocation, ctx); + // Verify generic signatures if we've been asked to. + verifyGenericSignaturesIfNeeded(Invocation, ctx); + } // Emit any additional outputs that we only need for a successful compilation. // We don't want to unnecessarily delay getting any errors back to the user. @@ -1915,7 +1917,8 @@ withSemanticAnalysis(CompilerInstance &Instance, FrontendObserver *observer, (void)migrator::updateCodeAndEmitRemapIfNeeded(&Instance); - if (Instance.getASTContext().hadError()) + if (Instance.getASTContext().hadError() && + !opts.AllowModuleWithCompilerErrors) return true; return cont(Instance); @@ -2098,7 +2101,8 @@ static bool performCompile(CompilerInstance &Instance, if (Instance.hasASTContext() && FrontendOptions::doesActionPerformEndOfPipelineActions(Action)) { performEndOfPipelineActions(Instance); - hadError |= Instance.getASTContext().hadError(); + if (!opts.AllowModuleWithCompilerErrors) + hadError |= Instance.getASTContext().hadError(); } return hadError; } @@ -2382,7 +2386,7 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance, if (PSPs.haveModuleOrModuleDocOutputPaths()) { if (Action == FrontendOptions::ActionType::MergeModules || Action == FrontendOptions::ActionType::EmitModuleOnly) { - return Context.hadError(); + return Context.hadError() && !opts.AllowModuleWithCompilerErrors; } } @@ -2400,7 +2404,7 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance, // Check if we had any errors; if we did, don't proceed to IRGen. if (Context.hadError()) - return true; + return !opts.AllowModuleWithCompilerErrors; runSILLoweringPasses(*SM); diff --git a/lib/FrontendTool/ScanDependencies.cpp b/lib/FrontendTool/ScanDependencies.cpp index b8b1d4a8b0b3c..4968a135ff3c8 100644 --- a/lib/FrontendTool/ScanDependencies.cpp +++ b/lib/FrontendTool/ScanDependencies.cpp @@ -680,8 +680,10 @@ static bool scanModuleDependencies(CompilerInstance &instance, llvm::SetVector, std::set> allModules; - // Create the module dependency cache. - ModuleDependenciesCache cache; + // Retrieve the instance's module dependency cache. + ModuleDependenciesCache *cache = instance.getModuleDependencyCache(); + assert(cache && + "Dependency Scanner expected a ModuleDependenciesCache on a compiler instance."); InterfaceSubContextDelegateImpl ASTDelegate(ctx.SourceMgr, ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts, ctx.ClangImporterOpts, @@ -697,11 +699,11 @@ static bool scanModuleDependencies(CompilerInstance &instance, if (isClang) { // Loading the clang module using Clang importer. // This action will populate the cache with the main module's dependencies. - rootDeps = ctx.getModuleDependencies(moduleName, /*IsClang*/true, cache, + rootDeps = ctx.getModuleDependencies(moduleName, /*IsClang*/true, *cache, ASTDelegate); } else { // Loading the swift module's dependencies. - rootDeps = ctx.getSwiftModuleDependencies(moduleName, cache, ASTDelegate); + rootDeps = ctx.getSwiftModuleDependencies(moduleName, *cache, ASTDelegate); } if (!rootDeps.hasValue()) { // We cannot find the clang module, abort. @@ -723,11 +725,11 @@ static bool scanModuleDependencies(CompilerInstance &instance, ++currentModuleIdx) { auto module = allModules[currentModuleIdx]; auto discoveredModules = - resolveDirectDependencies(instance, module, cache, ASTDelegate); + resolveDirectDependencies(instance, module, *cache, ASTDelegate); allModules.insert(discoveredModules.begin(), discoveredModules.end()); } // Write out the JSON description. - writeJSON(out, instance, cache, ASTDelegate, allModules.getArrayRef()); + writeJSON(out, instance, *cache, ASTDelegate, allModules.getArrayRef()); return false; } @@ -889,9 +891,11 @@ bool swift::scanDependencies(CompilerInstance &instance) { allModules.insert({mainModuleName.str(), mainDependencies.getKind()}); - // Create the module dependency cache. - ModuleDependenciesCache cache; - cache.recordDependencies(mainModuleName, std::move(mainDependencies)); + // Retrieve the instance's module dependency cache. + ModuleDependenciesCache *cache = instance.getModuleDependencyCache(); + assert(cache && + "Dependency Scanner expected a ModuleDependenciesCache on a compiler instance."); + cache->recordDependencies(mainModuleName, std::move(mainDependencies)); auto &ctx = instance.getASTContext(); auto ModuleCachePath = getModuleCachePathFromClang(ctx @@ -914,28 +918,28 @@ bool swift::scanDependencies(CompilerInstance &instance) { ++currentModuleIdx) { auto module = allModules[currentModuleIdx]; auto discoveredModules = - resolveDirectDependencies(instance, module, cache, ASTDelegate); + resolveDirectDependencies(instance, module, *cache, ASTDelegate); allModules.insert(discoveredModules.begin(), discoveredModules.end()); } // We have all explicit imports now, resolve cross import overlays. discoverCrosssImportOverlayDependencies(instance, mainModuleName, - /*All transitive dependencies*/allModules.getArrayRef().slice(1), cache, + /*All transitive dependencies*/allModules.getArrayRef().slice(1), *cache, ASTDelegate, [&](ModuleDependencyID id) { allModules.insert(id); }); // Dignose cycle in dependency graph. - if (diagnoseCycle(instance, cache, /*MainModule*/allModules.front(), ASTDelegate)) + if (diagnoseCycle(instance, *cache, /*MainModule*/allModules.front(), ASTDelegate)) return true; // Write out the JSON description. - writeJSON(out, instance, cache, ASTDelegate, allModules.getArrayRef()); + writeJSON(out, instance, *cache, ASTDelegate, allModules.getArrayRef()); // Update the dependency tracker. if (auto depTracker = instance.getDependencyTracker()) { for (auto module : allModules) { - auto deps = cache.findDependencies(module.first, module.second); + auto deps = cache->findDependencies(module.first, module.second); if (!deps) continue; diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.cpp b/lib/PrintAsObjC/DeclAndTypePrinter.cpp index bcdff13a458fd..43648aaa173d3 100644 --- a/lib/PrintAsObjC/DeclAndTypePrinter.cpp +++ b/lib/PrintAsObjC/DeclAndTypePrinter.cpp @@ -881,6 +881,9 @@ class DeclAndTypePrinter::Implementation case PlatformKind::OpenBSD: plat = "openbsd"; break; + case PlatformKind::Windows: + plat = "windows"; + break; case PlatformKind::none: llvm_unreachable("handled above"); } diff --git a/lib/SIL/IR/SILInstructions.cpp b/lib/SIL/IR/SILInstructions.cpp index 0c33c08103367..0b8ae2554ed6e 100644 --- a/lib/SIL/IR/SILInstructions.cpp +++ b/lib/SIL/IR/SILInstructions.cpp @@ -2937,5 +2937,8 @@ ReturnInst::ReturnInst(SILFunction &func, SILDebugLocation debugLoc, }); // Then merge all of our ownership kinds. Assert if we fail to merge. - ownershipKind = *ValueOwnershipKind::merge(ownershipKindRange); + ownershipKind = ValueOwnershipKind::merge(ownershipKindRange); + assert(ownershipKind != ValueOwnershipKind::Invalid && + "Conflicting ownership kinds when creating term inst from function " + "result info?!"); } diff --git a/lib/SIL/IR/SILValue.cpp b/lib/SIL/IR/SILValue.cpp index f4adab4cc7ab9..348782d940526 100644 --- a/lib/SIL/IR/SILValue.cpp +++ b/lib/SIL/IR/SILValue.cpp @@ -198,6 +198,8 @@ ValueOwnershipKind::ValueOwnershipKind(const SILFunction &F, SILType Type, StringRef ValueOwnershipKind::asString() const { switch (Value) { + case ValueOwnershipKind::Invalid: + return "invalid"; case ValueOwnershipKind::Unowned: return "unowned"; case ValueOwnershipKind::Owned: @@ -215,21 +217,27 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os, return os << kind.asString(); } -Optional -ValueOwnershipKind::merge(ValueOwnershipKind RHS) const { - auto LHSVal = Value; - auto RHSVal = RHS.Value; +ValueOwnershipKind ValueOwnershipKind::merge(ValueOwnershipKind rhs) const { + auto lhsVal = Value; + auto rhsVal = rhs.Value; - // Any merges with anything. - if (LHSVal == ValueOwnershipKind::None) { - return ValueOwnershipKind(RHSVal); - } - // Any merges with anything. - if (RHSVal == ValueOwnershipKind::None) { - return ValueOwnershipKind(LHSVal); - } + // If either lhs or rhs are invalid, return invalid. + if (lhsVal == ValueOwnershipKind::Invalid || + rhsVal == ValueOwnershipKind::Invalid) + return ValueOwnershipKind::Invalid; + + // None merges with anything. + if (lhsVal == ValueOwnershipKind::None) + return ValueOwnershipKind(rhsVal); + if (rhsVal == ValueOwnershipKind::None) + return ValueOwnershipKind(lhsVal); - return (LHSVal == RHSVal) ? Optional(*this) : llvm::None; + // At this point, if the two ownership kinds don't line up, the merge fails. + if (lhsVal != rhsVal) + return ValueOwnershipKind::Invalid; + + // Otherwise, we are good, return *this. + return *this; } ValueOwnershipKind::ValueOwnershipKind(StringRef S) { diff --git a/lib/SIL/IR/ValueOwnership.cpp b/lib/SIL/IR/ValueOwnership.cpp index 7ecc8ad741793..3d9ac9354c7c6 100644 --- a/lib/SIL/IR/ValueOwnership.cpp +++ b/lib/SIL/IR/ValueOwnership.cpp @@ -225,7 +225,7 @@ ValueOwnershipKindClassifier::visitForwardingInst(SILInstruction *i, return op.get().getOwnershipKind(); })); - if (!mergedValue.hasValue()) { + if (!mergedValue) { // If we have mismatched SILOwnership and sil ownership is not enabled, // just return None for staging purposes. If SILOwnership is enabled, then // we must assert! @@ -235,7 +235,7 @@ ValueOwnershipKindClassifier::visitForwardingInst(SILInstruction *i, llvm_unreachable("Forwarding inst with mismatching ownership kinds?!"); } - return mergedValue.getValue(); + return mergedValue; } #define FORWARDING_OWNERSHIP_INST(INST) \ @@ -341,7 +341,7 @@ ValueOwnershipKind ValueOwnershipKindClassifier::visitApplyInst(ApplyInst *ai) { llvm_unreachable("Forwarding inst with mismatching ownership kinds?!"); } - return *mergedOwnershipKind; + return mergedOwnershipKind; } ValueOwnershipKind ValueOwnershipKindClassifier::visitLoadInst(LoadInst *LI) { diff --git a/lib/SIL/Utils/MemAccessUtils.cpp b/lib/SIL/Utils/MemAccessUtils.cpp index b2023fa88ccf6..f335a1f03bb46 100644 --- a/lib/SIL/Utils/MemAccessUtils.cpp +++ b/lib/SIL/Utils/MemAccessUtils.cpp @@ -927,6 +927,7 @@ class AccessPathVisitor : public FindAccessVisitorImpl { // Ignore everything in getAccessProjectionOperand that is an access // projection with no affect on the access path. assert(isa(projectedAddr) + || isa(projectedAddr) || isa(projectedAddr) || isa(projectedAddr)); } @@ -1390,6 +1391,10 @@ AccessPathDefUseTraversal::visitSingleValueUser(SingleValueInstruction *svi, return IgnoredUse; } + case SILInstructionKind::InitEnumDataAddrInst: + pushUsers(svi, dfs); + return IgnoredUse; + // open_existential_addr and unchecked_take_enum_data_addr are classified as // access projections, but they also modify memory. Both see through them and // also report them as uses. diff --git a/lib/SIL/Verifier/SILOwnershipVerifier.cpp b/lib/SIL/Verifier/SILOwnershipVerifier.cpp index 691b60936c3b5..7f10e9f90d163 100644 --- a/lib/SIL/Verifier/SILOwnershipVerifier.cpp +++ b/lib/SIL/Verifier/SILOwnershipVerifier.cpp @@ -487,6 +487,8 @@ bool SILValueOwnershipChecker::gatherUsers( bool SILValueOwnershipChecker::checkFunctionArgWithoutLifetimeEndingUses( SILFunctionArgument *arg) { switch (arg->getOwnershipKind()) { + case ValueOwnershipKind::Invalid: + llvm_unreachable("Invalid ownership kind used?!"); case ValueOwnershipKind::Guaranteed: case ValueOwnershipKind::Unowned: case ValueOwnershipKind::None: @@ -507,6 +509,8 @@ bool SILValueOwnershipChecker::checkFunctionArgWithoutLifetimeEndingUses( bool SILValueOwnershipChecker::checkYieldWithoutLifetimeEndingUses( BeginApplyResult *yield, ArrayRef regularUses) { switch (yield->getOwnershipKind()) { + case ValueOwnershipKind::Invalid: + llvm_unreachable("Invalid ownership kind used?!"); case ValueOwnershipKind::Unowned: case ValueOwnershipKind::None: return true; diff --git a/lib/SILGen/RValue.cpp b/lib/SILGen/RValue.cpp index 9eaf85abb2df3..f54a18c28c35e 100644 --- a/lib/SILGen/RValue.cpp +++ b/lib/SILGen/RValue.cpp @@ -388,7 +388,7 @@ static void verifyHelper(ArrayRef values, NullablePtr SGF = nullptr) { // This is a no-op in non-assert builds. #ifndef NDEBUG - auto result = Optional(ValueOwnershipKind::None); + ValueOwnershipKind result = ValueOwnershipKind::None; Optional sameHaveCleanups; for (ManagedValue v : values) { assert((!SGF || !v.getType().isLoadable(SGF.get()->F) || @@ -408,8 +408,8 @@ static void verifyHelper(ArrayRef values, // This variable is here so that if the assert below fires, the current // reduction value is still available. - auto newResult = result.getValue().merge(kind); - assert(newResult.hasValue()); + auto newResult = result.merge(kind); + assert(newResult); result = newResult; } #endif diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index f3f64c4ba368c..4e8026702280d 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -1964,6 +1964,11 @@ ASTLoweringRequest::evaluate(Evaluator &evaluator, if (desc.opts.SkipFunctionBodies == FunctionBodySkipping::All) return silMod; + // Skip emitting SIL if there's been any compilation errors + if (silMod->getASTContext().hadError() && + silMod->getASTContext().LangOpts.AllowModuleWithCompilerErrors) + return silMod; + SILGenModuleRAII scope(*silMod); // Emit a specific set of SILDeclRefs if needed. diff --git a/lib/SILOptimizer/Differentiation/Thunk.cpp b/lib/SILOptimizer/Differentiation/Thunk.cpp index cf9928673fdbb..65cb11bb409cd 100644 --- a/lib/SILOptimizer/Differentiation/Thunk.cpp +++ b/lib/SILOptimizer/Differentiation/Thunk.cpp @@ -496,6 +496,8 @@ SILFunction *getOrCreateReabstractionThunk(SILOptFunctionBuilder &fb, // Owned values need to be destroyed. for (auto arg : valuesToCleanup) { switch (arg.getOwnershipKind()) { + case ValueOwnershipKind::Invalid: + llvm_unreachable("Invalid ownership kind?!"); case ValueOwnershipKind::Guaranteed: builder.emitEndBorrowOperation(loc, arg); break; diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index 55b4df58a2fa6..fb03c6b85da8a 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -222,6 +222,17 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC, SourceLoc loc) { unavailablePlatformKind); } +ExportContext ExportContext::forConformance(DeclContext *DC, + ProtocolDecl *proto) { + assert(isa(DC) || isa(DC)); + auto where = forDeclSignature(DC->getInnermostDeclarationDeclContext()); + + where.Exported &= proto->getFormalAccessScope( + DC, /*usableFromInlineAsPublic*/true).isPublic(); + + return where; +} + ExportContext ExportContext::withReason(ExportabilityReason reason) const { auto copy = *this; copy.Reason = unsigned(reason); @@ -1226,7 +1237,8 @@ static const Decl *ancestorMemberLevelDeclForAvailabilityFixit(const Decl *D) { while (D) { D = relatedDeclForAvailabilityFixit(D); - if (D->getDeclContext()->isTypeContext() && + if (!D->isImplicit() && + D->getDeclContext()->isTypeContext() && DeclAttribute::canAttributeAppearOnDecl(DeclAttrKind::DAK_Available, D)) { break; @@ -2172,20 +2184,19 @@ void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange, } } -void TypeChecker::diagnoseIfDeprecated( - SourceLoc loc, - const RootProtocolConformance *rootConf, - const ExtensionDecl *ext, - const ExportContext &where) { +bool TypeChecker::diagnoseIfDeprecated(SourceLoc loc, + const RootProtocolConformance *rootConf, + const ExtensionDecl *ext, + const ExportContext &where) { const AvailableAttr *attr = TypeChecker::getDeprecated(ext); if (!attr) - return; + return false; // We match the behavior of clang to not report deprecation warnings // inside declarations that are themselves deprecated on all deployment // targets. if (where.isDeprecated()) { - return; + return false; } auto *dc = where.getDeclContext(); @@ -2196,7 +2207,7 @@ void TypeChecker::diagnoseIfDeprecated( // Suppress a deprecation warning if the availability checking machinery // thinks the reference program location will not execute on any // deployment target for the current platform. - return; + return false; } } @@ -2215,7 +2226,7 @@ void TypeChecker::diagnoseIfDeprecated( attr->Deprecated.hasValue(), deprecatedVersion, /*message*/ StringRef()) .highlight(attr->getRange()); - return; + return true; } EncodedDiagnosticMessage encodedMessage(attr->Message); @@ -2225,6 +2236,7 @@ void TypeChecker::diagnoseIfDeprecated( attr->Deprecated.hasValue(), deprecatedVersion, encodedMessage.Message) .highlight(attr->getRange()); + return true; } void swift::diagnoseUnavailableOverride(ValueDecl *override, @@ -3374,7 +3386,8 @@ void swift::diagnoseTypeAvailability(const TypeRepr *TR, Type T, SourceLoc loc, bool swift::diagnoseConformanceAvailability(SourceLoc loc, ProtocolConformanceRef conformance, - const ExportContext &where) { + const ExportContext &where, + Type depTy, Type replacementTy) { assert(!where.isImplicit()); if (!conformance.isConcrete()) @@ -3385,15 +3398,30 @@ swift::diagnoseConformanceAvailability(SourceLoc loc, auto *DC = where.getDeclContext(); + auto maybeEmitAssociatedTypeNote = [&]() { + if (!depTy && !replacementTy) + return; + + Type selfTy = rootConf->getProtocol()->getProtocolSelfType(); + if (!depTy->isEqual(selfTy)) { + auto &ctx = DC->getASTContext(); + ctx.Diags.diagnose( + loc, + diag::assoc_conformance_from_implementation_only_module, + depTy, replacementTy->getCanonicalType()); + } + }; + if (auto *ext = dyn_cast(rootConf->getDeclContext())) { - if (TypeChecker::diagnoseConformanceExportability(loc, rootConf, ext, where)) + if (TypeChecker::diagnoseConformanceExportability(loc, rootConf, ext, where)) { + maybeEmitAssociatedTypeNote(); return true; + } - if (diagnoseExplicitUnavailability(loc, rootConf, ext, where)) + if (diagnoseExplicitUnavailability(loc, rootConf, ext, where)) { + maybeEmitAssociatedTypeNote(); return true; - - // Diagnose for deprecation - TypeChecker::diagnoseIfDeprecated(loc, rootConf, ext, where); + } // Diagnose (and possibly signal) for potential unavailability auto maybeUnavail = TypeChecker::checkConformanceAvailability( @@ -3401,13 +3429,24 @@ swift::diagnoseConformanceAvailability(SourceLoc loc, if (maybeUnavail.hasValue()) { TypeChecker::diagnosePotentialUnavailability(rootConf, ext, loc, DC, maybeUnavail.getValue()); + maybeEmitAssociatedTypeNote(); + return true; + } + + // Diagnose for deprecation + if (TypeChecker::diagnoseIfDeprecated(loc, rootConf, ext, where)) { + maybeEmitAssociatedTypeNote(); + + // Deprecation is just a warning, so keep going with checking the + // substitution map below. } } // Now, check associated conformances. SubstitutionMap subConformanceSubs = concreteConf->getSubstitutions(DC->getParentModule()); - if (diagnoseSubstitutionMapAvailability(loc, subConformanceSubs, where)) + if (diagnoseSubstitutionMapAvailability(loc, subConformanceSubs, where, + depTy, replacementTy)) return true; return false; @@ -3416,10 +3455,12 @@ swift::diagnoseConformanceAvailability(SourceLoc loc, bool swift::diagnoseSubstitutionMapAvailability(SourceLoc loc, SubstitutionMap subs, - const ExportContext &where) { + const ExportContext &where, + Type depTy, Type replacementTy) { bool hadAnyIssues = false; for (ProtocolConformanceRef conformance : subs.getConformances()) { - if (diagnoseConformanceAvailability(loc, conformance, where)) + if (diagnoseConformanceAvailability(loc, conformance, where, + depTy, replacementTy)) hadAnyIssues = true; } return hadAnyIssues; diff --git a/lib/Sema/TypeCheckAvailability.h b/lib/Sema/TypeCheckAvailability.h index 2c4816afd5af8..70b75b531e638 100644 --- a/lib/Sema/TypeCheckAvailability.h +++ b/lib/Sema/TypeCheckAvailability.h @@ -129,6 +129,11 @@ class ExportContext { /// it can reference anything. static ExportContext forFunctionBody(DeclContext *DC, SourceLoc loc); + /// Create an instance describing associated conformances that can be + /// referenced from the the conformance defined by the given DeclContext, + /// which must be a NominalTypeDecl or ExtensionDecl. + static ExportContext forConformance(DeclContext *DC, ProtocolDecl *proto); + /// Produce a new context with the same properties as this one, except /// changing the ExportabilityReason. This only affects diagnostics. ExportContext withReason(ExportabilityReason reason) const; @@ -212,12 +217,16 @@ void diagnoseTypeAvailability(const TypeRepr *TR, Type T, SourceLoc loc, bool diagnoseConformanceAvailability(SourceLoc loc, ProtocolConformanceRef conformance, - const ExportContext &context); + const ExportContext &context, + Type depTy=Type(), + Type replacementTy=Type()); bool diagnoseSubstitutionMapAvailability(SourceLoc loc, SubstitutionMap subs, - const ExportContext &context); + const ExportContext &context, + Type depTy=Type(), + Type replacementTy=Type()); /// Diagnose uses of unavailable declarations. Returns true if a diagnostic /// was emitted. diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp index 33893196da061..ffb541c362758 100644 --- a/lib/Sema/TypeCheckDeclObjC.cpp +++ b/lib/Sema/TypeCheckDeclObjC.cpp @@ -2402,6 +2402,7 @@ bool swift::diagnoseObjCUnsatisfiedOptReqConflicts(SourceFile &sf) { break; } } + assert(req != bestConflict && "requirement conflicts with itself?"); // Diagnose the conflict. auto reqDiagInfo = getObjCMethodDiagInfo(unsatisfied.second); diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 038a088f906ac..54298c224b68d 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -4308,56 +4308,6 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup( return ResolveWitnessResult::ExplicitFailed; } -static void checkExportability(Type depTy, Type replacementTy, - const ProtocolConformance *conformance, - NormalProtocolConformance *conformanceBeingChecked, - DeclContext *DC) { - SourceFile *SF = DC->getParentSourceFile(); - if (!SF) - return; - - SubstitutionMap subs = - conformance->getSubstitutions(SF->getParentModule()); - for (auto &subConformance : subs.getConformances()) { - if (!subConformance.isConcrete()) - continue; - checkExportability(depTy, replacementTy, subConformance.getConcrete(), - conformanceBeingChecked, DC); - } - - const RootProtocolConformance *rootConformance = - conformance->getRootConformance(); - ModuleDecl *M = rootConformance->getDeclContext()->getParentModule(); - - auto where = ExportContext::forDeclSignature( - DC->getInnermostDeclarationDeclContext()); - auto originKind = getDisallowedOriginKind( - rootConformance->getDeclContext()->getAsDecl(), - where); - if (originKind == DisallowedOriginKind::None) - return; - - ASTContext &ctx = SF->getASTContext(); - - Type selfTy = rootConformance->getProtocol()->getProtocolSelfType(); - if (depTy->isEqual(selfTy)) { - ctx.Diags.diagnose( - conformanceBeingChecked->getLoc(), - diag::conformance_from_implementation_only_module, - rootConformance->getType(), - rootConformance->getProtocol()->getName(), 0, M->getName(), - static_cast(originKind)); - } else { - ctx.Diags.diagnose( - conformanceBeingChecked->getLoc(), - diag::assoc_conformance_from_implementation_only_module, - rootConformance->getType(), - rootConformance->getProtocol()->getName(), M->getName(), - depTy, replacementTy->getCanonicalType(), - static_cast(originKind)); - } -} - void ConformanceChecker::ensureRequirementsAreSatisfied() { Conformance->finishSignatureConformances(); auto proto = Conformance->getProtocol(); @@ -4403,18 +4353,21 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() { // Now check that our associated conformances are at least as visible as // the conformance itself. - if (getRequiredAccessScope().isPublic() || isUsableFromInlineRequired()) { - for (auto req : proto->getRequirementSignature()) { - if (req.getKind() == RequirementKind::Conformance) { - auto depTy = req.getFirstType(); - auto *proto = req.getSecondType()->castTo()->getDecl(); - auto conformance = Conformance->getAssociatedConformance(depTy, proto); - if (conformance.isConcrete()) { - auto *concrete = conformance.getConcrete(); - auto replacementTy = DC->mapTypeIntoContext(concrete->getType()); - checkExportability(depTy, replacementTy, concrete, - Conformance, DC); - } + auto where = ExportContext::forConformance(DC, proto); + if (where.isImplicit()) + return; + + for (auto req : proto->getRequirementSignature()) { + if (req.getKind() == RequirementKind::Conformance) { + auto depTy = req.getFirstType(); + auto *proto = req.getSecondType()->castTo()->getDecl(); + auto conformance = Conformance->getAssociatedConformance(depTy, proto); + if (conformance.isConcrete()) { + auto *concrete = conformance.getConcrete(); + auto replacementTy = DC->mapTypeIntoContext(concrete->getType()); + diagnoseConformanceAvailability(Conformance->getLoc(), + conformance, where, + depTy, replacementTy); } } } diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 5194d610c16f2..4c60cbef1c33c 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -2308,6 +2308,8 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator, // Anything else should not have a synthesized setter. LLVM_FALLTHROUGH; case WriteImplKind::Immutable: + if (accessor->getASTContext().LangOpts.AllowModuleWithCompilerErrors) + return false; llvm_unreachable("should not be synthesizing accessor in this case"); case WriteImplKind::StoredWithObservers: diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp index 9d6f9b02d6753..d8806c5b8e4e2 100644 --- a/lib/Sema/TypeChecker.cpp +++ b/lib/Sema/TypeChecker.cpp @@ -344,9 +344,19 @@ void swift::performWholeModuleTypeChecking(SourceFile &SF) { auto &Ctx = SF.getASTContext(); FrontendStatsTracer tracer(Ctx.Stats, "perform-whole-module-type-checking"); - diagnoseObjCMethodConflicts(SF); - diagnoseObjCUnsatisfiedOptReqConflicts(SF); - diagnoseUnintendedObjCMethodOverrides(SF); + switch (SF.Kind) { + case SourceFileKind::Library: + case SourceFileKind::Main: + diagnoseObjCMethodConflicts(SF); + diagnoseObjCUnsatisfiedOptReqConflicts(SF); + diagnoseUnintendedObjCMethodOverrides(SF); + return; + case SourceFileKind::SIL: + case SourceFileKind::Interface: + // SIL modules and .swiftinterface files don't benefit from whole-module + // ObjC checking - skip it. + return; + } } bool swift::isAdditiveArithmeticConformanceDerivationEnabled(SourceFile &SF) { diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index 4b97eab57135a..a497589d200f9 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -1066,10 +1066,10 @@ void diagnoseIfDeprecated(SourceRange SourceRange, const ApplyExpr *Call); /// Emits a diagnostic for a reference to a conformnace that is deprecated. -void diagnoseIfDeprecated(SourceLoc Loc, - const RootProtocolConformance *DeprecatedConf, - const ExtensionDecl *Ext, - const ExportContext &Where); +bool diagnoseIfDeprecated(SourceLoc loc, + const RootProtocolConformance *rootConf, + const ExtensionDecl *ext, + const ExportContext &where); /// @} /// If LangOptions::DebugForbidTypecheckPrefix is set and the given decl diff --git a/lib/Serialization/DeclTypeRecordNodes.def b/lib/Serialization/DeclTypeRecordNodes.def index 2ab062799f926..5c62b8c50e27a 100644 --- a/lib/Serialization/DeclTypeRecordNodes.def +++ b/lib/Serialization/DeclTypeRecordNodes.def @@ -109,6 +109,8 @@ TYPE(SIL_BLOCK_STORAGE) TYPE(SIL_BOX) TYPE(NAME_ALIAS) +TYPE(ERROR) + FIRST_DECL(TYPE_ALIAS, 60) DECL(GENERIC_TYPE_PARAM) DECL(ASSOCIATED_TYPE) diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index e9a2b2d030b14..c3d439dbeeda7 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -2955,7 +2955,7 @@ class DeclDeserializer { declOrOffset = param; auto paramTy = MF.getType(interfaceTypeID); - if (paramTy->hasError()) { + if (paramTy->hasError() && !MF.isAllowModuleWithCompilerErrorsEnabled()) { // FIXME: This should never happen, because we don't serialize // error types. DC->printContext(llvm::errs()); @@ -5670,6 +5670,23 @@ class TypeDeserializer { return UnboundGenericType::get(genericDecl, parentTy, ctx); } + + Expected deserializeErrorType(ArrayRef scratch, + StringRef blobData) { + if (!MF.isAllowModuleWithCompilerErrorsEnabled()) + MF.fatal(); + + TypeID origID; + decls_block::ErrorTypeLayout::readRecord(scratch, origID); + + auto origTy = MF.getTypeChecked(origID); + if (!origTy) + return origTy.takeError(); + + if (!origTy.get()) + return ErrorType::get(ctx); + return ErrorType::get(origTy.get()); + } }; } @@ -5693,7 +5710,8 @@ Expected ModuleFile::getTypeChecked(TypeID TID) { #ifndef NDEBUG PrettyStackTraceType trace(getContext(), "deserializing", typeOrOffset.get()); - if (typeOrOffset.get()->hasError()) { + if (typeOrOffset.get()->hasError() && + !isAllowModuleWithCompilerErrorsEnabled()) { typeOrOffset.get()->dump(llvm::errs()); llvm_unreachable("deserialization produced an invalid type " "(rdar://problem/30382791)"); @@ -5753,6 +5771,7 @@ Expected TypeDeserializer::getTypeCheckedImpl() { CASE(Dictionary) CASE(Optional) CASE(UnboundGeneric) + CASE(Error) #undef CASE diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h index 3a5b3d5a0a5bd..198b569939d08 100644 --- a/lib/Serialization/ModuleFile.h +++ b/lib/Serialization/ModuleFile.h @@ -465,6 +465,12 @@ class ModuleFile return Core->Bits.IsImplicitDynamicEnabled; } + /// Whether this module is compiled while allowing errors + /// ('-experimental-allow-module-with-compiler-errors'). + bool isAllowModuleWithCompilerErrorsEnabled() const { + return Core->Bits.IsAllowModuleWithCompilerErrorsEnabled; + } + /// \c true if this module has incremental dependency information. bool hasIncrementalInfo() const { return Core->hasIncrementalInfo(); } diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index 2d7c4c5f249d4..ef26ebb1aa61c 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -145,6 +145,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor, options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy); extendedInfo.setResilienceStrategy(ResilienceStrategy(Strategy)); break; + case options_block::IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED: + extendedInfo.setAllowModuleWithCompilerErrorsEnabled(true); + break; default: // Unknown options record, possibly for use by a future version of the // module format. @@ -1150,6 +1153,8 @@ ModuleFileSharedCore::ModuleFileSharedCore( Bits.IsTestable = extInfo.isTestable(); Bits.ResilienceStrategy = unsigned(extInfo.getResilienceStrategy()); Bits.IsImplicitDynamicEnabled = extInfo.isImplicitDynamicEnabled(); + Bits.IsAllowModuleWithCompilerErrorsEnabled = + extInfo.isAllowModuleWithCompilerErrorsEnabled(); MiscVersion = info.miscVersion; hasValidControlBlock = true; diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h index 0bdceb68303f9..1ed9a62fdbe9e 100644 --- a/lib/Serialization/ModuleFileSharedCore.h +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -320,8 +320,11 @@ class ModuleFileSharedCore { /// Whether this module is compiled with implicit dynamic. unsigned IsImplicitDynamicEnabled: 1; + /// Whether this module is compiled while allowing errors. + unsigned IsAllowModuleWithCompilerErrorsEnabled: 1; + // Explicitly pad out to the next word boundary. - unsigned : 0; + unsigned : 3; } Bits = {}; static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small"); diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 453e59b2e7198..6ee683be9d458 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 585; // hop_to_executor instruction +const uint16_t SWIFTMODULE_VERSION_MINOR = 586; // allow errors in modules /// A standard hash seed used for all string hashes in a serialized module. /// @@ -787,7 +787,8 @@ namespace options_block { IS_TESTABLE, RESILIENCE_STRATEGY, ARE_PRIVATE_IMPORTS_ENABLED, - IS_IMPLICIT_DYNAMIC_ENABLED + IS_IMPLICIT_DYNAMIC_ENABLED, + IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED }; using SDKPathLayout = BCRecordLayout< @@ -821,6 +822,10 @@ namespace options_block { RESILIENCE_STRATEGY, BCFixed<2> >; + + using IsAllowModuleWithCompilerErrorsEnabledLayout = BCRecordLayout< + IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED + >; } /// The record types within the input block. @@ -919,6 +924,12 @@ namespace decls_block { BCArray> >; + /// A placeholder for invalid types + using ErrorTypeLayout = BCRecordLayout< + ERROR_TYPE, + TypeIDField // original type (if any) + >; + using BuiltinAliasTypeLayout = BCRecordLayout< BUILTIN_ALIAS_TYPE, DeclIDField, // typealias decl diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index a554e7f3ab290..6bf9e4d6c3d9d 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -588,7 +588,8 @@ DeclID Serializer::addDeclRef(const Decl *D, bool allowTypeAliasXRef) { serialization::TypeID Serializer::addTypeRef(Type ty) { #ifndef NDEBUG PrettyStackTraceType trace(M->getASTContext(), "serializing", ty); - assert((!ty || !ty->hasError()) && "Serializing error type"); + assert(M->getASTContext().LangOpts.AllowModuleWithCompilerErrors || + !ty || !ty->hasError() && "serializing type with an error"); #endif return TypesToSerialize.addRef(ty); @@ -755,6 +756,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(options_block, IS_TESTABLE); BLOCK_RECORD(options_block, ARE_PRIVATE_IMPORTS_ENABLED); BLOCK_RECORD(options_block, RESILIENCE_STRATEGY); + BLOCK_RECORD(options_block, IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED); BLOCK(INPUT_BLOCK); BLOCK_RECORD(input_block, IMPORTED_MODULE); @@ -934,6 +936,12 @@ void Serializer::writeHeader(const SerializationOptions &options) { Strategy.emit(ScratchRecord, unsigned(M->getResilienceStrategy())); } + if (getASTContext().LangOpts.AllowModuleWithCompilerErrors) { + options_block::IsAllowModuleWithCompilerErrorsEnabledLayout + AllowErrors(Out); + AllowErrors.emit(ScratchRecord); + } + if (options.SerializeOptionsForDebugging) { options_block::SDKPathLayout SDKPath(Out); options_block::XCCLayout XCC(Out); @@ -2712,6 +2720,12 @@ class Serializer::DeclSerializer : public DeclVisitor { // Retrieve the type of the pattern. auto getPatternType = [&] { + if (!pattern->hasType()) { + if (S.getASTContext().LangOpts.AllowModuleWithCompilerErrors) + return ErrorType::get(S.getASTContext()); + llvm_unreachable("all nodes should have types"); + } + Type type = pattern->getType(); // If we have a contextual type, map out to an interface type. @@ -3438,7 +3452,8 @@ class Serializer::DeclSerializer : public DeclVisitor { getRawStableDefaultArgumentKind(argKind), defaultArgumentText); - if (interfaceType->hasError()) { + if (interfaceType->hasError() && + !S.getASTContext().LangOpts.AllowModuleWithCompilerErrors) { param->getDeclContext()->printContext(llvm::errs()); interfaceType->dump(llvm::errs()); llvm_unreachable("error in interface type of parameter"); @@ -3797,7 +3812,8 @@ void Serializer::writeASTBlockEntity(const Decl *D) { } }; - assert(!D->isInvalid() && "cannot create a module with an invalid decl"); + assert(getASTContext().LangOpts.AllowModuleWithCompilerErrors || + !D->isInvalid() && "cannot create a module with an invalid decl"); if (isDeclXRef(D)) { writeCrossReference(D); return; @@ -3968,16 +3984,23 @@ class Serializer::TypeSerializer : public TypeVisitor { /// If this gets referenced, we forgot to handle a type. void visitType(const TypeBase *) = delete; - void visitErrorType(const ErrorType *) { - llvm_unreachable("should not serialize an invalid type"); + void visitErrorType(const ErrorType *ty) { + if (S.getASTContext().LangOpts.AllowModuleWithCompilerErrors) { + using namespace decls_block; + unsigned abbrCode = S.DeclTypeAbbrCodes[ErrorTypeLayout::Code]; + ErrorTypeLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, + S.addTypeRef(ty->getOriginalType())); + return; + } + llvm_unreachable("should not serialize an ErrorType"); } void visitUnresolvedType(const UnresolvedType *) { - llvm_unreachable("should not serialize an invalid type"); + llvm_unreachable("should not serialize an UnresolvedType"); } void visitHoleType(const HoleType *) { - llvm_unreachable("should not serialize an invalid type"); + llvm_unreachable("should not serialize a HoleType"); } void visitModuleType(const ModuleType *) { @@ -4520,6 +4543,7 @@ void Serializer::writeAllDeclsAndTypes() { registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); + registerDeclTypeAbbr(); registerDeclTypeAbbr(); diff --git a/lib/SymbolGraphGen/AvailabilityMixin.cpp b/lib/SymbolGraphGen/AvailabilityMixin.cpp index 4dc66f0b9ed62..ba0789b29fedc 100644 --- a/lib/SymbolGraphGen/AvailabilityMixin.cpp +++ b/lib/SymbolGraphGen/AvailabilityMixin.cpp @@ -58,6 +58,8 @@ StringRef getDomain(const AvailableAttr &AvAttr) { return { "watchOSAppExtension" }; case swift::PlatformKind::OpenBSD: return { "OpenBSD" }; + case swift::PlatformKind::Windows: + return { "Windows" }; case swift::PlatformKind::none: return { "*" }; } diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp index 76f84c9d51cae..fcbc6e270e036 100644 --- a/lib/TBDGen/TBDGen.cpp +++ b/lib/TBDGen/TBDGen.cpp @@ -251,6 +251,8 @@ getLinkerPlatformId(OriginallyDefinedInAttr::ActiveVersion Ver) { llvm_unreachable("cannot find platform kind"); case swift::PlatformKind::OpenBSD: llvm_unreachable("not used for this platform"); + case swift::PlatformKind::Windows: + llvm_unreachable("not used for this platform"); case swift::PlatformKind::iOS: case swift::PlatformKind::iOSApplicationExtension: return Ver.IsSimulator ? LinkerPlatformId::iOS_sim: diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp index b505c2bc76c59..8c827367db0fa 100644 --- a/stdlib/public/runtime/Metadata.cpp +++ b/stdlib/public/runtime/Metadata.cpp @@ -2721,7 +2721,12 @@ static void initClassFieldOffsetVector(ClassMetadata *self, // situations where our entire superclass hierarchy is defined // in Swift. (But note that ObjC might think we have a superclass // even if Swift doesn't, because of SwiftObject.) - rodata->InstanceStart = size; + // + // The rodata may be in read-only memory if the compiler knows that the size + // it generates is already definitely correct. Don't write to this value + // unless it's necessary. + if (rodata->InstanceStart != size) + rodata->InstanceStart = size; #endif // Okay, now do layout. @@ -2745,7 +2750,8 @@ static void initClassFieldOffsetVector(ClassMetadata *self, #if SWIFT_OBJC_INTEROP // Save the size into the Objective-C metadata as well. - rodata->InstanceSize = size; + if (rodata->InstanceSize != size) + rodata->InstanceSize = size; #endif } diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/CoreFeatures b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/CoreFeatures new file mode 120000 index 0000000000000..085f649ae9452 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/CoreFeatures @@ -0,0 +1 @@ +Versions/Current/CoreFeatures \ No newline at end of file diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Headers b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Headers new file mode 120000 index 0000000000000..a177d2a6b9260 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Modules b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Modules new file mode 120000 index 0000000000000..5736f3186e797 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/CoreFeatures b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/CoreFeatures new file mode 100755 index 0000000000000..c417011291284 Binary files /dev/null and b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/CoreFeatures differ diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/CoreFeatures-Swift.h b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/CoreFeatures-Swift.h new file mode 100644 index 0000000000000..9c19c04a68a59 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/CoreFeatures-Swift.h @@ -0,0 +1,442 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1) +#ifndef COREFEATURES_SWIFT_H +#define COREFEATURES_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#include +#include +#include +#include + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif + +#if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +#else +# define SWIFT_RUNTIME_NAME(X) +#endif +#if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +#else +# define SWIFT_COMPILE_NAME(X) +#endif +#if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +#else +# define SWIFT_METHOD_FAMILY(X) +#endif +#if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +#else +# define SWIFT_NOESCAPE +#endif +#if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +#else +# define SWIFT_RELEASES_ARGUMENT +#endif +#if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define SWIFT_WARN_UNUSED_RESULT +#endif +#if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +#else +# define SWIFT_NORETURN +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif + +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif + +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif + +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if defined(__has_attribute) && __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +#else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +#endif +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#if __has_feature(modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#import + +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="CoreFeatures",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + + +@interface RootObject (SWIFT_EXTENSION(CoreFeatures)) +@end + +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#pragma clang diagnostic pop +#endif + +#elif defined(__x86_64__) && __x86_64__ +// Generated by Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1) +#ifndef COREFEATURES_SWIFT_H +#define COREFEATURES_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#include +#include +#include +#include + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif + +#if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +#else +# define SWIFT_RUNTIME_NAME(X) +#endif +#if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +#else +# define SWIFT_COMPILE_NAME(X) +#endif +#if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +#else +# define SWIFT_METHOD_FAMILY(X) +#endif +#if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +#else +# define SWIFT_NOESCAPE +#endif +#if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +#else +# define SWIFT_RELEASES_ARGUMENT +#endif +#if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define SWIFT_WARN_UNUSED_RESULT +#endif +#if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +#else +# define SWIFT_NORETURN +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif + +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif + +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif + +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if defined(__has_attribute) && __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +#else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +#endif +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#if __has_feature(modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#import + +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="CoreFeatures",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + + +@interface RootObject (SWIFT_EXTENSION(CoreFeatures)) +@end + +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#pragma clang diagnostic pop +#endif + +#endif diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/CoreFeatures.h b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/CoreFeatures.h new file mode 100644 index 0000000000000..e160d0014e86a --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/CoreFeatures.h @@ -0,0 +1 @@ +#import diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/RootObject.h b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/RootObject.h new file mode 100644 index 0000000000000..46b978afdfed8 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Headers/RootObject.h @@ -0,0 +1,14 @@ +__attribute__((objc_root_class)) +@interface RootObject +- (instancetype) init; +@end + +@protocol RootProtocol +@optional +- (void) rootObject:(RootObject *)root willChangeValue:(void *)value; +- (void) rootObject:(RootObject *)root didChangeValue:(void *)value; +@end + +@protocol ReactiveRootProtocol +@end + diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64-apple-macos.swiftdoc b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64-apple-macos.swiftdoc new file mode 100644 index 0000000000000..b811c5d392a16 Binary files /dev/null and b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64-apple-macos.swiftdoc differ diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64-apple-macos.swiftinterface b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64-apple-macos.swiftinterface new file mode 100644 index 0000000000000..3a003f37a7081 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64-apple-macos.swiftinterface @@ -0,0 +1,8 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1) +// swift-module-flags: -target arm64-apple-macos11.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name CoreFeatures +@_exported import CoreFeatures +import Foundation +import Swift +extension RootObject : CoreFeatures.ReactiveRootProtocol { +} diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64.swiftdoc b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64.swiftdoc new file mode 100644 index 0000000000000..b811c5d392a16 Binary files /dev/null and b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64.swiftdoc differ diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64.swiftinterface b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64.swiftinterface new file mode 100644 index 0000000000000..3a003f37a7081 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/arm64.swiftinterface @@ -0,0 +1,8 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1) +// swift-module-flags: -target arm64-apple-macos11.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name CoreFeatures +@_exported import CoreFeatures +import Foundation +import Swift +extension RootObject : CoreFeatures.ReactiveRootProtocol { +} diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64-apple-macos.swiftdoc b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64-apple-macos.swiftdoc new file mode 100644 index 0000000000000..b7497fe39ff76 Binary files /dev/null and b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64-apple-macos.swiftdoc differ diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64-apple-macos.swiftinterface b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64-apple-macos.swiftinterface new file mode 100644 index 0000000000000..827d360b9df23 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64-apple-macos.swiftinterface @@ -0,0 +1,8 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1) +// swift-module-flags: -target x86_64-apple-macos11.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name CoreFeatures +@_exported import CoreFeatures +import Foundation +import Swift +extension RootObject : CoreFeatures.ReactiveRootProtocol { +} diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64.swiftdoc b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64.swiftdoc new file mode 100644 index 0000000000000..b7497fe39ff76 Binary files /dev/null and b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64.swiftdoc differ diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64.swiftinterface b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64.swiftinterface new file mode 100644 index 0000000000000..827d360b9df23 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/CoreFeatures.swiftmodule/x86_64.swiftinterface @@ -0,0 +1,8 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1) +// swift-module-flags: -target x86_64-apple-macos11.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name CoreFeatures +@_exported import CoreFeatures +import Foundation +import Swift +extension RootObject : CoreFeatures.ReactiveRootProtocol { +} diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/module.modulemap b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000000000..f7cd21a55f09d --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,11 @@ +framework module CoreFeatures { + umbrella header "CoreFeatures.h" + + export * + module * { export * } +} + +module CoreFeatures.Swift { + header "CoreFeatures-Swift.h" + requires objc +} diff --git a/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/Current b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/Current new file mode 120000 index 0000000000000..8c7e5a667f1b7 --- /dev/null +++ b/test/ClangImporter/Inputs/requirement-conflict/CoreFeatures.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/test/ClangImporter/requirement-conflict.swift b/test/ClangImporter/requirement-conflict.swift new file mode 100644 index 0000000000000..39e9a52e6db1c --- /dev/null +++ b/test/ClangImporter/requirement-conflict.swift @@ -0,0 +1,28 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: %target-swift-frontend -typecheck -F %S/Inputs/requirement-conflict -module-cache-path %t/clang-module-cache %s + +// REQUIRES: objc_interop +// N.B. technically only need objc_interop here, but CoreFeatures would have to +// be cross-compiled for more architectures. It's sufficient to verify this +// works for macOS alone since we only care that we don't emit errors. +// REQUIRES: OS=macosx + +import CoreFeatures + +// The RootObject class in CoreFeatures is intentionally quite strange. +// Formally, RootObject declares a conformance to an Objective-C protocol called +// 'ReactiveRootProtocol', but in Swift instead of ObjC. When we go to import +// the ObjC side of the framework, we notice this and mirror-in the requirements +// from its ancestor 'RootProtocol'. With that accomplished, we now have an ObjC +// class imported through Swift with ObjC members mirrored on top. This combo +// used to be toxic - we would see the very members we synthesized during the +// shadowing pass and would diagnose them as directly conflicting with the +// protocol conformance we had declared in Swift. That is - we would say +// a requirement conflicted directly... with itself! +// +// Nowadays we just exempt interface files from this kind of checking, which is +// the same behavior one would get if they had set up this very scenario with +// a plain swiftmodule file. +let root = CoreFeatures.RootObject() +print(root) diff --git a/test/Frontend/allow-errors.swift b/test/Frontend/allow-errors.swift new file mode 100644 index 0000000000000..533fe2bb90fe8 --- /dev/null +++ b/test/Frontend/allow-errors.swift @@ -0,0 +1,14 @@ +// RUN: %empty-directory(%t) + +// The module should be generated regardless of errors and diagnostic should still be output +// RUN: %target-swift-frontend -verify -emit-module -o %t/errors.swiftmodule -experimental-allow-module-with-compiler-errors %s +// RUN: llvm-bcanalyzer %t/errors.swiftmodule | %FileCheck -check-prefix=CHECK-BC %s +// CHECK-BC-NOT: UnknownCode + +struct InvalidStruct { + let memberMissingType: undefined // expected-error {{cannot find type 'undefined'}} +} + +func invalidFunc() -> InvalidStruct { + ret // expected-error {{cannot find 'ret'}} +} diff --git a/test/Frontend/crash-in-user-code.swift b/test/Frontend/crash-in-user-code.swift index 4a36a0c3b5a4c..5372941b605d0 100644 --- a/test/Frontend/crash-in-user-code.swift +++ b/test/Frontend/crash-in-user-code.swift @@ -7,6 +7,7 @@ // UNSUPPORTED: OS=ios // UNSUPPORTED: OS=tvos // UNSUPPORTED: OS=watchos +// UNSUPPORTED: MSVC_VER=15.0 // CHECK: Stack dump: // CHECK-NEXT: Program arguments: diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift index c3e1f228d1262..b5125597727c9 100644 --- a/test/IDE/complete_decl_attribute.swift +++ b/test/IDE/complete_decl_attribute.swift @@ -40,6 +40,7 @@ struct MyStruct {} // AVAILABILITY1-NEXT: Keyword/None: macCatalyst[#Platform#]; name=macCatalyst // AVAILABILITY1-NEXT: Keyword/None: macCatalystApplicationExtension[#Platform#]; name=macCatalystApplicationExtension // AVAILABILITY1-NEXT: Keyword/None: OpenBSD[#Platform#]; name=OpenBSD{{$}} +// AVAILABILITY1-NEXT: Keyword/None: Windows[#Platform#]; name=Windows{{$}} // AVAILABILITY1-NEXT: End completions @available(*, #^AVAILABILITY2^#) diff --git a/test/Parse/diagnose_availability_windows.swift b/test/Parse/diagnose_availability_windows.swift new file mode 100644 index 0000000000000..1ca049fe71cf1 --- /dev/null +++ b/test/Parse/diagnose_availability_windows.swift @@ -0,0 +1,28 @@ +// RUN: %target-typecheck-verify-swift +// REQUIRES: OS=windows-msvc + +// expected-note@+2{{'unavailable()' has been explicitly marked unavailable here}} +@available(Windows, unavailable, message: "unsupported") +func unavailable() {} + +// expected-error@+1 {{'unavailable()' is unavailable in Windows: unsupported}} +unavailable() + +@available(Windows, introduced: 10.0.17763, deprecated: 10.0.19140) +func introduced_deprecated() {} + +// expected-error@+1 {{'introduced_deprecated()' is only available in * 10.0.17763 or newe}} +introduced_deprecated() +// expected-note@-1 {{add 'if #available' version check}} + +@available(Windows 10, *) +func windows10() {} + +// expected-error@+1 {{'windows10()' is only available in * 10 or newer}} +windows10() +// expected-note@-1 {{add 'if #available' version check}} + +func coniditonal_compilation() { + if #available(Windows 10, *) { + } +} diff --git a/test/SIL/ownership-verifier/undef.sil b/test/SIL/ownership-verifier/undef.sil index e31d12e0a5f87..ab3d5262da7aa 100644 --- a/test/SIL/ownership-verifier/undef.sil +++ b/test/SIL/ownership-verifier/undef.sil @@ -20,6 +20,7 @@ struct MyInt { // CHECK-NEXT: Operand Ownership Map: // CHECK-NEXT: Op #: 0 // CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap -- +// CHECK-NEXT: invalid: No. // CHECK-NEXT: unowned: No. // CHECK-NEXT: owned: Yes. Liveness: LifetimeEnding // CHECK-NEXT: guaranteed: No. @@ -28,6 +29,7 @@ struct MyInt { // CHECK-NEXT: Operand Ownership Map: // CHECK-NEXT: Op #: 0 // CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap -- +// CHECK-NEXT: invalid: No. // CHECK-NEXT: unowned: No. // CHECK-NEXT: owned: Yes. Liveness: LifetimeEnding // CHECK-NEXT: guaranteed: No. @@ -36,6 +38,7 @@ struct MyInt { // CHECK-NEXT: Operand Ownership Map: // CHECK-NEXT: Op #: 0 // CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap -- +// CHECK-NEXT: invalid: No. // CHECK-NEXT: unowned: No. // CHECK-NEXT: owned: Yes. Liveness: LifetimeEnding // CHECK-NEXT: guaranteed: No. @@ -44,6 +47,7 @@ struct MyInt { // CHECK-NEXT: Operand Ownership Map: // CHECK-NEXT: Op #: 0 // CHECK-NEXT: Ownership Map: -- OperandOwnershipKindMap -- +// CHECK-NEXT: invalid: No. // CHECK-NEXT: unowned: No. // CHECK-NEXT: owned: No. // CHECK-NEXT: guaranteed: No. diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift index 6062f4116579f..9b6e06027636d 100644 --- a/test/SILOptimizer/access_marker_verify.swift +++ b/test/SILOptimizer/access_marker_verify.swift @@ -333,8 +333,9 @@ func testInitGenericEnum(t: T) -> GenericEnum? { // CHECK: copy_addr %1 to [initialization] [[ADR1]] : $*T // CHECK: [[STK:%.*]] = alloc_stack $GenericEnum // CHECK: [[ENUMDATAADDR:%.*]] = init_enum_data_addr [[STK]] -// CHECK-NOT: begin_access -// CHECK: copy_addr [take] [[ADR1]] to [initialization] [[ENUMDATAADDR]] : $*T +// CHECK: [[ACCESSENUM:%.*]] = begin_access [modify] [unsafe] [[ENUMDATAADDR]] : $*T +// CHECK: copy_addr [take] [[ADR1]] to [initialization] [[ACCESSENUM]] : $*T +// CHECK: end_access [[ACCESSENUM]] : $*T // CHECK: inject_enum_addr // CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[PROJ]] // CHECK: copy_addr [take] %{{.*}} to [[ACCESS]] : $*GenericEnum diff --git a/test/SILOptimizer/accesspath_uses.sil b/test/SILOptimizer/accesspath_uses.sil index 82e72c6438bd6..6557725bf8a32 100644 --- a/test/SILOptimizer/accesspath_uses.sil +++ b/test/SILOptimizer/accesspath_uses.sil @@ -866,3 +866,54 @@ bb5: %999 = tuple () return %999 : $() } + +// CHECK-LABEL: @test_init_enum_addr +// CHECK: ###For MemOp: store %0 to [init] %2 : $*AnyObject +// CHECK: Stack %1 = alloc_stack $Optional +// CHECK: Path: () +// CHECK: Exact Uses { +// CHECK-NEXT: store %0 to [init] %{{.*}} : $*AnyObject +// CHECK-NEXT: Path: () +// CHECK-NEXT: inject_enum_addr %1 : $*Optional, #Optional.some!enumelt +// CHECK-NEXT: Path: () +// CHECK-NEXT: %{{.*}} = load [copy] %1 : $*Optional +// CHECK-NEXT: Path: () +// CHECK-NEXT: dealloc_stack %1 : $*Optional +// CHECK-NEXT: Path: () +// CHECK-NEXT: } +// CHECK: ###For MemOp: inject_enum_addr %1 : $*Optional, #Optional.some!enumelt +// CHECK: Stack %1 = alloc_stack $Optional +// CHECK: Path: () +// CHECK: Exact Uses { +// CHECK-NEXT: store %0 to [init] %{{.*}} : $*AnyObject +// CHECK-NEXT: Path: () +// CHECK-NEXT: inject_enum_addr %1 : $*Optional, #Optional.some!enumelt +// CHECK-NEXT: Path: () +// CHECK-NEXT: %{{.*}} = load [copy] %1 : $*Optional +// CHECK-NEXT: Path: () +// CHECK-NEXT: dealloc_stack %1 : $*Optional +// CHECK-NEXT: Path: () +// CHECK-NEXT: } +// CHECK: ###For MemOp: %5 = load [copy] %1 : $*Optional +// CHECK: Stack %1 = alloc_stack $Optional +// CHECK: Path: () +// CHECK: Exact Uses { +// CHECK-NEXT: store %0 to [init] %{{.*}} : $*AnyObject +// CHECK-NEXT: Path: () +// CHECK-NEXT: inject_enum_addr %1 : $*Optional, #Optional.some!enumelt +// CHECK-NEXT: Path: () +// CHECK-NEXT: %{{.*}} = load [copy] %1 : $*Optional +// CHECK-NEXT: Path: () +// CHECK-NEXT: dealloc_stack %1 : $*Optional +// CHECK-NEXT: Path: () +// CHECK-NEXT: } +sil [ossa] @test_init_enum_addr : $@convention(thin) (@owned AnyObject) -> @owned Optional { +bb0(%0 : @owned $AnyObject): + %1 = alloc_stack $Optional + %2 = init_enum_data_addr %1 : $*Optional, #Optional.some!enumelt + store %0 to [init] %2 : $*AnyObject + inject_enum_addr %1 : $*Optional, #Optional.some!enumelt + %5 = load [copy] %1 : $*Optional + dealloc_stack %1 : $*Optional + return %5 : $Optional +} diff --git a/test/SILOptimizer/load_borrow_verify.sil b/test/SILOptimizer/load_borrow_verify.sil index 72620cd797833..143ea1b36341a 100644 --- a/test/SILOptimizer/load_borrow_verify.sil +++ b/test/SILOptimizer/load_borrow_verify.sil @@ -58,3 +58,22 @@ bb0(%0 : $Int64): end_access %33 : $*Int64 return %35 : $Int64 } + +// CHECK-LABEL: sil [ossa] @test_borrow_init_enum_addr : $@convention(thin) (@owned AnyObject) -> () { +// CHECK: bb0(%0 : @owned $AnyObject): +// CHECK: [[ALLOC:%.*]] = alloc_stack $Optional +// CHECK: init_enum_data_addr [[ALLOC]] : $*Optional, #Optional.some!enumelt +// CHECK: load_borrow [[ALLOC]] : $*Optional +// CHECK-LABEL: } // end sil function 'test_borrow_init_enum_addr' +sil [ossa] @test_borrow_init_enum_addr : $@convention(thin) (@owned AnyObject) -> () { +bb0(%0 : @owned $AnyObject): + %1 = alloc_stack $Optional + %2 = init_enum_data_addr %1 : $*Optional, #Optional.some!enumelt + store %0 to [init] %2 : $*AnyObject + inject_enum_addr %1 : $*Optional, #Optional.some!enumelt + %5 = load_borrow %1 : $*Optional + end_borrow %5 : $Optional + dealloc_stack %1 : $*Optional + %99 = tuple () + return %99 : $() +} \ No newline at end of file diff --git a/test/SPI/protocol_requirement.swift b/test/SPI/protocol_requirement.swift index c3b952e1c8221..1b4984e8049fc 100644 --- a/test/SPI/protocol_requirement.swift +++ b/test/SPI/protocol_requirement.swift @@ -104,7 +104,8 @@ public protocol Proto { public struct BadStruct {} @_spi(Horse) extension BadStruct : OtherProto {} -public struct BadConforms : Proto { // expected-error {{cannot use conformance of 'BadStruct' to 'OtherProto' in associated type 'Self.A.Element' (inferred as 'BadStruct'); the conformance is declared as SPI}} +public struct BadConforms : Proto { // expected-error {{cannot use conformance of 'BadStruct' to 'OtherProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.A.Element' (inferred as 'BadStruct')}} public typealias A = [BadStruct] } diff --git a/test/Sema/conformance_availability.swift b/test/Sema/conformance_availability.swift index 7e8263bd725ba..61dd90e25d207 100644 --- a/test/Sema/conformance_availability.swift +++ b/test/Sema/conformance_availability.swift @@ -16,7 +16,7 @@ public struct HasUnavailableConformance1 {} @available(*, unavailable) extension HasUnavailableConformance1 : Horse {} -// expected-note@-1 6{{conformance of 'HasUnavailableConformance1' to 'Horse' has been explicitly marked unavailable here}} +// expected-note@-1 7{{conformance of 'HasUnavailableConformance1' to 'Horse' has been explicitly marked unavailable here}} func passUnavailableConformance1(x: HasUnavailableConformance1) { takesHorse(x) // expected-error {{conformance of 'HasUnavailableConformance1' to 'Horse' is unavailable}} @@ -212,4 +212,51 @@ func passAvailableConformance1a(x: HasAvailableConformance1) { takesHorse(x) x.giddyUp() _ = UsesHorse.self +} + +// Associated conformance with unavailability +protocol Rider { + associatedtype H : Horse +} + +struct AssocConformanceUnavailable : Rider { +// expected-error@-1 {{conformance of 'HasUnavailableConformance1' to 'Horse' is unavailable}} +// expected-note@-2 {{in associated type 'Self.H' (inferred as 'HasUnavailableConformance1')}} + typealias H = HasUnavailableConformance1 +} + +// Associated conformance with deprecation +struct AssocConformanceDeprecated : Rider { +// expected-warning@-1 {{conformance of 'HasDeprecatedConformance1' to 'Horse' is deprecated}} +// expected-note@-2 {{in associated type 'Self.H' (inferred as 'HasDeprecatedConformance1')}} + typealias H = HasDeprecatedConformance1 +} + +// Associated conformance with availability +struct AssocConformanceAvailable1 : Rider { +// expected-error@-1 {{conformance of 'HasAvailableConformance1' to 'Horse' is only available in macOS 100 or newer}} +// expected-note@-2 {{in associated type 'Self.H' (inferred as 'HasAvailableConformance1')}} +// expected-note@-3 {{add @available attribute to enclosing struct}} + typealias H = HasAvailableConformance1 +} + +@available(macOS 100, *) +struct AssocConformanceAvailable2 : Rider { + typealias H = HasAvailableConformance1 +} + +struct AssocConformanceAvailable3 {} + +extension AssocConformanceAvailable3 : Rider { +// expected-error@-1 {{conformance of 'HasAvailableConformance1' to 'Horse' is only available in macOS 100 or newer}} +// expected-note@-2 {{in associated type 'Self.H' (inferred as 'HasAvailableConformance1')}} +// expected-note@-3 {{add @available attribute to enclosing extension}} + typealias H = HasAvailableConformance1 +} + +struct AssocConformanceAvailable4 {} + +@available(macOS 100, *) +extension AssocConformanceAvailable4 : Rider { + typealias H = HasAvailableConformance1 } \ No newline at end of file diff --git a/test/Sema/implementation-only-import-in-decls.swift b/test/Sema/implementation-only-import-in-decls.swift index 3583696735ca8..23a46fc49c53e 100644 --- a/test/Sema/implementation-only-import-in-decls.swift +++ b/test/Sema/implementation-only-import-in-decls.swift @@ -217,15 +217,23 @@ protocol InternalAssociatedTypeProto { public struct PublicInferredAssociatedTypeImpl { public func takesAssoc(_: NormalStruct) {} } -extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} -extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} +extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + +extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + extension PublicInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay @usableFromInline struct UFIInferredAssociatedTypeImpl { public func takesAssoc(_: NormalStruct) {} } -extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} -extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} +extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + +extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + extension UFIInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay struct InternalInferredAssociatedTypeImpl { @@ -239,8 +247,12 @@ public struct PublicExplicitAssociatedTypeImpl { public typealias Assoc = NormalStruct public func takesAssoc(_: NormalStruct) {} } -extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} -extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} +extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + +extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + extension PublicExplicitAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay @@ -251,7 +263,8 @@ public protocol BaseProtoWithNoRequirement { public protocol RefinedProto: BaseProtoWithNoRequirement where Assoc: NormalProto { } -public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} +public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} public func takesAssoc(_: NormalStruct) {} } @@ -266,18 +279,26 @@ public protocol SlightlyMoreComplicatedRequirement { associatedtype Assoc: Collection where Assoc.Element: NormalProto func takesAssoc(_: Assoc) } -public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}} +public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct')}} + public func takesAssoc(_: [NormalStruct]) {} } -public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass'); 'BADLibrary' has been imported as implementation-only}} +public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass')}} + public func takesAssoc(_: [SubclassOfNormalClass]) {} } -public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct'); 'BADLibrary' has been imported as implementation-only}} +public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct')}} + public func takesAssoc(_: [ConditionalGenericStruct]) {} } -public struct ClassConstrainedGenericArg: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'T'); 'BADLibrary' has been imported as implementation-only}} +public struct ClassConstrainedGenericArg: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'T')}} + public func takesAssoc(_: T) {} } diff --git a/test/Sema/spi-in-decls.swift b/test/Sema/spi-in-decls.swift index 5a7bbd4b7ba75..bad6d5facce01 100644 --- a/test/Sema/spi-in-decls.swift +++ b/test/Sema/spi-in-decls.swift @@ -251,15 +251,24 @@ protocol InternalAssociatedTypeProto { public struct PublicInferredAssociatedTypeImpl { public func takesAssoc(_: NormalStruct) {} } -extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} -extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} +extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + +extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + extension PublicInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay @usableFromInline struct UFIInferredAssociatedTypeImpl { public func takesAssoc(_: NormalStruct) {} } -extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} -extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} + +extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + +extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + extension UFIInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay struct InternalInferredAssociatedTypeImpl { @@ -273,8 +282,12 @@ public struct PublicExplicitAssociatedTypeImpl { public typealias Assoc = NormalStruct public func takesAssoc(_: NormalStruct) {} } -extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} -extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} +extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} + +extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc'}} + extension PublicExplicitAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay @@ -285,7 +298,8 @@ public protocol BaseProtoWithNoRequirement { public protocol RefinedProto: BaseProtoWithNoRequirement where Assoc: NormalProto { } -public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}} +public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}} public func takesAssoc(_: NormalStruct) {} } @@ -300,17 +314,23 @@ public protocol SlightlyMoreComplicatedRequirement { associatedtype Assoc: Collection where Assoc.Element: NormalProto func takesAssoc(_: Assoc) } -public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct'); the conformance is declared as SPI}} +public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct')}} public func takesAssoc(_: [NormalStruct]) {} } -public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass'); the conformance is declared as SPI}} +public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass')}} public func takesAssoc(_: [SubclassOfNormalClass]) {} } -public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct'); the conformance is declared as SPI}} +public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct')}} + public func takesAssoc(_: [ConditionalGenericStruct]) {} } -public struct ClassConstrainedGenericArg: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'T'); the conformance is declared as SPI}} +public struct ClassConstrainedGenericArg: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}} +// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'T')}} + public func takesAssoc(_: T) {} } diff --git a/test/SourceKit/CursorInfo/invalid_offset.swift b/test/SourceKit/CursorInfo/invalid_offset.swift index e01d0fdefc092..3c91054814b99 100644 --- a/test/SourceKit/CursorInfo/invalid_offset.swift +++ b/test/SourceKit/CursorInfo/invalid_offset.swift @@ -1,15 +1,12 @@ let a = 12 // rdar://problem/30346106 -// Invalid offset should trigger a crash. +// Invalid offset should not trigger a crash. // RUN: not %sourcekitd-test 2>&1 \ // RUN: -req=open %s -- %s == \ // RUN: -req=edit -async -offset=0 -length=200 -replace='' %s -- %s == \ -// RUN: -req=cursor -offset=250 %s -- %s \ -// RUN: | %FileCheck %s +// RUN: -req=cursor -offset=250 %s -- %s // rdar://problem/38162017 // REQUIRES: OS=macosx - -// CHECK: (Request Failed): Unable to resolve the start of the token diff --git a/test/SourceKit/Misc/Inputs/errors-a.swift b/test/SourceKit/Misc/Inputs/errors-a.swift new file mode 100644 index 0000000000000..cb806c6befef8 --- /dev/null +++ b/test/SourceKit/Misc/Inputs/errors-a.swift @@ -0,0 +1,88 @@ +this file has a _bunch_ of errors, but we +want to generate the module anyway! + +public typealias InvalidAlias = undefined + +public class InvalidClass: undefined, InvalidProtocol { + public var classMemberA: undefined + + public init(param1: undefined, param2: undefined) { + undefined + } + + public convenience init() { + self.init(undefined, undefined) + } + + public convenience init(param: undefined) {} +} + +public class InvalidClassSub1: InvalidClass { + public var classMemberB: undefined + + public override init(param1: undefined, param2: undefined) { + undefined + } + + public convenience init() {} +} + +public class InvalidClassSub2: InvalidClass { + public var classMemberC: undefined + + public convenience init() {} +} + +public enum InvalidEnum { + var badEnumMemberA + + case enumeratorA + case enumeratorB, enumeratorC trailing +} + +public struct InvalidGenericStruct + where T.Item == U.Item, T.Item: undefined { + public var genericMemberA: undefined +} + +public protocol InvalidProtocol : undefined { + associatedtype Item + mutating func add(_) + func get() -> Item + mutating func set(item: Item) +} + +public struct InvalidStruct : undefined, InvalidProtocol { + typealias Item = undefined + + public let memberA: Int = undefined { + willSet(newVal invalid) { + print("Setting value \(newVal)") + } + didSet(oldVal invalid) { + print("Set value \(oldVal)") + } + } + public let memberB: undefined { + willSet { + print("Setting value \(newValue)") + } + didSet { + print("Set value \(oldValue)") + } + } + public var memberC: undefined { + return undefined + }() + public lazy var memberD: undefined { + return undefined + }() + public var memberE: undefined { + get { undefined } + set { undefined = "bar" } + } + + mutating func set(item: Item) { + undefined + } +} diff --git a/test/SourceKit/Misc/Inputs/errors-b.swift b/test/SourceKit/Misc/Inputs/errors-b.swift new file mode 100644 index 0000000000000..cc43e8f139315 --- /dev/null +++ b/test/SourceKit/Misc/Inputs/errors-b.swift @@ -0,0 +1,28 @@ +public func invalidFuncBody() { undefined } + +public func invalidFuncSignature(undefined '' undefined) {} + +public func invalidFuncThrows() throws -> undefined { throw undefined } + +public func invalidFuncType() -> undefined {} + +public func invalidGenericFuncBody(param: T) -> T { undefined } + +public func invalidGenericFuncType(param: T) -> undefined {} + +public let invalidGlobalClosureBody = { arg -> Int in + undefined +} + +public let invalidGlobalClosureType = { -> in } + +public let invalidGlobalKeypath = InvalidStruct\.undefined + +public let invalidGlobalMissingInit: String = + +public func invalidPartialFunc + +public func typeUsesFunc(pe: InvalidEnum, pa: InvalidAlias, + pp: InvalidProtocol, ps: InvalidStruct, + pg: GenericInvalidStruct, + pc: InvalidClass) -> Int {} diff --git a/test/SourceKit/Misc/load-module-with-errors.swift b/test/SourceKit/Misc/load-module-with-errors.swift new file mode 100644 index 0000000000000..28584b61331ef --- /dev/null +++ b/test/SourceKit/Misc/load-module-with-errors.swift @@ -0,0 +1,125 @@ +import errors + +func foo() { + invalidGlobalMissingInit = "" + + let bar: InvalidStruct + bar.memberB + invalidPartialFunc() + bar. + + let baz: ; + +} + +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module -experimental-allow-module-with-compiler-errors -primary-file %S/Inputs/errors-a.swift %S/Inputs/errors-b.swift -module-name errors -o %t/errors.a.swiftmodule +// RUN: %target-swift-frontend -emit-module -experimental-allow-module-with-compiler-errors %S/Inputs/errors-a.swift -primary-file %S/Inputs/errors-b.swift -module-name errors -o %t/errors.b.swiftmodule +// RUN: %target-swift-frontend -merge-modules -emit-module -experimental-allow-module-with-compiler-errors %t/errors.a.swiftmodule %t/errors.b.swiftmodule -module-name errors -o %t/errors.swiftmodule + +// Read the module back in to make sure it can be deserialized +// RUN: %target-swift-ide-test -print-module -source-filename dummy -module-to-print errors -I %t | %FileCheck %s +// CHECK: typealias InvalidAlias = <> +// CHECK: class InvalidClass : <>, InvalidProtocol +// CHECK: var classMemberA: <> +// CHECK: init(param1: <>, param2: <>) +// CHECK: convenience init() +// CHECK: convenience init(param: <>) +// CHECK: class InvalidClassSub1 : InvalidClass +// CHECK: var classMemberB: <> +// CHECK: init(param1: <>, param2: <>) +// CHECK: convenience init() +// CHECK: class InvalidClassSub2 : InvalidClass +// CHECK: var classMemberC: <> +// CHECK: convenience init() +// CHECK: enum InvalidEnum +// CHECK: case enumeratorA +// CHECK: case enumeratorB +// CHECK: case enumeratorC +// CHECK: struct InvalidGenericStruct +// CHECK: var genericMemberA: <> +// CHECK: protocol InvalidProtocol +// CHECK: associatedtype Item +// CHECK: mutating func add(_: <>) +// CHECK: func get() -> Self.Item +// CHECK: func set(item: Self.Item) +// CHECK: struct InvalidStruct : <>, InvalidProtocol +// CHECK: typealias Item = <> +// CHECK: let memberA: Int +// CHECK: let memberB: <> +// CHECK: var memberC: <> { get } +// CHECK: lazy var memberD: <> { mutating get } +// CHECK: var memberE: <> +// CHECK: mutating func set(item: <>) +// CHECK: func invalidFuncBody() +// CHECK: func invalidFuncSignature() +// CHECK: func invalidFuncThrows() throws +// CHECK: func invalidFuncType() -> <> +// CHECK: func invalidGenericFuncBody(param: T) -> T +// CHECK: func invalidGenericFuncType(param: T) -> <> +// CHECK: invalidGlobalClosureBody: +// CHECK: invalidGlobalClosureType: +// CHECK: invalidGlobalKeypath: +// CHECK: invalidGlobalMissingInit: String +// CHECK: func invalidPartialFunc() +// CHECK: func typeUsesFunc + +// Check cursor info for the various symbols +// RUN: %sourcekitd-test -req=cursor -pos=4:3 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-GLOBAL +// CHECK-GLOBAL: source.lang.swift.ref.var.global +// CHECK-GLOBAL: invalidGlobalMissingInit + +// RUN: %sourcekitd-test -req=cursor -pos=6:12 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-STRUCT +// CHECK-STRUCT: source.lang.swift.ref.struct +// CHECK-STRUCT: InvalidStruct + +// : %sourcekitd-test -req=cursor -pos=7:7 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-MEMBER +// CHECK-MEMBER: source.lang.swift.ref.var.instance +// CHECK-MEMBER: memberB + +// RUN: %sourcekitd-test -req=cursor -pos=8:3 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-FUNC +// CHECK-FUNC: source.lang.swift.ref.function.free +// CHECK-FUNC: invalidPartialFunc + +// Check completions +// RUN: %sourcekitd-test -req=complete -pos=9:7 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-MEMBER-COMPLETE +// CHECK-MEMBER-COMPLETE: key.name: "add( +// CHECK-MEMBER-COMPLETE: key.name: "get( +// CHECK-MEMBER-COMPLETE: key.name: "memberA" +// CHECK-MEMBER-COMPLETE: key.name: "memberB" +// CHECK-MEMBER-COMPLETE: key.name: "memberC" +// CHECK-MEMBER-COMPLETE: key.name: "memberD" +// CHECK-MEMBER-COMPLETE: key.name: "memberE" +// CHECK-MEMBER-COMPLETE: key.name: "set( + +// RUN: %sourcekitd-test -req=complete -pos=11:11 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-TYPE-COMPLETE +// CHECK-TYPE-COMPLETE: key.name: "InvalidAlias" +// CHECK-TYPE-COMPLETE: key.name: "InvalidClass" +// CHECK-TYPE-COMPLETE: key.name: "InvalidClassSub1" +// CHECK-TYPE-COMPLETE: key.name: "InvalidClassSub2" +// CHECK-TYPE-COMPLETE: key.name: "InvalidEnum" +// CHECK-TYPE-COMPLETE: key.name: "InvalidGenericStruct" +// CHECK-TYPE-COMPLETE: key.name: "InvalidProtocol" +// CHECK-TYPE-COMPLETE: key.name: "InvalidStruct" + +// RUN: %sourcekitd-test -req=complete -pos=12:1 %s -- -I %t -target %target-triple %s | %FileCheck %s -check-prefix=CHECK-GLOBAL-COMPLETE +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidAlias" +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidClass" +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidClassSub1" +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidClassSub2" +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidEnum" +// CHECK-GLOBAL-COMPLETE: key.name: "invalidFuncBody( +// CHECK-GLOBAL-COMPLETE: key.name: "invalidFuncSignature( +// CHECK-GLOBAL-COMPLETE: key.name: "invalidFuncThrows( +// CHECK-GLOBAL-COMPLETE: key.name: "invalidFuncType( +// CHECK-GLOBAL-COMPLETE: key.name: "invalidGenericFuncBody( +// CHECK-GLOBAL-COMPLETE: key.name: "invalidGenericFuncType( +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidGenericStruct" +// CHECK-GLOBAL-COMPLETE: key.name: "invalidGlobalClosureBody" +// CHECK-GLOBAL-COMPLETE: key.name: "invalidGlobalClosureType +// CHECK-GLOBAL-COMPLETE: key.name: "invalidGlobalKeypath +// CHECK-GLOBAL-COMPLETE: key.name: "invalidGlobalMissingInit +// CHECK-GLOBAL-COMPLETE: key.name: "invalidPartialFunc( +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidProtocol" +// CHECK-GLOBAL-COMPLETE: key.name: "InvalidStruct" +// CHECK-GLOBAL-COMPLETE: key.name: "typeUsesFunc( diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp index 7f963f593916f..4d83b28f1a21c 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp @@ -660,6 +660,7 @@ static void reportAttributes(ASTContext &Ctx, static UIdent PlatformtvOSAppExt("source.availability.platform.tvos_app_extension"); static UIdent PlatformWatchOSAppExt("source.availability.platform.watchos_app_extension"); static UIdent PlatformOpenBSD("source.availability.platform.openbsd"); + static UIdent PlatformWindows("source.availability.platform.windows"); std::vector Scratch; for (auto Attr : getDeclAttributes(D, Scratch)) { @@ -690,6 +691,8 @@ static void reportAttributes(ASTContext &Ctx, PlatformUID = PlatformWatchOSAppExt; break; case PlatformKind::OpenBSD: PlatformUID = PlatformOpenBSD; break; + case PlatformKind::Windows: + PlatformUID = PlatformWindows; break; } AvailableAttrInfo Info; diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index 0c33df44404c0..9b42ea1c358a3 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -14,6 +14,21 @@ target_link_libraries(swift-frontend swiftSymbolGraphGen LLVMBitstreamReader) +# Generate and install supported feature JSON file to the toolchain. +if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(DUMMY_SWIFT_INPUT "${SWIFT_RUNTIME_OUTPUT_INTDIR}/dummyInput.swift") + set(INT_FEATURE_FILE "${SWIFT_RUNTIME_OUTPUT_INTDIR}/SupportedFeatures.json") + add_custom_command(TARGET swift-frontend POST_BUILD + COMMAND "${CMAKE_COMMAND}" "-E" "touch" "${DUMMY_SWIFT_INPUT}" + COMMAND "${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-frontend" + "-emit-supported-features" "-o" + "${INT_FEATURE_FILE}" + "${DUMMY_SWIFT_INPUT}") + swift_install_in_component(FILES "${INT_FEATURE_FILE}" + DESTINATION "bin" + COMPONENT compiler) +endif() + swift_create_post_build_symlink(swift-frontend SOURCE "swift-frontend${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION "swift${CMAKE_EXECUTABLE_SUFFIX}" diff --git a/utils/build-script-impl b/utils/build-script-impl index 5d5323a9dbfb5..2376ef7e955ad 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -2347,6 +2347,7 @@ for host in "${ALL_HOSTS[@]}"; do -DCMAKE_CXX_COMPILER:PATH="${CLANG_BIN}/clang++" -DCMAKE_SWIFT_COMPILER:PATH="${SWIFTC_BIN}" -DCMAKE_Swift_COMPILER:PATH="${SWIFTC_BIN}" + -DCMAKE_Swift_FLAGS:STRING="-module-cache-path \"${module_cache}\"" -DCMAKE_INSTALL_PREFIX:PATH="$(get_host_install_prefix ${host})" -DCMAKE_INSTALL_LIBDIR:PATH="lib" diff --git a/validation-test/Sema/type_checker_perf/fast/rdar18360240.swift.gyb b/validation-test/Sema/type_checker_perf/fast/rdar18360240.swift.gyb index a9e1b674c85ec..d3a80b33700c9 100644 --- a/validation-test/Sema/type_checker_perf/fast/rdar18360240.swift.gyb +++ b/validation-test/Sema/type_checker_perf/fast/rdar18360240.swift.gyb @@ -1,4 +1,4 @@ -// RUN: %scale-test --begin 2 --end 10 --step 2 --select NumConstraintScopes %s +// RUN: %scale-test --begin 2 --end 10 --step 2 --select NumConstraintScopes --polynomial-threshold 1.5 %s // REQUIRES: asserts,no_asan let empty: [Int] = []