diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d1903aed7e554..0c25e0dbd16d8 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -22,21 +22,29 @@ jobs:
sudo apt-get purge libgcc-9-dev gcc-9 libstdc++-9-dev
sudo swapoff -a
sudo rm -f /swapfile
+ sudo rm -rf /opt/hostedtoolcache
+ sudo rm -rf /usr/share/dotnet
sudo apt clean
docker rmi $(docker image ls -aq)
df -h
- uses: actions/checkout@v1
with:
path: swift
+ - name: Prepare sccache timestamp
+ id: cache_timestamp
+ shell: cmake -P {0}
+ run: |
+ string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
+ message("::set-output name=timestamp::${current_date}")
- uses: actions/cache@v1
with:
path: ../build-cache
- key: ${{ runner.os }}-sccache-v9
+ key: ${{ runner.os }}-sccache-v10-${{ steps.cache_timestamp.outputs.timestamp }}
+ restore-keys: |
+ ${{ runner.os }}-sccache-v10-
- name: Build Linux installable archive
run: |
./utils/webassembly/ci.sh
- echo "Cleanup build directory to free disk space"
- rm -rf ../build
- name: Upload Linux installable archive
uses: actions/upload-artifact@v1
with:
@@ -58,10 +66,18 @@ jobs:
- uses: actions/checkout@v1
with:
path: swift
+ - name: Prepare sccache timestamp
+ id: cache_timestamp
+ shell: cmake -P {0}
+ run: |
+ string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
+ message("::set-output name=timestamp::${current_date}")
- uses: actions/cache@v1
with:
path: ../build-cache
- key: ${{ runner.os }}-sccache-v9
+ key: ${{ runner.os }}-sccache-v10-${{ steps.cache_timestamp.outputs.timestamp }}
+ restore-keys: |
+ ${{ runner.os }}-sccache-v10-
- name: Build macOS installable archive
run: |
sudo xcode-select --switch /Applications/Xcode_12_beta.app/Contents/Developer/
@@ -72,7 +88,7 @@ jobs:
name: macos-installable
path: ../swift-wasm-DEVELOPMENT-SNAPSHOT-osx.tar.gz
- name: Pack test results
- run: tar cJf swift-test-results.tar.gz ../build/*/swift-macosx-x86_64/swift-test-results
+ run: tar cJf swift-test-results.tar.gz ../target-build/*/swift-macosx-x86_64/swift-test-results
- name: Upload test results
uses: actions/upload-artifact@v1
with:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b2af5d8f7abe..fb765f84639a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,29 +4,100 @@ CHANGELOG
Note: This is in reverse chronological order, so newer entries are added to the top.
-| Version | Released | Toolchain |
-| :--------------------- | :--------- | :---------- |
-| [Swift 5.3](#swift-53) | | |
-| [Swift 5.2](#swift-52) | 2020-03-24 | Xcode 11.4 |
-| [Swift 5.1](#swift-51) | 2019-09-20 | Xcode 11.0 |
-| [Swift 5.0](#swift-50) | 2019-03-25 | Xcode 10.2 |
-| [Swift 4.2](#swift-42) | 2018-09-17 | Xcode 10.0 |
-| [Swift 4.1](#swift-41) | 2018-03-29 | Xcode 9.3 |
-| [Swift 4.0](#swift-40) | 2017-09-19 | Xcode 9.0 |
-| [Swift 3.1](#swift-31) | 2017-03-27 | Xcode 8.3 |
-| [Swift 3.0](#swift-30) | 2016-09-13 | Xcode 8.0 |
-| [Swift 2.2](#swift-22) | 2016-03-21 | Xcode 7.3 |
-| [Swift 2.1](#swift-21) | 2015-10-21 | Xcode 7.1 |
-| [Swift 2.0](#swift-20) | 2015-09-17 | Xcode 7.0 |
-| [Swift 1.2](#swift-12) | 2015-04-08 | Xcode 6.3 |
-| [Swift 1.1](#swift-11) | 2014-12-02 | Xcode 6.1.1 |
-| [Swift 1.0](#swift-10) | 2014-09-15 | Xcode 6.0 |
+| Version | Released | Toolchain |
+| :------------------------ | :--------- | :---------- |
+| [Swift Next](#swift-next) |
+| [Swift 5.3](#swift-53) | | |
+| [Swift 5.2](#swift-52) | 2020-03-24 | Xcode 11.4 |
+| [Swift 5.1](#swift-51) | 2019-09-20 | Xcode 11.0 |
+| [Swift 5.0](#swift-50) | 2019-03-25 | Xcode 10.2 |
+| [Swift 4.2](#swift-42) | 2018-09-17 | Xcode 10.0 |
+| [Swift 4.1](#swift-41) | 2018-03-29 | Xcode 9.3 |
+| [Swift 4.0](#swift-40) | 2017-09-19 | Xcode 9.0 |
+| [Swift 3.1](#swift-31) | 2017-03-27 | Xcode 8.3 |
+| [Swift 3.0](#swift-30) | 2016-09-13 | Xcode 8.0 |
+| [Swift 2.2](#swift-22) | 2016-03-21 | Xcode 7.3 |
+| [Swift 2.1](#swift-21) | 2015-10-21 | Xcode 7.1 |
+| [Swift 2.0](#swift-20) | 2015-09-17 | Xcode 7.0 |
+| [Swift 1.2](#swift-12) | 2015-04-08 | Xcode 6.3 |
+| [Swift 1.1](#swift-11) | 2014-12-02 | Xcode 6.1.1 |
+| [Swift 1.0](#swift-10) | 2014-09-15 | Xcode 6.0 |
+Swift Next
+----------
+
+* [SE-0287][]:
+
+ Implicit member expressions now support chains of member accesses, making the following valid:
+
+ ```swift
+ let milky: UIColor = .white.withAlphaComponent(0.5)
+ let milky2: UIColor = .init(named: "white")!.withAlphaComponent(0.5)
+ let milkyChance: UIColor? = .init(named: "white")?.withAlphaComponent(0.5)
+ ```
+
+ As is the case with the existing implicit member expression syntax, the resulting type of the chain must be the same as the (implicit) base, so it is not well-formed to write:
+
+ ```swift
+ let cgMilky: CGColor = .white.withAlphaComponent(0.5).cgColor
+ ```
+
+ (Unless, of course, appropriate `white` and `withAlphaComponent` members were defined on `CGColor`.)
+
+ Members of a "chain" can be properties, method calls, subscript accesses, force unwraps, or optional chaining question marks. Furthermore, the type of each member along the chain is permitted to differ (again, as long as the base of the chain matches the resulting type) meaning the following successfully typechecks:
+
+ ```swift
+ struct Foo {
+ static var foo = Foo()
+ static var bar = Bar()
+
+ var anotherFoo: Foo { Foo() }
+ func getFoo() -> Foo { Foo() }
+ var optionalFoo: Foo? { Foo() }
+ subscript() -> Foo { Foo() }
+ }
+
+ struct Bar {
+ var anotherFoo = Foo()
+ }
+
+ let _: Foo? = .bar.anotherFoo.getFoo().optionalFoo?.optionalFoo![]
+ ```
+
Swift 5.3
---------
+* [SE-0279][] & [SE-0286][]:
+
+ Trailing closure syntax has been extended to allow additional labeled closures to follow the initial unlabeled closure:
+
+ ```swift
+ // Single trailing closure argument
+ UIView.animate(withDuration: 0.3) {
+ self.view.alpha = 0
+ }
+ // Multiple trailing closure arguments
+ UIView.animate(withDuration: 0.3) {
+ self.view.alpha = 0
+ } completion: { _ in
+ self.view.removeFromSuperview()
+ }
+ ```
+
+ Additionally, trailing closure arguments now match the appropriate parameter according to a forward-scan rule (as opposed to the previous backward-scan rule):
+
+ ```swift
+ func takesClosures(first: () -> Void, second: (Int) -> Void = { _ in }) {}
+
+ takesClosures {
+ print("First")
+ }
+ ```
+
+ In the above example, the trailing closure argument matches parameter `first`, whereas pre-Swift-5.3 it would have matched `second`. In order to ease the transition to this new rule, cases in which the forward-scan and backward-scan match a single trailing closure to different parameters, the backward-scan result is preferred and a warning is emitted. This is expected to be upgraded to an error in the next major version of Swift.
+
* [SR-7083][]:
Property observers such as `willSet` and `didSet` are now supported on `lazy` properties:
@@ -8070,7 +8141,10 @@ Swift 1.0
[SE-0268]:
[SE-0269]:
[SE-0276]:
+[SE-0279]:
[SE-0280]:
+[SE-0286]:
+[SE-0287]:
[SR-75]:
[SR-106]:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 31d450f959d8d..38f3b831b2f59 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -369,6 +369,10 @@ option(SWIFT_REPORT_STATISTICS
"Create json files which contain internal compilation statistics"
FALSE)
+option(SWIFT_DISABLE_OBJC_INTEROP
+ "Disable Objective-C interoperability even on platforms what would normally have it"
+ FALSE)
+
# FIXME(wasm) Reflection tests are temporalily disabled due to lack of linker features
option(SWIFTWASM_DISABLE_REFLECTION_TEST
"Disable building swift-reflection-test for WebAssembly build"
@@ -391,10 +395,6 @@ option(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
"Should the runtime be built with support for non-thread-safe leak detecting entrypoints"
FALSE)
-option(SWIFT_STDLIB_USE_NONATOMIC_RC
- "Build the standard libraries and overlays with nonatomic reference count operations enabled"
- FALSE)
-
option(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS
"Enable runtime function counters and expose the API."
FALSE)
@@ -634,6 +634,22 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQU
set(SWIFT_COMPILER_IS_MSVC_LIKE TRUE)
endif()
+if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
+ # CMake's default for CMAKE_CXX_FLAGS_RELEASE is "-O3 -DNDEBUG". Let's avoid "-O3" for consistency
+ # between Release and RelWithDebInfo. Dropping -DNDEBUG from this setting is blocked by triggering
+ # a test failure of Swift-Unit :: Syntax/./SwiftSyntaxTests/TypeSyntaxTests.MetatypeTypeWithAPIs
+ # because unit tests don't currently explicitly set -DNDEBUG/-UNDEBUG.
+ set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
+
+ _compute_lto_flag("${SWIFT_TOOLS_ENABLE_LTO}" _lto_flag_out)
+ if(_lto_flag_out)
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE} -gline-tables-only")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -gline-tables-only")
+ endif()
+else()
+
+endif()
+
#
# Configure SDKs.
#
@@ -933,7 +949,6 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
endif()
endif()
-find_package(Python2 COMPONENTS Interpreter REQUIRED)
find_package(Python3 COMPONENTS Interpreter REQUIRED)
#
diff --git a/README.md b/README.md
index e99f28b549c8d..ab4a2a6033f29 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,14 @@ The required version of Xcode changes frequently, and is often a beta release.
Check this document or the host information on for the
current required version.
+Swift's build tooling is meant to support spaces in the paths passed to them,
+but using spaces sometimes tickles bugs in Swift's build scripts or the tools
+they rely on. For example, [SR-13441](https://bugs.swift.org/browse/SR-13441)
+is caused by a space in the Xcode path used on macOS. If you see Swift's build
+tooling misbehave due to a space in a path, please
+[report the bug on the Swift bug tracker](https://swift.org/contributing/#reporting-bugs)
+and then change the path to work around it.
+
You will also need [CMake](https://cmake.org) and [Ninja](https://ninja-build.org),
which can be installed via a package manager:
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index ef28ed87b2483..f63860100e928 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -91,6 +91,7 @@ set(SWIFT_BENCH_MODULES
single-source/Fibonacci
single-source/FindStringNaive
single-source/FlattenList
+ single-source/FloatingPointConversion
single-source/FloatingPointParsing
single-source/FloatingPointPrinting
single-source/Hanoi
@@ -136,6 +137,7 @@ set(SWIFT_BENCH_MODULES
single-source/PrefixWhile
single-source/Prims
single-source/PrimsNonStrongRef
+ single-source/ProtocolConformance
single-source/ProtocolDispatch
single-source/ProtocolDispatch2
single-source/Queue
diff --git a/benchmark/scripts/Template.swift b/benchmark/scripts/Template.swift
index 00337a1fb48b4..ea25b249d4679 100644
--- a/benchmark/scripts/Template.swift
+++ b/benchmark/scripts/Template.swift
@@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
-// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
+// 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
@@ -19,4 +19,4 @@ public let {name} = [
@inline(never)
public func run_{name}(N: Int) {{
// TODO
-}}
\ No newline at end of file
+}}
diff --git a/benchmark/single-source/FloatingPointConversion.swift b/benchmark/single-source/FloatingPointConversion.swift
new file mode 100644
index 0000000000000..ebf2c6d4b19a3
--- /dev/null
+++ b/benchmark/single-source/FloatingPointConversion.swift
@@ -0,0 +1,190 @@
+//===--- FloatingPointConversion.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 TestsUtils
+
+public let FloatingPointConversion = [
+ BenchmarkInfo(
+ name: "ConvertFloatingPoint.ConcreteDoubleToDouble",
+ runFunction: run_ConvertFloatingPoint_ConcreteDoubleToDouble,
+ tags: [.validation, .api],
+ setUpFunction: { blackHole(doubles) }),
+ BenchmarkInfo(
+ name: "ConvertFloatingPoint.GenericDoubleToDouble",
+ runFunction: run_ConvertFloatingPoint_GenericDoubleToDouble,
+ tags: [.validation, .api],
+ setUpFunction: { blackHole(doubles) }),
+ BenchmarkInfo(
+ name: "ConvertFloatingPoint.MockFloat64ToDouble",
+ runFunction: run_ConvertFloatingPoint_MockFloat64ToDouble,
+ tags: [.validation, .api],
+ setUpFunction: { blackHole(mockFloat64s) }),
+]
+
+protocol MockBinaryFloatingPoint: BinaryFloatingPoint {
+ associatedtype _Value: BinaryFloatingPoint
+ var _value: _Value { get set }
+ init(_ _value: _Value)
+}
+
+extension MockBinaryFloatingPoint {
+ static var exponentBitCount: Int { _Value.exponentBitCount }
+ static var greatestFiniteMagnitude: Self {
+ Self(_Value.greatestFiniteMagnitude)
+ }
+ static var infinity: Self { Self(_Value.infinity) }
+ static var leastNonzeroMagnitude: Self { Self(_Value.leastNonzeroMagnitude) }
+ static var leastNormalMagnitude: Self { Self(_Value.leastNormalMagnitude) }
+ static var nan: Self { Self(_Value.nan) }
+ static var pi: Self { Self(_Value.pi) }
+ static var signalingNaN: Self { Self(_Value.signalingNaN) }
+ static var significandBitCount: Int { _Value.significandBitCount }
+
+ static func + (lhs: Self, rhs: Self) -> Self { Self(lhs._value + rhs._value) }
+ static func += (lhs: inout Self, rhs: Self) { lhs._value += rhs._value }
+ static func - (lhs: Self, rhs: Self) -> Self { Self(lhs._value - rhs._value) }
+ static func -= (lhs: inout Self, rhs: Self) { lhs._value -= rhs._value }
+ static func * (lhs: Self, rhs: Self) -> Self { Self(lhs._value * rhs._value) }
+ static func *= (lhs: inout Self, rhs: Self) { lhs._value *= rhs._value }
+ static func / (lhs: Self, rhs: Self) -> Self { Self(lhs._value / rhs._value) }
+ static func /= (lhs: inout Self, rhs: Self) { lhs._value /= rhs._value }
+
+ init(_ value: Int) { self.init(_Value(value)) }
+ init(_ value: Float) { self.init(_Value(value)) }
+ init(_ value: Double) { self.init(_Value(value)) }
+ #if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
+ init(_ value: Float80) { self.init(_Value(value)) }
+ #endif
+ init(integerLiteral value: _Value.IntegerLiteralType) {
+ self.init(_Value(integerLiteral: value))
+ }
+ init(floatLiteral value: _Value.FloatLiteralType) {
+ self.init(_Value(floatLiteral: value))
+ }
+ init(sign: FloatingPointSign, exponent: _Value.Exponent, significand: Self) {
+ self.init(
+ _Value(sign: sign, exponent: exponent, significand: significand._value))
+ }
+ init(
+ sign: FloatingPointSign,
+ exponentBitPattern: _Value.RawExponent,
+ significandBitPattern: _Value.RawSignificand
+ ) {
+ self.init(
+ _Value(
+ sign: sign,
+ exponentBitPattern: exponentBitPattern,
+ significandBitPattern: significandBitPattern))
+ }
+
+ var binade: Self { Self(_value.binade) }
+ var exponent: _Value.Exponent { _value.exponent }
+ var exponentBitPattern: _Value.RawExponent { _value.exponentBitPattern }
+ var isCanonical: Bool { _value.isCanonical }
+ var isFinite: Bool { _value.isFinite }
+ var isInfinite: Bool { _value.isInfinite }
+ var isNaN: Bool { _value.isNaN }
+ var isNormal: Bool { _value.isNormal }
+ var isSignalingNaN: Bool { _value.isSignalingNaN }
+ var isSubnormal: Bool { _value.isSubnormal }
+ var isZero: Bool { _value.isZero }
+ var magnitude: Self { Self(_value.magnitude) }
+ var nextDown: Self { Self(_value.nextDown) }
+ var nextUp: Self { Self(_value.nextUp) }
+ var sign: FloatingPointSign { _value.sign }
+ var significand: Self { Self(_value.significand) }
+ var significandBitPattern: _Value.RawSignificand {
+ _value.significandBitPattern
+ }
+ var significandWidth: Int { _value.significandWidth }
+ var ulp: Self { Self(_value.ulp) }
+
+ mutating func addProduct(_ lhs: Self, _ rhs: Self) {
+ _value.addProduct(lhs._value, rhs._value)
+ }
+ func advanced(by n: _Value.Stride) -> Self { Self(_value.advanced(by: n)) }
+ func distance(to other: Self) -> _Value.Stride {
+ _value.distance(to: other._value)
+ }
+ mutating func formRemainder(dividingBy other: Self) {
+ _value.formRemainder(dividingBy: other._value)
+ }
+ mutating func formSquareRoot() { _value.formSquareRoot() }
+ mutating func formTruncatingRemainder(dividingBy other: Self) {
+ _value.formTruncatingRemainder(dividingBy: other._value)
+ }
+ func isEqual(to other: Self) -> Bool { _value.isEqual(to: other._value) }
+ func isLess(than other: Self) -> Bool { _value.isLess(than: other._value) }
+ func isLessThanOrEqualTo(_ other: Self) -> Bool {
+ _value.isLessThanOrEqualTo(other._value)
+ }
+ mutating func round(_ rule: FloatingPointRoundingRule) { _value.round(rule) }
+}
+
+struct MockFloat64: MockBinaryFloatingPoint {
+ var _value: Double
+ init(_ _value: Double) { self._value = _value }
+}
+
+let doubles = [
+ 1.8547832857295, 26.321549267719135, 98.9544480962058, 73.70286973782363,
+ 82.04918555938816, 76.38902969312758, 46.35647857011161, 64.0821426030317,
+ 97.82373347320156, 55.742361037720634, 23.677941665488856, 93.7347588108058,
+ 80.72657040828412, 32.137580733275826, 64.78192587530002, 21.459686568896863,
+ 24.88407660280718, 85.25905561999171, 12.858847331083556, 29.418845887252864,
+ 67.64627066438761, 68.09883494078815, 57.781587230862094, 63.38335631088038,
+ 83.31376661495327, 87.45936846358906, 0.6757674136841918, 86.45465036820696,
+ 84.72715137492781, 82.67894289189142, 26.1667640621554, 21.24895661442493,
+ 65.06399183516027, 90.06549073883058, 59.2736650501005, 94.5800380563246,
+ 84.22617424003917, 26.93158630395639, 9.069952095976841, 96.10067836567679,
+ 62.60505762081415, 29.57878462599286, 66.06040114311294, 51.709999429326636,
+ 64.79777579583545, 45.25948795832151, 94.31492354198335, 52.31096166433902,
+]
+
+let mockFloat64s = doubles.map { MockFloat64($0) }
+
+@inline(__always)
+func convert<
+ T: BinaryFloatingPoint, U: BinaryFloatingPoint
+>(_ value: T, to: U.Type) -> U {
+ U(value)
+}
+
+@inline(never)
+public func run_ConvertFloatingPoint_ConcreteDoubleToDouble(_ N: Int) {
+ for _ in 0..<(N * 100) {
+ for element in doubles {
+ let f = Double(identity(element))
+ blackHole(f)
+ }
+ }
+}
+
+@inline(never)
+public func run_ConvertFloatingPoint_GenericDoubleToDouble(_ N: Int) {
+ for _ in 0..<(N * 100) {
+ for element in doubles {
+ let f = convert(identity(element), to: Double.self)
+ blackHole(f)
+ }
+ }
+}
+
+@inline(never)
+public func run_ConvertFloatingPoint_MockFloat64ToDouble(_ N: Int) {
+ for _ in 0..<(N * 100) {
+ for element in mockFloat64s {
+ let f = Double(identity(element))
+ blackHole(f)
+ }
+ }
+}
diff --git a/benchmark/single-source/ProtocolConformance.swift b/benchmark/single-source/ProtocolConformance.swift
new file mode 100644
index 0000000000000..b042065c02ab3
--- /dev/null
+++ b/benchmark/single-source/ProtocolConformance.swift
@@ -0,0 +1,76 @@
+//===--- ProtocolDispatch.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 TestsUtils
+
+public let ProtocolConformance = BenchmarkInfo (
+ name: "ProtocolConformance",
+ runFunction: run_ProtocolConformance,
+ tags: [.validation, .runtime])
+
+protocol P {}
+
+struct One: P {}
+struct Two {}
+
+struct Cat {}
+
+extension Cat: P where T: P, U: P {}
+
+protocol Growable {}
+extension Growable {
+ func grow() -> (Growable, Growable) {
+ return (Cat(), Cat())
+ }
+}
+
+extension One: Growable {}
+extension Two: Growable {}
+extension Cat: Growable {}
+
+@inline(never)
+public func run_ProtocolConformance(_ N: Int) {
+ var array: [Growable] = [One(), Two()]
+ var i = 0
+ var checks = 0
+
+ // The expected number of times we expect `elt is P` to be true.
+ var expectedConforms = 0
+
+ // The expected number of times we expect `elt is P` to be true
+ // per iteration, at the current time.
+ var expectedConformsPerIter = 1
+
+ // The number of times we've actually seen `elt is P` be true.
+ var conforms = 0
+ while checks < N * 500 {
+ let (a, b) = array[i].grow()
+ array.append(a)
+ array.append(b)
+
+ // The number of times `elt is P` is true per outer iteration
+ // goes up by 1 when the array's count is a power of 2.
+ if array.count & (array.count - 1) == 0 {
+ expectedConformsPerIter += 1
+ }
+ expectedConforms += expectedConformsPerIter
+
+ for elt in array {
+ if elt is P {
+ conforms += 1
+ }
+ checks += 1
+ }
+ i += 1
+ }
+ CheckResults(expectedConforms == conforms)
+}
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index b4791ad6208e7..160c4eb50c8a3 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -79,6 +79,7 @@ import ExistentialPerformance
import Fibonacci
import FindStringNaive
import FlattenList
+import FloatingPointConversion
import FloatingPointParsing
import FloatingPointPrinting
import Hanoi
@@ -131,6 +132,7 @@ import PrefixWhile
import Prims
import PrimsNonStrongRef
import PrimsSplit
+import ProtocolConformance
import ProtocolDispatch
import ProtocolDispatch2
import Queue
@@ -265,6 +267,7 @@ registerBenchmark(Fibonacci)
registerBenchmark(FindStringNaive)
registerBenchmark(FlattenListLoop)
registerBenchmark(FlattenListFlatMap)
+registerBenchmark(FloatingPointConversion)
registerBenchmark(FloatingPointParsing)
registerBenchmark(FloatingPointPrinting)
registerBenchmark(Hanoi)
@@ -317,6 +320,7 @@ registerBenchmark(PrefixWhile)
registerBenchmark(Prims)
registerBenchmark(PrimsNonStrongRef)
registerBenchmark(PrimsSplit)
+registerBenchmark(ProtocolConformance)
registerBenchmark(ProtocolDispatch)
registerBenchmark(ProtocolDispatch2)
registerBenchmark(QueueGeneric)
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 1db26266cb757..e4304b6b484eb 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -93,7 +93,7 @@ function(_add_host_variant_c_compile_link_flags name)
set(_sysroot
"${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}")
- if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS)
+ if(SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_USE_ISYSROOT)
target_compile_options(${name} PRIVATE -isysroot;${_sysroot})
elseif(NOT SWIFT_COMPILER_IS_MSVC_LIKE AND NOT "${_sysroot}" STREQUAL "/")
target_compile_options(${name} PRIVATE --sysroot=${_sysroot})
@@ -130,13 +130,18 @@ function(_add_host_variant_c_compile_flags target)
_add_host_variant_c_compile_link_flags(${target})
is_build_type_optimized("${CMAKE_BUILD_TYPE}" optimized)
- if(optimized)
- target_compile_options(${target} PRIVATE -O2)
+ is_build_type_with_debuginfo("${CMAKE_BUILD_TYPE}" debuginfo)
+ # Add -O0/-O2/-O3/-Os/-g/-momit-leaf-frame-pointer/... based on CMAKE_BUILD_TYPE.
+ target_compile_options(${target} PRIVATE "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
+
+ if(optimized)
# Omit leaf frame pointers on x86 production builds (optimized, no debug
# info, and no asserts).
- is_build_type_with_debuginfo("${CMAKE_BUILD_TYPE}" debug)
- if(NOT debug AND NOT LLVM_ENABLE_ASSERTIONS)
+ if(NOT debuginfo AND NOT LLVM_ENABLE_ASSERTIONS)
+ # Unfortunately, this cannot be folded into the standard
+ # CMAKE_CXX_FLAGS_... because Apple multi-SDK builds use different
+ # architectures for different SDKs.
if(SWIFT_HOST_VARIANT_ARCH MATCHES "i?86")
if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
target_compile_options(${target} PRIVATE -momit-leaf-frame-pointer)
@@ -145,27 +150,6 @@ function(_add_host_variant_c_compile_flags target)
endif()
endif()
endif()
- else()
- if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
- target_compile_options(${target} PRIVATE -O0)
- else()
- target_compile_options(${target} PRIVATE /Od)
- endif()
- endif()
-
- # CMake automatically adds the flags for debug info if we use MSVC/clang-cl.
- if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
- is_build_type_with_debuginfo("${CMAKE_BUILD_TYPE}" debuginfo)
- if(debuginfo)
- _compute_lto_flag("${SWIFT_TOOLS_ENABLE_LTO}" _lto_flag_out)
- if(_lto_flag_out)
- target_compile_options(${target} PRIVATE -gline-tables-only)
- else()
- target_compile_options(${target} PRIVATE -g)
- endif()
- else()
- target_compile_options(${target} PRIVATE -g0)
- endif()
endif()
if(SWIFT_HOST_VARIANT_SDK STREQUAL WINDOWS)
diff --git a/cmake/modules/DarwinSDKs.cmake b/cmake/modules/DarwinSDKs.cmake
index 20a5620fba6a7..dc570b7005834 100644
--- a/cmake/modules/DarwinSDKs.cmake
+++ b/cmake/modules/DarwinSDKs.cmake
@@ -26,6 +26,24 @@ if(swift_build_osx)
configure_target_variant(OSX-R "OS X Release" OSX R "Release")
endif()
+is_sdk_requested(FREESTANDING swift_build_freestanding)
+if(swift_build_freestanding)
+ set(SWIFT_FREESTANDING_SDK "" CACHE STRING
+ "Which SDK to use when building the FREESTANDING stdlib")
+ set(SWIFT_FREESTANDING_TRIPLE_NAME "" CACHE STRING
+ "Which triple name (e.g. 'none-macho') to use when building the FREESTANDING stdlib")
+ set(SWIFT_FREESTANDING_ARCHS "" CACHE STRING
+ "Which architectures to build when building the FREESTANDING stdlib")
+ configure_sdk_darwin(
+ FREESTANDING "FREESTANDING" ""
+ "${SWIFT_FREESTANDING_SDK}" freestanding "${SWIFT_FREESTANDING_TRIPLE_NAME}" freestanding "${SWIFT_FREESTANDING_ARCHS}")
+ set(SWIFT_SDK_FREESTANDING_LIB_SUBDIR "freestanding")
+ configure_target_variant(FREESTANDING-DA "FREESTANDING Debug+Asserts" FREESTANDING DA "Debug+Asserts")
+ configure_target_variant(FREESTANDING-RA "FREESTANDING Release+Asserts" FREESTANDING RA "Release+Asserts")
+ configure_target_variant(FREESTANDING-R "FREESTANDING Release" FREESTANDING R "Release")
+ configure_target_variant(FREESTANDING-S "FREESTANDING MinSizeRelease" FREESTANDING S "MinSizeRelease")
+endif()
+
# Compatible cross-compile SDKS for Darwin OSes: IOS, IOS_SIMULATOR, TVOS,
# TVOS_SIMULATOR, WATCHOS, WATCHOS_SIMULATOR (archs hardcoded below).
diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake
index 52c08025e62a0..feb7f513c96ce 100644
--- a/cmake/modules/SwiftConfigureSDK.cmake
+++ b/cmake/modules/SwiftConfigureSDK.cmake
@@ -145,6 +145,8 @@ endfunction()
# SWIFT_SDK_${prefix}_LIB_SUBDIR Library subdir for this SDK
# SWIFT_SDK_${prefix}_VERSION_MIN_NAME Version min name for this SDK
# SWIFT_SDK_${prefix}_TRIPLE_NAME Triple name for this SDK
+# SWIFT_SDK_${prefix}_OBJECT_FORMAT The object file format (e.g. MACHO)
+# SWIFT_SDK_${prefix}_USE_ISYSROOT Whether to use -isysroot
# SWIFT_SDK_${prefix}_ARCHITECTURES Architectures (as a list)
# SWIFT_SDK_${prefix}_IS_SIMULATOR Whether this is a simulator target.
# SWIFT_SDK_${prefix}_ARCH_${ARCH}_TRIPLE Triple name
@@ -187,6 +189,7 @@ macro(configure_sdk_darwin
set(SWIFT_SDK_${prefix}_VERSION_MIN_NAME "${version_min_name}")
set(SWIFT_SDK_${prefix}_TRIPLE_NAME "${triple_name}")
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "MACHO")
+ set(SWIFT_SDK_${prefix}_USE_ISYSROOT TRUE)
set(SWIFT_SDK_${prefix}_ARCHITECTURES ${architectures})
if(SWIFT_DARWIN_SUPPORTED_ARCHS)
@@ -270,6 +273,7 @@ macro(configure_sdk_unix name architectures)
else()
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "ELF")
endif()
+ set(SWIFT_SDK_${prefix}_USE_ISYSROOT FALSE)
foreach(arch ${architectures})
if("${prefix}" STREQUAL "ANDROID")
@@ -432,6 +436,7 @@ macro(configure_sdk_windows name environment architectures)
set(SWIFT_SDK_${prefix}_LIB_SUBDIR "windows")
set(SWIFT_SDK_${prefix}_ARCHITECTURES "${architectures}")
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "COFF")
+ set(SWIFT_SDK_${prefix}_USE_ISYSROOT FALSE)
foreach(arch ${architectures})
if(arch STREQUAL armv7)
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index a65799b8c53cd..9e60d04a4f5e3 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -176,6 +176,11 @@ Globals
global ::= global 'MJ' // noncanonical specialized generic type metadata instantiation cache associated with global
global ::= global 'MN' // noncanonical specialized generic type metadata for global
+ #if SWIFT_RUNTIME_VERSION >= 5.4
+ global ::= context (decl-name '_')+ 'WZ' // global variable one-time initialization function
+ global ::= context (decl-name '_')+ 'Wz' // global variable one-time initialization token
+ #endif
+
A direct symbol resolves directly to the address of an object. An
indirect symbol resolves to the address of a pointer to the object.
They are distinct manglings to make a certain class of bugs
@@ -1107,3 +1112,40 @@ nominal type descriptor symbol for ``CxxStruct`` while compiling the ``main`` mo
.. code::
sSo9CxxStructVMn // -> nominal type descriptor for __C.CxxStruct
+
+Importing C++ class template instantiations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A class template instantiation is imported as a struct named
+``__CxxTemplateInst`` plus Itanium mangled type of the instantiation (see the
+``type`` production in the Itanium specification). Note that Itanium mangling is
+used on all platforms, regardless of the ABI of the C++ toolchain, to ensure
+that the mangled name is a valid Swift type name (this is not the case for MSVC
+mangled names). A prefix with a double underscore (to ensure we have a reserved
+C++ identifier) is added to limit the possibility for conflicts with names of
+user-defined structs. The struct is notionally defined in the ``__C`` module,
+similarly to regular C and C++ structs and classes. Consider the following C++
+module:
+
+.. code-block:: c++
+
+ template
+ struct MagicWrapper {
+ T t;
+ };
+
+ struct MagicNumber {};
+
+ typedef MagicWrapper WrappedMagicNumber;
+
+``WrappedMagicNumber`` is imported as a typealias for struct
+``__CxxTemplateInst12MagicWrapperI11MagicNumberE``. Interface of the imported
+module looks as follows:
+
+.. code-block:: swift
+
+ struct __CxxTemplateInst12MagicWrapperI11MagicNumberE {
+ var t: MagicNumber
+ }
+ struct MagicNumber {}
+ typealias WrappedMagicNumber = __CxxTemplateInst12MagicWrapperI11MagicNumberE
diff --git a/docs/Branches.md b/docs/Branches.md
index 083f89610419d..036849f9da2a1 100644
--- a/docs/Branches.md
+++ b/docs/Branches.md
@@ -18,11 +18,11 @@ To switch from one set of branches to another, you can use `utils/update-checkou
## The Release Branches
-| Swift | LLVM Project
-| ---------------- | ----------------------
-| swift-x.y-branch | swift/swift-x.y-branch
+| Swift | LLVM Project
+| ----------- | -----------------
+| release/x.y | swift/release/x.y
-At some point before a release, a *release branch* will be created in every repository with a name like `swift-4.0-branch`. (The actual number is chosen by Apple.) After the branch has been created, commits must make it to this branch to make it into the release. In some cases, the [release manager][] for the branch will decide to merge in all additional changes from `master`; otherwise, cherry-picking changes and making a new pull request is the way to go. If there are any "patch" releases (e.g. Swift 4.0.1), they will also come from this branch.
+At some point before a release, a *release branch* will be created in every repository with a name like `release/5.3`. (The actual number is chosen by Apple.) After the branch has been created, commits must make it to this branch to make it into the release. In some cases, the [release manager][] for the branch will decide to merge in all additional changes from `master`; otherwise, cherry-picking changes and making a new pull request is the way to go. If there are any "patch" releases (e.g. Swift 5.3.1), they will also come from this branch.
Note that these branches come not from the "development" branches (above), but the "upstream" branches (below). This is because they need to contain the latest changes not just from Swift, but from the LLVM project as well. For some releases, the release branch for the LLVM project will be timed to coincide with the corresponding llvm.org release branch.
@@ -35,7 +35,7 @@ Note that these branches come not from the "development" branches (above), but t
`swift/master-next` is a branch for LLVM that includes all changes necessary to support Swift. Changes from llvm.org's master branch are automatically merged in. Why isn't this just `swift/master`? Well, because LLVM changes *very* rapidly, and that wouldn't be very stable. However, we do want to make sure the Swift stuff keeps working.
-If you are making changes to LLVM to support Swift, you'll probably need to work on them in `swift/master` to test them against Swift itself, but they should be committed to `swift/master-next`, and cherry-picked to the current release branch (`swift/swift-x.y-branch`) if needed. Remember, the release branches are automerged into `swift/master` on a regular basis.
+If you are making changes to LLVM to support Swift, you'll probably need to work on them in `swift/master` to test them against Swift itself, but they should be committed to `swift/master-next`, and cherry-picked to the current release branch (`swift/release/x.y`) if needed. Remember, the release branches are automerged into `swift/master` on a regular basis.
(If you're making changes to LLVM Project that *aren't* about Swift, they should generally be made on llvm.org instead, then cherry-picked to the active release branch or `swift/master`.)
@@ -83,6 +83,6 @@ Some branches are *automerged* into other branches, to keep them in sync. This i
- `master` is automerged into `master-next`
### LLVM Project
-- `swift/swift-x.y-branch` (the *latest* release branch) is automerged into `swift/master`
+- `swift/release/x.y` (the *latest* release branch) is automerged into `swift/master`
- llvm.org's `master` is automerged into `swift/master-next`
-- llvm.org's release branch *may* be automerged into `swift/swift-x.y-branch`, if they are in sync
+- llvm.org's release branch *may* be automerged into `swift/release/x.y`, if they are in sync
diff --git a/docs/CppInteroperabilityManifesto.md b/docs/CppInteroperabilityManifesto.md
index f3a8df51820d2..b23c914268c1b 100644
--- a/docs/CppInteroperabilityManifesto.md
+++ b/docs/CppInteroperabilityManifesto.md
@@ -67,6 +67,7 @@ Assumptions:
+ [Function templates: calls with generic type parameters](#function-templates-calls-with-generic-type-parameters)
+ [Function templates: importing as real generic functions](#function-templates-importing-as-real-generic-functions)
+ [Class templates](#class-templates)
+ + [Class templates: importing instantiation behind typedef](#class-templates-importing-instantiation-behind-typedef)
+ [Class templates: importing specific specilalizations](#class-templates-importing-specific-specilalizations)
+ [Class templates: using with generic type parameters](#class-templates-using-with-generic-type-parameters)
+ [Class templates: using in generic code through a synthesized protocol](#class-templates-using-in-generic-code-through-a-synthesized-protocol)
@@ -2575,6 +2576,45 @@ We could ignore explicit specializations of function templates, because they
don't affect the API. Explicit specializations of class templates can
dramatically change the API of the type.
+### Class templates: Importing full class template instantiations
+
+A class template instantiation could be imported as a struct named
+`__CxxTemplateInst` plus Itanium mangled type of the instantiation (see the
+`type` production in the Itanium specification). Note that Itanium mangling is
+used on all platforms, regardless of the ABI of the C++ toolchain, to ensure
+that the mangled name is a valid Swift type name (this is not the case for MSVC
+mangled names). A prefix with a double underscore (to ensure we have a reserved
+C++ identifier) is added to limit the possibility for conflicts with names of
+user-defined structs. The struct is notionally defined in the `__C` module,
+similarly to regular C and C++ structs and classes. Consider the following C++
+module:
+
+```c++
+// C++ header.
+
+template
+struct MagicWrapper {
+ T t;
+};
+struct MagicNumber {};
+
+typedef MagicWrapper WrappedMagicNumber;
+```
+
+`WrappedMagicNumber` will be imported as a typealias for a struct
+`__CxxTemplateInst12MagicWrapperI11MagicNumberE`. Interface of the imported
+module will look as follows:
+
+```swift
+// C++ header imported to Swift.
+
+struct __CxxTemplateInst12MagicWrapperI11MagicNumberE {
+ var t: MagicNumber
+}
+struct MagicNumber {}
+typealias WrappedMagicNumber = __CxxTemplateInst12MagicWrapperI11MagicNumberE
+```
+
### Class templates: importing specific specilalizations
Just like with calls to C++ function templates, it is easy to compile a use of a
@@ -2752,7 +2792,7 @@ func useConcrete() {
### Class templates: importing as real generic structs
-If we know the complete set of allowed type arguments to a C++ function
+If we know the complete set of allowed type arguments to a C++ struct
template, we could import it as an actual Swift generic struct. Every method of
that struct will perform dynamic dispatch based on type parameters. See
the section about function templates for more details.
diff --git a/docs/DynamicCasting.md b/docs/DynamicCasting.md
new file mode 100644
index 0000000000000..0efc4fcb862b8
--- /dev/null
+++ b/docs/DynamicCasting.md
@@ -0,0 +1,729 @@
+# Dynamic Casting Behavior
+
+* Author: [Tim Kientzle](https://github.com/tbkka)
+* Implementation: [apple/swift#29658](https://github.com/apple/swift/pull/29658)
+
+## Introduction
+
+The Swift language has three casting operators: `is`, `as?`, and `as!`.
+Each one takes an instance on the left-hand side and a type expression on the right-hand side.
+
+* The _cast test operator_ `is` tests whether a particular instance can be converted to a particular destination type. It returns a boolean result.
+
+* The _conditional cast operator_ `as?` attempts the conversion and returns an `Optional` result: `nil` if the conversion failed, and a non-nil optional containing the result otherwise.
+
+* The _forced cast operator_ `as!` unconditionally performs the casting conversion and returns the result. If an `as!` expression does not succeed, the implementation may terminate the program.
+
+Note: The static coercion operator `as` serves a different role and its behavior will not be specifically discussed in this document.
+
+The following invariants relate the three casting operators:
+* Cast test: `x is T == ((x as? T) != nil)`
+* Conditional cast: `(x as? T) == (x is T) ? .some(x as! T) : nil`
+* Forced cast: `x as! T` is equivalent to `(x as? T)!`
+
+In particular, note that `is` and `as!` can be implemented in terms of `as?` and vice-versa.
+
+As with other operators with `!` in their names, `as!` is intended to only be invoked in cases where the programmer knows a priori that the cast will succeed.
+If the conversion would not succeed, then the behavior may not be fully deterministic.
+See the discussion of Array casting below for a specific case where this non-determinism can be important.
+
+The following sections detail the rules that govern the casting operations for particular Swift types.
+Except where noted, casting between types described in different sections below will always fail -- for example, casting a struct instance to a function type or vice-versa.
+
+Where possible, each section includes machine-verifiable _invariants_ that can be used as the basis for developing a robust test suite for this functionality.
+
+## Identity Cast
+
+Casting an instance of a type to its own type will always succeed and return the original value unchanged.
+
+```
+let a: Int = 7
+a is Int // true
+a as? Int // Succeeds
+a as! Int == a // true
+```
+
+## Class and Foreign Types
+
+Class types generally follow standard object-oriented casting conventions.
+Objective-C and CoreFoundation (CF) types follow the behaviors expected from Objective-C.
+
+### Classes
+
+Casting among class types follows standard object-oriented programming conventions:
+
+* Class upcasts: If `C` is a subclass of `SuperC` and `c` is an instance of `C`, then `c is SuperC == true` and `(c as? SuperC) != nil`. (Note: These "upcasts" do not change the in-memory representation.) However, when `c` is accessed via a variable or expression of type `SuperC`, only methods and instance variables defined on `SuperC` are available.
+
+* Class downcasts: If `C` is a subclass of `SuperC` and `sc` is an instance of `SuperC`, then `sc is C` will be true iff `sc` is actually an instance of `C`. (Note: Again, a downcast does not affect the in-memory representation.)
+
+* Objective-C class casting: The rules above also apply when one of the classes in question is defined with the `@objc` attribute or inherits from an Objective-C class.
+
+* Class casts to AnyObject: Any class reference can be cast to `AnyObject` and then cast back to the original type. See "AnyObject" below.
+
+* If a struct or enum type conforms to `_ObjectiveCBridgeable`, then classes of the associated bridging type can be cast to the struct or enum type and vice versa. See "The `_ObjectiveCBridgeable` Protocol" below.
+
+Invariants:
+* For any two class types `C1` and `C2`: `c is C1 && c is C2` iff `((c as? C1) as? C2) != nil`
+* For any class type `C`: `c is C` iff `(c as! AnyObject) is C`
+* For any class type `C`: if `c is C`, then `(c as! AnyObject) as! C === c`
+
+### CoreFoundation types
+
+* If `CF` is a CoreFoundation type, `cf` is an instance of `CF`, and `NS` is the corresponding Objective-C type, then `cf is NS == true`
+* Further, since every Objective-C type inherits from `NSObject`, `cf is NSObject == true`
+* In the above situation, if `T` is some other type and `cf is NS == true`, then `cf as! NS is T` iff `cf is T`.
+
+The intention of the above is to treat instances of CoreFoundation types as being simultaneously instances of the corresponding Objective-C type, in keeping with the general dual nature of these types.
+In particular, if a protocol conformance is declared on the Objective-C type, then instances of the CoreFoundation type can be cast to the protocol type directly.
+
+XXX TODO: Converse? If ObjC instance has CF equivalent and CF type is extended, ... ??
+
+### Objective-C types
+
+The following discussion applies in three different cases:
+* _Explicit_ conversions from use of the `is`, `as?`, and `as!` operators.
+* _Implicit_ conversions from Swift to Objective-C: These conversions are generated automatically when Swift code calls an Objective-C function or method with an argument that is not already of an Objective-C type, or when a Swift function returns a value to an Objective-C caller.
+* _Implicit_ conversions from Objective-C to Swift: These are generated automatically when arguments are passed from an Objective-C caller to a Swift function, or when an Objective-C function returns a value to a Swift caller.
+Unless stated otherwise, all of the following cases apply equally to all three of the above cases.
+
+Explicit casts among Swift and Objective-C class types follow the same general rules described earlier for class types in general.
+Likewise, explicitly casting a class instance to an Objective-C protocol type follows the general rules for casts to protocol types.
+
+XXX TODO EXPLAIN Implicit conversions from Objective-C types to Swift types XXXX.
+
+CoreFoundation types can be explicitly cast to and from their corresponding Objective-C types as described above.
+
+Objective-C types and protocols
+* `T` is an Objective-C class type iff `T.self is NSObject.Type`
+* `P` is an Objective-C protocol iff XXX TODO XXX
+
+### The `_ObjectiveCBridgeable` Protocol
+
+The `_ObjectiveCBridgeable` protocol allows certain types to opt into custom casting behavior.
+Note that although this mechanism was explicitly designed to simplify Swift interoperability with Objective-C, it is not necessarily tied to Objective-C.
+
+The `_ObjectiveCBridgeable` protocol defines an associated reference type `_ObjectiveCType`, along with a collection of methods that support casting to and from the associated `_ObjectiveCType`.
+This protocol allows library code to provide tailored mechanisms for casting Swift types to reference types.
+When casting to `AnyObject`, the casting logic prefers this tailored mechanism to the general `_SwiftValue` container mentioned above.
+
+Note: The associated `_ObjectiveCType` is constrained to be a subtype of `AnyObject`; it is not limited to being an actual Objective-C type.
+In particular, this mechanism is equally available to the Swift implementation of Foundation on non-Apple platforms and the Objective-C Foundation on Apple platforms.
+
+Example #1: Foundation extends the `Array` type in the standard library with an `_ObjectiveCBridgeable` conformance to `NSArray`. This allows Swift arrays to be cast to and from Foundation `NSArray` instances.
+```
+let a = [1, 2, 3] // Array
+let b = a as? AnyObject // casts to NSArray
+```
+
+Example #2: Foundation also extends each Swift numeric type with an `_ObjectiveCBridgeable` conformance to `NSNumber`.
+```
+let a = 1 // Int
+// After the next line, b is an Optional
+// holding a reference to an NSNumber
+let b = a as? AnyObject
+// NSNumber is bridgeable to Double
+let c = b as? Double
+```
+
+## Other Concrete Types
+
+In addition to the class types described earlier, Swift has several other kinds of concrete types.
+
+Casting between the different kinds described below (such as casting an enum to a tuple) will always fail.
+
+### Structs and Enums
+
+You cannot cast between different concrete struct or enum types.
+More formally:
+
+* If `S` and `T` are struct or enum types and `s is S == true`, then `s is T` iff `S.self == T.self`.
+
+Struct or enum types can be cast to class types if the struct or enum implements the `_ObjectiveCBridgeable` protocol as described earlier.
+
+### Optionals
+
+Casting to and from optional types will transparently unwrap optionals as much as necessary, including nested optional types.
+
+* If `T` and `U` are any two types, and `t` is an instance of `T`, then `.some(t) is Optional == t is U`
+* Optional injection: if `T` and `U` are any two types, `t` is a non-nil instance of `T`, then `t is Optional == t is U`
+* Optional projection: if `T` and `U` are any two types, and `t` is an instance of `T`, then `.some(t) is U == t is U`
+* Nil Casting: if `T` and `U` are any two types, then `Optional.none is Optional == true`
+
+Note: For "Optional Injection" above, the requirement that `t` is a non-nil instance of `T` implies that either `T` is not an `Optional` or that `T` is `Optional` and `t` has the form `.some(u)`
+
+Examples
+```
+// T and U are any two distinct types (possibly optional)
+// NO is any non-optional type
+let t: T
+let u: U
+let no: NO
+// Casting freely adds/removes optional wrappers
+t is Optional == true
+t is Optional> == true
+Optional.some(t) is T == true
+Optional>.some(.some(t)) is T == true
+// Non-optionals cast to optionals iff they cast to the inner type
+no is Optional == no is U
+Optional.some(no) is Optional == no is U
+// Non-nil optionals cast to a different type iff the inner value does
+Optional.some(t) is U == t is U
+Optional>.some(.some(t)) is U == t is U
+// Nil optionals always cast to other optional types
+Optional.none is Optional == true
+// Nil optionals never cast to non-optionals
+Optional.none is NO == false
+```
+
+Depth Preservation:
+The rules above imply that nested optionals are transparently unwrapped to arbitrary depth.
+For example, if an instance of `T` can be cast to type `U`, then `T????` can be cast to `U????`.
+This can be ambiguous if the former contains a `nil` value;
+casting the nil to `U????` might end up with any of the following distinct values `.none`, `.some(.none)`, `.some(.some(.none))`, or `.some(.some(.some(.none)))`.
+
+To resolve this ambiguity, the implementation should first inspect the type of the inner `.none` value and count the optional depth.
+Note that "optional depth" here refers to the number of optional wrappers needed to get from the innermost non-optional type to the type of the `.none`.
+
+1. If the target allows it, the value should inject into the target with the same optional depth as the source.
+2. Otherwise, the value should inject with the greatest optional depth possible.
+
+Examples
+```
+// Depth preservation
+// The `.none` here has type `T?` with optional depth 1
+let t1: T???? = .some(.some(.some(.none)))
+// This `.none` has type `T????` with optional depth 4
+let t4: T???? = .none
+// Result has optional depth 1, matching source
+t1 as! U???? // Produces .some(.some(.some(.none)))
+t1 as! U??? // Produces .some(.some(.none))
+t1 as! U?? // Produces .some(.none)
+t1 as! U? // Produces .none
+// Result has optional depth 2, because 4 is not possible
+t4 as! U?? // Produces .none
+// Remember that `as?` adds a layer of optional
+// These casts succeed, hence the outer `.some`
+t1 as? U???? // Produces .some(.some(.some(.some(.none))))
+t1 as? U??? // Produces .some(.some(.some(.none)))
+t1 as? U?? // Produces .some(.some(.none))
+t1 as? U? // Produces .some(.none)
+t4 as? U?? // Produces .some(.none)
+```
+
+### Array/Set/Dictionary Casts
+
+For Array, Set, or Dictionary types, you can use the casting operators to translate to another instance of the same outer container (Array, Set, or Dictionary respectively) with a different component type.
+Note that the following discussion applies only to these specific types.
+It does not apply to any other types, nor is there any mechanism to add this behavior to other types.
+
+Example: Given an `arr` of type `Array`, you can cast `arr as? Array`.
+The result will be a new array where each `Int` in the original array has been individually cast to an `Any`.
+
+However, if any component item cannot be cast, then the outer cast will also fail.
+For example, consider the following:
+```
+let a: Array = [Int(7), "string"]
+a as? Array // Fails because "string" cannot be cast to `Int`
+```
+
+Specifically, the casting operator acts for `Array` as if it were implemented as follows.
+In particular, note that an empty array can be successfully cast to any destination array type.
+```
+func arrayCast(source: Array) -> Optional> {
+ var result = Array()
+ for t in source {
+ if let u = t as? U {
+ result.append(u)
+ } else {
+ return nil
+ }
+ }
+ return result
+}
+```
+
+Invariants
+* Arrays cast iff their contents do: If `t` is an instance of `T` and `U` is any type, then `t is U == [t] is [U]`
+* Empty arrays always cast: If `T` and `U` are any types, `Array() is Array`
+
+Similar logic applies to `Set` and `Dictionary` casts.
+Note that the resulting `Set` or `Dictionary` may have fewer items than the original if the component casting operation converts non-equal items in the source into equal items in the destination.
+
+Specifically, the casting operator acts on `Set` and `Dictionary` as if by the following code:
+```
+func setCast(source: Set) -> Optional> {
+ var result = Set()
+ for t in source {
+ if let u = t as? U {
+ result.append(u)
+ } else {
+ return nil
+ }
+ }
+ return result
+}
+
+func dictionaryCast(source: Dictionary) -> Optional> {
+ var result = Dictionary()
+ for (k,v) in source {
+ if let k2 = k as? K2, v2 = v as? V2 {
+ result[k2] = v2
+ } else {
+ return nil
+ }
+ }
+ return result
+}
+```
+
+#### Collection Casting performance and `as!`
+
+For `as?` casts, the casting behavior above requires that every element be converted separately.
+This can be a particular bottleneck when trying to share large containers between Swift and Objective-C code.
+
+However, for `as!` casts, it is the programmer's responsibility to guarantee that the operation will succeed before requesting the conversion.
+The implementation is allowed (but not required) to exploit this by deferring the inner component casts until the relevant item is needed.
+Such lazy conversion can provide a significant performance improvement in cases where the data is known (by the programmer) to be safe and where the inner component casts are non-trivial.
+However, if the conversion cannot be completed, it is indeterminate whether the cast request will fail immediately or whether the program will fail at some later point.
+
+### Tuples
+
+Casting from a tuple type T1 to a tuple type T2 will succeed iff the following hold:
+* T1 and T2 have the same number of elements
+* If an element has a label in both T1 and T2, the labels are identical
+* Each element of T1 can be individually cast to the corresponding type of T2
+
+### Functions
+
+Casting from a function type F1 to a function type F2 will succeed iff the following hold:
+* The two types have the same number of arguments
+* Corresponding arguments have identical types
+* The return types are identical
+* If F1 is a throwing function type, then F2 must be a throwing function type. If F1 is not throwing, then F2 may be a throwing or non-throwing function type.
+
+Note that it is _not_ sufficient for argument and return types to be castable; they must actually be identical.
+
+## Existential Types
+
+Conceptually, an "existential type" is an opaque wrapper that carries a type and an instance of that type.
+The various existential types differ in what kinds of types they can hold (for example, `AnyObject` can only hold reference types) and in the capabilities exposed by the container (`AnyHashable` exposes equality testing and hashing).
+
+The key invariant for existential types `E` is the following:
+* Strong existential invariant: If `t` is any instance, `U` is any type, and `t is E` then `(t as! E) as? U` produces the same result as `t as? U`
+
+Intuitively, this simply says that if you can put an instance `t` into an existential `E`, then you can take it back out again via casting.
+For Equatable types, this implies that the results of the two operations here are equal to each other when they succeed.
+It also implies that if either of these `as?` casts fails, so will the other.
+
+`AnyObject` and `AnyHashable` do not fully satisfy the strong invariant described above. Instead, they satisfy the following weaker version:
+* Weak existential invariant: If `t` is any instance, `U` is any type, and both `t is U` and `t is E`, then `(t as! E) as? U` produces the same result as `t as? U`
+
+### Objective-C Interactions
+
+The difference between the strong and weak existential invariants comes about because casting to `AnyObject` or `AnyHashable` can trigger Objective-C bridging conversions.
+The result of these conversions may support casts that the original type did not.
+As a result, `(t as! E)` may be castable to `U` even if `t` alone is not directly castable.
+
+One example of this is Foundation's `NSNumber` type which conditionally bridges to several Swift numeric types.
+As a result, when Foundation is in scope, `Int(7) is Double == false` but `(Int(7) as! AnyObject) is Double == true`.
+In general, the ability to add new bridging behaviors from a single type to several distinct types implies that Swift casting cannot be transitive.
+
+### Any
+
+Any Swift instance can be cast to the type `Any`.
+An instance of `Any` has no useful methods or properties; to utilize the contents, you must cast it to another type.
+Every type identifier is an instance of the metatype `Any.Type`.
+
+Invariants
+* If `t` is any instance, then `t is Any == true`
+* If `t` is any instance, `t as! Any` always succeeds
+* For every type `T` (including protocol types), `T.self is Any.Type`
+* Strong existential invariant: If `t` is any instance and `U` is any type, then `(t as! Any) as? U` produces the same result as `t as? U`.
+
+### AnyObject
+
+Any class, enum, struct, tuple, function, metatype, or existential metatype instance can be cast to `AnyObject`.
+
+XXX TODO The runtime logic has code to cast protocol types to `AnyObject` only if they are compatible with `__SwiftValue`. What is the practical effect of this logic? Does it mean that casting a protocol type to `AnyObject` will sometimes unwrap (if the protocol is incompatible) and sometimes not? What protocols are affected by this?
+
+The contents of an `AnyObject` container can be accessed by casting to another type:
+* Weak existential invariant: If `t` is any instance, `U` is any type, `t is AnyObject`, and `t is U`, then `(t as! AnyObject) as? U` will produce the same result as `t as? U`
+
+Implementation Note: `AnyObject` is represented in memory as a pointer to a refcounted object. The dynamic type of the object can be recovered from the "isa" field of the object. The optional form `AnyObject?` is the same except that it allows null. Reference types (class, metatype, or existential metatype instances) can be directly assigned to an `AnyObject` without any conversion. For non-reference types -- including struct, enum, and tuple types -- the casting logic will first look for an `_ObjectiveCBridgeable` conformance that it can use to convert the source into a tailored reference type. If that fails, the value will be copied into an opaque `_SwiftValue` container.
+
+(See "The _ObjectiveCBridgeable Protocol" below for more details.)
+
+### Error (SE-0112)
+
+The `Error` type behaves like an ordinary existential type for casting purposes.
+
+(See "Note: 'Self-conforming' protocols" below for additional details relevant to the `Error` protocol.)
+
+### AnyHashable (SE-0131)
+
+For casting purposes, `AnyHashable` behaves like an existential type.
+It satisfies the weak existential invariant above.
+
+However, note that `AnyHashable` does not act like an existential for other purposes.
+For example, it's metatype is named `AnyHashable.Type` and it does not have an existential metatype.
+
+### Protocol Witness types
+
+Any protocol definition (except those that include an `associatedtype` property or which makes use of the `Self` typealias) has an associated existential type named after the protocol.
+
+Specifically, assume you have a protocol definition
+```
+protocol P {}
+```
+
+As a result of this definition, there is an existential type (also called `P`).
+This existential type is also known as a "protocol witness type" since it exposes exactly the capabilities that are defined by the protocol.
+Other capabilities of the type `T` are not accessible from a `P` instance.
+Any Swift instance of a concrete type `T` can be cast to the type `P` iff `T` conforms to the protocol `P`.
+
+The contents of a protocol witness can be accessed by casting to some other appropriate type:
+* Strong existential Invariant: For any protocol `P`, instance `t`, and type `U`, if `t is P`, then `t as? U` produces the same result as `(t as! P) as? U`
+
+In addition to the protocol witness type `P`, every Swift protocol `P` implicitly defines two other types:
+`P.Protocol` is the "protocol metatype", the type of `P.self`.
+`P.Type` is the "protocol existential metatype".
+These are described in more detail below.
+
+Regarding Protocol casts and Optionals
+
+When casting an Optional to a protocol type, the optional is preserved if possible.
+Given an instance `o` of type `Optional` and a protocol `P`, the cast request `o as? P` will produce different results depending on whether `Optional` directly conforms to `P`:
+
+* If `Optional` conforms to `P`, then the result will be a protocol witness wrapping the `o` instance. In this case, a subsequent cast to `Optional` will restore the original instance. In particular, this case will preserve `nil` instances.
+
+* If `Optional` does not directly conform, then `o` will be unwrapped and the cast will be attempted with the contained object. If `o == nil`, this will fail. In the case of a nested optional `T???` this will result in fully unwrapping the inner non-optional.
+
+* If all of the above fail, then the cast will fail.
+
+For example, `Optional` conforms to `CustomDebugStringConvertible` but not to `CustomStringConvertible`.
+Casting an optional instance to the first of these protocols will result in an item whose `.debugDescription` will describe the optional instance.
+Casting an optional instance to the second will provide an instance whose `.description` property describes the inner non-Optional instance.
+
+## Metatypes
+
+Swift supports two kinds of metatypes:
+In addition to the regular metatypes supported by many other languages, it also has _existential_ metatypes that can be used to access static protocol requirements.
+
+### Metatypes
+
+For every type `T`, there is a unique instance `T.self` that represents the type at runtime.
+As with all instances, `T.self` has a type.
+We call this type the "metatype of `T`".
+Technically, static variables or methods of a type belong to the `T.self` instance and are defined by the metatype of `T`:
+
+Example:
+```
+struct S {
+ let ivar = 2
+ static let svar = 1
+}
+S.ivar // Error: only available on an instance
+S().ivar // 2
+type(of: S()) == S.self
+S.self.svar // 1
+S.svar // Shorthand for S.self.svar
+```
+
+For most Swift types, the metatype of `T` is named `T.Type`.
+However, in the following cases the metatype has a different name:
+* For a nominal protocol type `P`, the metatype is named `P.Protocol`
+* For non-protocol existential types `E`, the metatype is also named `E.Protocol`. For example, `Any.Protocol`, `AnyObject.Protocol`, and `Error.Protocol`.
+* For a type bound to a generic variable `G`, the metatype is named `G.Type` _even if `G` is bound to a protocol or existential type_. Specifically, if `G` is bound to the nominal protocol type `P`, then `G.Type` is another name for the metatype `P.Protocol`, and hence `G.Type.self == P.Protocol.self`.
+* As explained above, although `AnyHashable` behaves like an existential type in some respects, its metatype is called `AnyHashable.Type`.
+
+Example:
+```
+// Metatype of a struct type
+struct S: P {}
+S.self is S.Type // always true
+S.Type.self is S.Type.Type // always true
+let s = S()
+type(of: s) == S.self // always true
+type(of: S.self) == S.Type.self
+
+// Metatype of a protocol (or other existential) type
+protocol P {}
+P.self is P.Protocol // always true
+// P.Protocol is a metatype, not a protocol, so:
+P.Protocol.self is P.Protocol.Type // always true
+let p = s as! P
+type(of: p) == P.self // always true
+
+// Metatype for a type bound to a generic type variable
+f(s) // Bind G to S
+f(p) // Bind G to P
+func f(_ g: G) {
+ G.self is G.Type // always true
+}
+```
+
+Invariants
+* For a nominal non-protocol type `T`, `T.self is T.Type`
+* For a nominal protocol type `P`, `P.self is P.Protocol`
+* `P.Protocol` is a singleton: `T.self is P.Protocol` iff `T` is exactly `P`
+* A non-protocol type `T` conforms to a protocol `P` iff `T.self is P.Type` (If `T` is a protocol type, see "Self conforming existential types" below for details.)
+* `T` is a subtype of a non-protocol type `U` iff `T.self is U.Type`
+* Subtypes define metatype subtypes: if `T` and `U` are non-protocol types, `T.self is U.Type == T.Type.self is U.Type.Type`
+* Subtypes define metatype subtypes: if `T` is a non-protocol type and `P` is a protocol type, `T.self is P.Protocol == T.Type.self is P.Protocol.Type`
+
+### Existential Metatypes
+
+Protocols can specify constraints and provide default implementations for instances of types.
+They can also specify constraints and provide default implementations for static members of types.
+As described above, casting a regular instance of a type to a protocol type produces a protocol witness instance that exposes only those features required or provided by the protocol.
+Similarly, a type identifier instance (`T.self`) can be cast to a protocol's "existential metatype" to expose just the parts of the type corresponding to the protocol's static requirements.
+
+The existential metatype of a protocol `P` is called `P.Type`.
+(Recall that for a non-protocol type `T`, the expression `T.Type` refers to the regular metatype.
+Non-protocol types do not have existential metatypes.
+For a generic variable `G`, the expression also refers to the regular metatype, even if the generic variable is bound to a protocol.
+There is no mechanism in Swift to refer to the existential metatype via a generic variable.)
+
+Example
+```
+protocol P {
+ var ivar: Int { get }
+ static svar: Int { get }
+}
+struct S: P {
+ let ivar = 1
+ static let svar = 2
+}
+S().ivar // 1
+S.self.svar // 2
+(S() as! P).ivar // 1
+(S.self as! P.Type).svar // 2
+```
+
+Invariants
+* If `T` conforms to `P` and `t` is an instance of `T`, then `t is P` and `T.self is P.Type`
+* If `P` is a sub-protocol of `P1` and `T` is any type, then `T.self is P.Type` implies that `T.self is P1.Type`
+* Since every type `T` conforms to `Any`, `T.self is Any.Type` is always true
+* Since every class type `C` conforms to `AnyObject`, `C.self is AnyObject.Type` is always true (this includes Objective-C class types)
+
+### Note: "Self conforming" existential types
+
+As mentioned above, a protocol definition for `P` implicitly defines types `P.Type` (the existential metatype) and `P.Protocol` (the metatype).
+It also defines an associated type called `P` which is the type of a container that can hold any object whose concrete type conforms to the protocol `P`.
+
+A protocol is "self conforming" if the container type `P` conforms to the protocol `P`.
+This is equivalent to saying that `P.self` is an instance of `P.Type`.
+(Remember that `P.self` is always an instance of `P.Protocol`.)
+
+This is a concern for Swift because of the following construct, which attempts to invoke a generic `f` in a situation where the concrete instance clearly conforms to `P` but is represented as a `P` existential:
+```
+func f(t: T) { .. use t .. }
+let a : P = something
+f(a)
+```
+This construct is valid only if `T` conforms to `P` when `T = P`; that is, if `P` self-conforms.
+
+A similar situation arises with generic types:
+```
+struct MyGenericType {
+ init(_ value: T) { ... }
+}
+let a : P
+let b : MyGenericType(a)
+```
+As above, since `a` has type `P`, this code is instantiating `MyGenericType` with `T = P`, which is only valid if `P` conforms to `P`.
+Note that any protocol that specifies static methods, static properties, associated types, or initializers cannot possibly be self-conforming.
+
+Although the discussion above specifically talks about protocols, it applies equally well to other existential types.
+As of Swift 5.3, the only self-conforming existential types are `Any`, `Error`, and Objective-C protocols that have no static requirements.
+
+Invariants
+* `Any` self-conforms: `Any.self is Any.Type == true`
+* `Error` self-conforms: `Error.self is Error.Type == true`
+* If `P` self-conforms and is a sub-protocol of `P1`, then `P.self is P1.Type == true`
+
+For example, the last invariant here implies that for any Objective-C protocol `OP` that has no static requirements, `OP.self is AnyObject.Type`. This follows from the fact that `OP` self-conforms and that every Objective-C protocol has `AnyObject` as an implicit parent protocol.
+
+## Implementation Notes
+
+Casting operators that appear in source code are translated into SIL in a variety of ways depending on the details of the types involved.
+One common path renders `as!` into some variant of the `unconditional_checked_cast` instruction and renders `as?` and `is` into a conditional branch instruction such as `checked_cast_br`.
+
+SIL optimization passes attempt to simplify these.
+In some cases, the result of the cast can be fully determined at compile time.
+In a few cases, the compiler can generate tailored code to perform the cast (for example, assigning a reference to an `AnyObject` variable).
+In other cases, the compiler can determine whether the cast will succeed without necessarily being able to compute the result.
+For example, casting a class reference to a superclass will always succeed, which may allow a `checked_cast_br` instruction to be simplified into a non-branching `unconditional_checked_cast`.
+Similarly, an `as?` cast that can be statically proven to always fail can be simplified into a constant `nil` value.
+Note that these SIL functions are also used for other purposes, including implicit bridging conversions when calling into Objective-C.
+This makes them common enough to be subject to some limited optimizations even in `-Onone` mode.
+
+When SIL is translated into LLVM IR, the remaining cast operations are rendered into calls to appropriate runtime functions.
+The most general such function is `swift_dynamicCast` which accepts a pointer to the input value, a location in which to store the result, and metadata describing the types involved.
+When possible, the compiler prefers to instead emit calls to specialized variants of this function with names like `swift_dynamicCastClass` and `swift_dynamicCastMetatypeToObject` (a full list is in the [Runtime Documentation](/docs/Runtime.md)).
+These specialized versions require fewer arguments and perform fewer internal checks, which makes them cheaper to use.
+
+The `swift_dynamicCast` function examines the input and output types to determine appropriate conversions.
+This process recurses on the input type to examine the contents of an existential container or `Optional`.
+If the output is an existential container or `Optional` type, it will also recurse on the output type to determine a suitable base conversion and then must configure the container appropriately for the contents.
+It may also perform additional metadata lookups to determine whether either type conforms to `Hashable`, `Error`, or `ObjectiveCBridgeable` protocols.
+For collections, this process may end up recursively attempting to convert each element.
+
+## Compared to Swift 5.3
+
+These are some of the ways in which Swift 5.3 differs from the behavior described above:
+
+* Casts for which the target type is "more Optional" than the static source type previously produced errors. This disallowed all of the following: injecting an `Int` into an `Int?`, extracting an `Int?` from an opaque `Any` container, and casting an `Array` to an `Array`. This document allows all of these.
+
+```
+let a = 7
+// Swift 5.3: error: cannot downcast to a more optional type
+// Specification: returns true
+a is Int?
+// Swift 5.3: error: cannot downcast to a more optional type
+// Specification: returns false
+a is Optional
+
+let b: Int? = 7
+let c: Any = b
+// Swift 5.3: error: cannot downcast to a more optional type
+// Specification: returns true
+c is Int?
+```
+
+* An instance of a CoreFoundation type could sometimes be cast to a protocol defined on the companion Obj-C type and sometimes not. To make the behavior consistent, we had to choose one; having such casts always succeed seems more consistent with the general dual nature of Obj-C/CF types.
+
+```
+import Foundation
+protocol P {}
+extension NSString: P {}
+let a = CFStringCreateWithCString(nil, "hello, world",
+ CFStringBuiltInEncodings.UTF8.rawValue)
+// Swift 5.3: prints "true"
+print(a is P)
+let b: Any = a
+// Swift 5.3: prints "false"
+// Specification: prints "true"
+print(b is P)
+```
+
+* The Swift 5.3 compiler asserts attempting to cast a struct to AnyObject
+
+```
+struct S {}
+let s = S()
+// Swift 5.3: Compiler crash (in asserts build)
+// Specification: Succeeds via _SwiftValue boxing
+s as? AnyObject
+```
+
+* `NSNumber()` does not cast to itself via `as?` in unoptimized builds
+
+```
+import Foundation
+let a = NSNumber()
+// true in 5.3 for optimized builds; false for unoptimized builds
+print((a as? NSNumber) != nil)
+```
+
+* `Optional` does not project
+
+```
+import Foundation
+let a: Optional = NSNumber()
+// Swift 5.3: false
+// Specification: true
+print(a is NSNumber)
+// Swift 5.3: nil
+// Specification: .some(NSNumber())
+print(a as? NSNumber)
+```
+
+* Casting `NSNumber()` to `Any` crashes at runtime
+
+```
+import Foundation
+let a = NSNumber()
+// Swift 5.3: Runtime crash (both optimized and unoptimized builds)
+// Specification: Succeeds
+print(a is Any)
+```
+
+* SR-2289: CF types cannot be cast to protocol existentials
+
+```
+import Foundation
+protocol P {}
+extension CFBitVector : P {
+ static func makeImmutable(from values: Array) -> CFBitVector {
+ return CFBitVectorCreate(nil, values, values.count * 8)
+ }
+}
+// Swift 5.3: Crashes in unoptimized build, prints true in optimized build
+// Specification: prints true
+print(CFBitVector.makeImmutable(from: [10,20]) is P)
+```
+
+* SR-4552: Cannot cast `Optional as Any` to protocol type. Note that this is a particular problem for reflection with weak fields, since `Mirror` reflects those as `Any` containing an `Optional` value.
+
+```
+protocol P {}
+class C: P {}
+let c: C? = C()
+let a = c as? Any
+// Swift 5.3: prints "false"
+// Specification: prints "true"
+print(a is P)
+```
+
+* SR-8964: `Any` containing `Optional` cannot cast to `Error`
+
+```
+struct MyError: Error { }
+let a: Any? = MyError()
+let b: Any = a
+// Swift 5.3: Prints false
+// Specification: prints true
+print(b is Error)
+```
+
+* SR-6126: Inconsistent results for nested optionals
+
+```
+// Note: SR-6126 includes many cases similar to the following
+let x: Int? = nil
+print(x as Int??) // ==> "Optional(nil)"
+// Swift 5.3: prints "nil"
+// Specification: should print "Optional(nil)" (same as above)
+print((x as? Int??)!)
+```
+
+* `Error.self` does not fully self-conform
+
+```
+// Swift 5.3: Prints "false"
+// Specification: prints "true"
+print(Error.self is Error.Type)
+```
+
+* Objective-C protocol metatypes do not fully self-conform
+
+```
+import Foundation
+let a = NSObjectProtocol.self
+print(a is NSObjectProtocol.Type)
+```
+
+* SR-1999: Cannot cast `Any` contents to a protocol type
+
+```
+protocol P {}
+class Foo: P {}
+let optionalFoo: Foo? = Foo()
+let any: Any = optionalFoo
+// Swift 5.3: Prints "false"
+// Specification: prints "true"
+print(any as? P)
+```
+
+* XXX TODO List others
diff --git a/docs/Lexicon.md b/docs/Lexicon.md
index 32e2d4acd8dfa..bc8ed1e9465d8 100644
--- a/docs/Lexicon.md
+++ b/docs/Lexicon.md
@@ -111,6 +111,11 @@ the AST level. See also [witness table](#witness-table).
context. This type may contain [archetypes](#archetype) and cannot be
used directly from outside the context. Compare with [interface type](#interface-type).
+## critical edge
+
+An edge in a control flow graph where the destination has multiple predecessors
+and the source has multiple successors.
+
## customization point
Informal term for a protocol requirement that has a default implementation,
diff --git a/docs/LibraryEvolution.rst b/docs/LibraryEvolution.rst
index e2813f4567fce..dac3495fe893a 100644
--- a/docs/LibraryEvolution.rst
+++ b/docs/LibraryEvolution.rst
@@ -578,7 +578,9 @@ There are very few safe changes to make to protocols and their members:
- The ``@discardableResult`` and ``@warn_unqualified_access`` attributes may
be added to or removed from a function requirement.
- A new ``associatedtype`` requirement may be added (with the appropriate
- availability), as long as it has a default implementation.
+ availability), as long as it has a default implementation. If the protocol
+ did not have one or more ``associatedtype`` requirements before the change,
+ then this is a `binary-compatible source-breaking change`.
- A new non-type requirement may be added (with the appropriate availability),
as long as it has an unconstrained default implementation. If the requirement
uses ``Self`` and the protocol has no other requirements using ``Self`` and
diff --git a/docs/Modules.rst b/docs/Modules.rst
index fbea23d6c8b4b..fbaa3864313c5 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -441,10 +441,6 @@ Glossary
__ https://en.wikipedia.org/wiki/Name_mangling#C.2B.2B
- module
- An entity containing the API for a library, to be `imported ` into
- a source file.
-
qualified name
A multi-piece name like ``Foundation.NSWindow``, which names an entity
within a particular context. This document is concerned with the case where
@@ -463,9 +459,3 @@ Glossary
SIL
"Swift Intermediate Language", a stable IR for the distribution of
inlineable code.
-
-
- target
- A dynamic library, framework, plug-in, or application to be built.
- A natural LTO boundary, and roughly the same as what Xcode requires
- separate targets to build.
diff --git a/docs/README.md b/docs/README.md
index b3e2c3f976d4d..d5b028f34b736 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -159,6 +159,8 @@ documentation, please create a thread on the Swift forums under the
Documents the Swift Intermediate Language (SIL).
- [TransparentAttr.md](/docs/TransparentAttr.md):
Documents the semantics of the `@_transparent` attribute.
+- [DynamicCasting.md](/docs/DynamicCasting.md):
+ Behavior of the dynamic casting operators `is`, `as?`, and `as!`.
- [Runtime.md](/docs/Runtime.md):
Describes the ABI interface to the Swift runtime.
diff --git a/docs/WebAssembly.md b/docs/WebAssembly.md
new file mode 100644
index 0000000000000..b8b730f813342
--- /dev/null
+++ b/docs/WebAssembly.md
@@ -0,0 +1,29 @@
+# WebAssembly support in Swift
+
+WebAssembly is a platform that significantly differs from hardware platforms that Swift already supports.
+While it's a virtual machine, there are considerations to be taken into account when targeting it:
+
+* WebAssembly is still at an early stage, so many features you'd be expect from other platforms are not
+available yet, specifically:
+ 1. `wasm64` variant is not specified yet, only the 32-bit `wasm32` variant is supported in WebAssembly
+ hosts such as browsers.
+ 2. While a preview of multi-threading and atomics is available in some browsers and stand-alone
+ WebAssembly hosts, [the corresponding proposal](https://github.com/WebAssembly/threads/) haven't
+ formally reached the implementation phase yet.
+ 3. Dynamic linking is not formally specified and tooling for it is not available yet.
+* Binary size is a high priority requirement. Since WebAssembly payloads are usually served in browsers,
+one wouldn't want end users to download multi-megabyte binaries.
+
+Nevertheless, an early implementation of the WebAssembly target is available [in a separate
+fork](https://github.com/SwiftWasm). Here we're describing some decisions that were made while developing
+the implementation.
+
+## Relative Pointers
+
+Relative pointers are used in Swift runtime, but currently it's not feasible to use them for the WebAssembly
+target due to the design of WebAssembly and lack of LLVM support. If LLVM supported subtraction relocation
+type on WebAssembly like `R_X86_64_PC32` or `X86_64_RELOC_SUBTRACTOR`, this issue can be solved easily.
+
+Since `R_X86_64_PC32` and `X86_64_RELOC_SUBTRACTOR` are mainly used to generate PIC but WebAssembly doesn't
+require PIC because it doesn't support dynamic linking. In addition, the memory space also begins at 0, so
+it's unnecessary to relocate at load time. All absolute addresses can be embedded in wasm binary file directly.
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 4260e19a78172..b66f30f0516cc 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -8,11 +8,10 @@ The commands below (with the exception of installing Visual Studio) must be ente
### Visual Studio
-An easy way to get most of the tools to build Swift is using the [Visual Studio installer](https://www.visualstudio.com/downloads/). This command installs all needed Visual Studio components as well as Python and Git:
+An easy way to get most of the tools to build Swift is using the [Visual Studio installer](https://www.visualstudio.com/downloads/). This command installs all needed Visual Studio components as well as Python, Git, CMake and Ninja:
```
vs_community ^
- --add Component.CPython2.x86 ^
--add Component.CPython3.x64 ^
--add Microsoft.VisualStudio.Component.Git ^
--add Microsoft.VisualStudio.Component.VC.ATL ^
@@ -28,13 +27,7 @@ The following [link](https://docs.microsoft.com/visualstudio/install/workload-co
### Python
-The command above already installs Python 2 and 3. Alternatively, in the Visual Studio installation program, under *Individual Components*
-
-1. Install *Python 2*, either the 32-bit version (C:\Python27\\) or the 64-bit version (C:\Python27amd64\\)
-
- **Note:** If you install the 64-bit version only, you will need to adjust `PYTHON_EXECUTABLE` below to `C:\Python27amd64\python.exe`
-
-2. Install *Python 3 64 bits (3.7.x)*
+The command above already installs Python 3. Alternatively, in the Visual Studio installation program, under *Individual Components*, install *Python 3 64 bits (3.7.x)*.
If you are building a debug version of Swift, you should also install the Python debug binaries.
@@ -69,9 +62,13 @@ git clone https://github.com/apple/swift-cmark cmark
git clone https://github.com/apple/swift-corelibs-libdispatch swift-corelibs-libdispatch
git clone https://github.com/apple/swift-corelibs-foundation swift-corelibs-foundation
git clone https://github.com/apple/swift-corelibs-xctest swift-corelibs-xctest
-git clone https://github.com/apple/swift-llbuild llbuild
git clone https://github.com/apple/swift-tools-support-core swift-tools-support-core
-git clone -c core.autocrlf=input https://github.com/apple/swift-package-manager swiftpm
+git clone -c core.symlinks=true https://github.com/apple/swift-llbuild swift-llbuild
+git clone https://github.com/JPSim/Yams Yams
+git clone https://github.com/apple/swift-driver swift-driver
+git clone https://github.com/apple/swift-argument-parser swift-argument-parser
+git clone -c core.autocrlf=input https://github.com/apple/swift-package-manager swift-package-manager
+git clone https://github.com/apple/indexstore-db indexstore-db
```
## Dependencies (ICU, SQLite3, curl, libxml2 and zlib)
@@ -119,119 +116,266 @@ Warning: Creating the above links usually requires administrator privileges. The
## Build the toolchain
```cmd
-cmake -B "S:\b\toolchain" ^
+cmake -B "S:\b\1" ^
-C S:\swift\cmake\caches\Windows-x86_64.cmake ^
-D CMAKE_BUILD_TYPE=Release ^
- -D SWIFT_PATH_TO_LIBDISPATCH_SOURCE=S:\swift-corelibs-libdispatch ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D LLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc ^
-D LLVM_ENABLE_PDB=YES ^
- -D LLVM_EXTERNAL_SWIFT_SOURCE_DIR=S:\swift ^
-D LLVM_EXTERNAL_CMARK_SOURCE_DIR=S:\cmark ^
- -D SWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE=S:\Library\icu-67\usr\include ^
- -D SWIFT_WINDOWS_x86_64_ICU_UC=S:\Library\icu-67\usr\lib\icuuc67.lib ^
+ -D LLVM_EXTERNAL_SWIFT_SOURCE_DIR=S:\swift ^
+ -D SWIFT_PATH_TO_LIBDISPATCH_SOURCE=S:\swift-corelibs-libdispatch ^
-D SWIFT_WINDOWS_x86_64_ICU_I18N_INCLUDE=S:\Library\icu-67\usr\include ^
-D SWIFT_WINDOWS_x86_64_ICU_I18N=S:\Library\icu-67\usr\lib\icuin67.lib ^
- -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D SWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE=S:\Library\icu-67\usr\include ^
+ -D SWIFT_WINDOWS_x86_64_ICU_UC=S:\Library\icu-67\usr\lib\icuuc67.lib ^
-G Ninja ^
-S S:\llvm-project\llvm
-ninja -C S:\b\toolchain
+ninja -C S:\b\1
```
-**Note:** If you installed only the 64-bit version of Python, you will need to adjust `PYTHON_EXECUTABLE` argument to `C:\Python27amd64\python.exe`
-
-
## Running Swift tests on Windows
```cmd
-path S:\Library\icu-67\usr\bin;S:\b\toolchain\bin;S:\b\toolchain\tools\swift\libdispatch-prefix\bin;%PATH%;%ProgramFiles%\Git\usr\bin
+path S:\Library\icu-67\usr\bin;S:\b\1\bin;S:\b\1\tools\swift\libdispatch-prefix\bin;%PATH%;%ProgramFiles%\Git\usr\bin
ninja -C S:\b\toolchain check-swift
```
## Build swift-corelibs-libdispatch
```cmd
-cmake -B S:\b\libdispatch -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_CXX_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D ENABLE_SWIFT=YES -G Ninja -S S:\swift-corelibs-libdispatch
-ninja -C S:\b\libdispatch
+cmake -B S:\b\2 ^
+ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_CXX_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D ENABLE_SWIFT=YES ^
+ -G Ninja ^
+ -S S:\swift-corelibs-libdispatch
+
+ninja -C S:\b\2
```
## Test swift-corelibs-libdispatch
```cmd
-ninja -C S:\b\libdispatch check
+ninja -C S:\b\2 check
```
## Build swift-corelibs-foundation
```cmd
-cmake -B S:\b\foundation -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" -D ICU_ROOT="S:/Library/icu-67" -D ICU_INCLUDE_DIR=S:/Library/icu-67/usr/include -D LIBXML2_LIBRARY="S:/Library/libxml2-development/usr/lib/libxml2s.lib" -D LIBXML2_INCLUDE_DIR="S:/Library/libxml2-development/usr/include/libxml2" -D ENABLE_TESTING=NO -D dispatch_DIR=S:/b/libdispatch/cmake/modules -G Ninja -S S:\swift-corelibs-foundation
-ninja -C S:\b\foundation
+cmake -B S:\b\3 ^
+ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" ^
+ -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" ^
+ -D ICU_I18N_LIBRARY_RELEASE=S:\library\icu-67\usr\lib\icuin67.lib ^
+ -D ICU_ROOT=S:\Library\icu-67\usr ^
+ -D ICU_UC_LIBRARY_RELEASE=S:\Library\icu-67\usr\lib\icuuc67.lib ^
+ -D LIBXML2_LIBRARY=S:\Library\libxml2-development\usr\lib\libxml2s.lib ^
+ -D LIBXML2_INCLUDE_DIR=S:\Library\libxml2-development\usr\include\libxml2 ^
+ -D ENABLE_TESTING=NO ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -G Ninja ^
+ -S S:\swift-corelibs-foundation
+
+ninja -C S:\b\3
```
- Add Foundation to your path:
```cmd
-path S:\b\foundation\Foundation;%PATH%
+path S:\b\3\bin;%PATH%
```
## Build swift-corelibs-xctest
```cmd
-cmake -B S:\b\xctest -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D dispatch_DIR=S:\b\dispatch\cmake\modules -D Foundation_DIR=S:\b\foundation\cmake\modules -D LIT_COMMAND=S:\toolchain\llvm\utils\lit\lit.py -D PYTHON_EXECUTABLE=C:\Python27\python.exe -G Ninja -S S:\swift-corelibs-xctest
-ninja -C S:\b\xctest
+cmake -B S:\b\4 ^
+ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D LIT_COMMAND=S:\llvm-project\llvm\utils\lit\lit.py ^
+ -G Ninja ^
+ -S S:\swift-corelibs-xctest
+
+ninja -C S:\b\4
```
- Add XCTest to your path:
```cmd
-path S:\b\xctest;%PATH%
+
+path S:\b\4;%PATH%
```
## Test XCTest
```cmd
-ninja -C S:\b\xctest check-xctest
+ninja -C S:\b\4 check-xctest
```
## Rebuild Foundation
```cmd
-cmake -B S:\b\foundation -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" -D ICU_ROOT="S:/Library/icu-67" -D LIBXML2_LIBRARY="S:/Library/libxml2-development/usr/lib/libxml2.lib" -D LIBXML2_INCLUDE_DIR="S:/Library/libxml2-development/usr/include" -D ENABLE_TESTING=YES -D dispatch_DIR=S:/b/libdispatch/cmake/modules -D XCTest_DIR=S:/b/xctest/cmake/modules -G Ninja -S S:\swift-corelibs-foundation
-ninja -C S:\b\foundation
+cmake -B S:\b\3 ^
+ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" ^
+ -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" ^
+ -D ICU_I18N_LIBRARY_RELEASE=S:\library\icu-67\usr\lib\icuin67.lib ^
+ -D ICU_ROOT=S:\Library\icu-67\usr ^
+ -D ICU_UC_LIBRARY_RELEASE=S:\Library\icu-67\usr\lib\icuuc67.lib ^
+ -D LIBXML2_LIBRARY=S:\Library\libxml2-development\usr\lib\libxml2s.lib ^
+ -D LIBXML2_INCLUDE_DIR=S:\Library\libxml2-development\usr\include\libxml2 ^
+ -D ENABLE_TESTING=YES ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D XCTest_DIR=S:\b\4\cmake\modules ^
+ -G Ninja ^
+ -S S:\swift-corelibs-foundation
+
+ninja -C S:\b\3
```
## Test Foundation
```cmd
-cmake --build S:\b\foundation
-ninja -C S:\b\foundation test
+ninja -C S:\b\3 test
```
-## Build llbuild
+## Build swift-tools-core-support
```cmd
-set AR=llvm-ar
-cmake -B S:\b\llbuild -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_CXX_COMPILER=cl -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D Foundation_DIR=S:/b/foundation/cmake/modules -D dispatch_DIR=S:/b/libdispatch/cmake/modules -D SQLite3_INCLUDE_DIR=S:\Library\sqlite-3.28.0\usr\include -D SQLite3_LIBRARY=S:\Library\sqlite-3.28.0\usr\lib\sqlite3.lib -D LLBUILD_SUPPORT_BINDINGS=Swift -G Ninja -S S:\llbuild
-ninja -C S:\b\llbuild
+cmake -B S:\b\5 ^
+ -D BUILD_SHARED_LIBS=YES ^
+ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D SQLite3_INCLUDE_DIR=S:\Library\sqlite-3.28.0\usr\include ^
+ -D SQLite3_LIBRARY=S:\Library\sqlite-3.28.0\usr\lib\SQLite3.lib ^
+ -G Ninja ^
+ -S S:\swift-tools-support-core
+
+ninja -C S:\b\5
+```
+
+## Build swift-llbuild
+
+```cmd
+cmake -B S:\b\6 ^
+ -D BUILD_SHARED_LIBS=YES ^
+ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_CXX_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D CMAKE_CXX_FLAGS="-Xclang -fno-split-cold-code" ^
+ -D LLBUILD_SUPPORT_BINDINGS=Swift ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D SQLite3_INCLUDE_DIR=S:\Library\sqlite-3.28.0\usr\include ^
+ -D SQLite3_LIBRARY=S:\Library\sqlite-3.28.0\usr\lib\sqlite3.lib ^
+ -G Ninja ^
+ -S S:\swift-llbuild
+
+ninja -C S:\b\6
```
- Add llbuild to your path:
```cmd
-path S:\b\llbuild\bin;%PATH%
+path S:\b\6\bin;%PATH%
```
-## Build swift-tools-core-support
+## Build Yams
```cmd
-cmake -B S:\b\tsc -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=cl -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D Foundation_DIR=S:/b/foundation/cmake/modules -D dispatch_DIR=S:/b/libdispatch/cmake/modules -G Ninja -S S:\swift-tools-support-core
-ninja -C S:\b\tsc
+cmake -B S:\b\7 ^
+ -D BUILD_SHARED_LIBS=YES ^
+ -D CMAKE_BUILD_TYPE=Release ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D XCTest_DIR=S:\b\4\cmake\modules ^
+ -G Ninja ^
+ -S S:\swift-llbuild
+
+ninja -C S:\b\7
+```
+
+## Build swift-driver
+
+```cmd
+cmake -B S:\b\8 ^
+ -D BUILD_SHARED_LIBS=YES ^
+ -D CMAKE_BUILD_TYPE=Release ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D TSC_DIR=S:\b\5\cmake\modules ^
+ -D LLBuild_DIR=S:\b\6\cmake\modules ^
+ -D Yams_DIR=S:\b\7\cmake\modules ^
+ -G Ninja ^
+ -S S:\swift-driver
+
+ninja -C S:\b\8
+```
+
+## Build swift-argument-parser
+
+```cmd
+cmake -B S:\b\9 ^
+ -D BUILD_SHARED_LIBS=YES ^
+ -D CMAKE_BUILD_TYPE=Release ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D XCTest_DIR=S:\b\4\cmake\modules ^
+ -G Ninja ^
+ -S S:\swift-argument-parser
+
+ninja -C S:\b\9
```
## Build swift-package-manager
```cmd
-cmake -B S:\b\spm -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_CXX_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D USE_VENDORED_TSC=YES -D Foundation_DIR=S:/b/foundation/cmake/modules -D dispatch_DIR=S:/b/libdispatch/cmake/modules -D LLBuild_DIR=S:/b/llbuild/cmake/modules -G Ninja -S S:\swiftpm
-ninja -C S:\b\spm
+cmake -B S:\b\10 ^
+ -D BUILD_SHARED_LIBS=YES ^
+ -D CMAKE_BUILD_TYPE=Release ^
+ -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+ -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+ -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+ -D dispatch_DIR=S:\b\2\cmake\modules ^
+ -D Foundation_DIR=S:\b\3\cmake\modules ^
+ -D TSC_DIR=S:\b\5\cmake\modules ^
+ -D LLBuild_DIR=S:\b\6\cmake\modules ^
+ -D Yams_DIR=S:\b\7\cmake\modules ^
+ -D SwiftDriver_DIR=S:\b\8\cmake\modules ^
+ -D ArgumentParser_DIR=S:\b\9\cmake\modules ^
+ -G Ninja ^
+ -S S:\swift-package-manager
+
+ninja -C S:\b\10
+```
+
+Indicate to swift-package-manager where to find the Package Description before installation:
+```cmd
+set SWIFTPM_PD_LIBS=S:\b\10\pm
```
## Install the Swift toolchain on Windows
diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h
index 2f6d07561224b..0ac4ab8943c42 100644
--- a/include/swift/ABI/Metadata.h
+++ b/include/swift/ABI/Metadata.h
@@ -3772,6 +3772,21 @@ struct TargetSingletonMetadataInitialization {
const TargetTypeContextDescriptor *description) const;
};
+template
+struct TargetCanonicalSpecializedMetadatasListCount {
+ uint32_t count;
+};
+
+template
+struct TargetCanonicalSpecializedMetadatasListEntry {
+ TargetRelativeDirectPointer, /*Nullable*/ false> metadata;
+};
+
+template
+struct TargetCanonicalSpecializedMetadataAccessorsListEntry {
+ TargetRelativeDirectPointer accessor;
+};
+
template
class TargetTypeContextDescriptor
: public TargetContextDescriptor {
@@ -3821,6 +3836,10 @@ class TargetTypeContextDescriptor
return getTypeContextDescriptorFlags().hasForeignMetadataInitialization();
}
+ bool hasCanonicicalMetadataPrespecializations() const {
+ return getTypeContextDescriptorFlags().hasCanonicalMetadataPrespecializations();
+ }
+
/// Given that this type has foreign metadata initialization, return the
/// control structure for it.
const TargetForeignMetadataInitialization &
@@ -3853,6 +3872,9 @@ class TargetTypeContextDescriptor
return words + offset;
}
+ const llvm::ArrayRef, /*Nullable*/ false>>
+ getCanonicicalMetadataPrespecializations() const;
+
static bool classof(const TargetContextDescriptor *cd) {
return cd->getKind() >= ContextDescriptorKind::Type_First
&& cd->getKind() <= ContextDescriptorKind::Type_Last;
@@ -3990,7 +4012,10 @@ class TargetClassDescriptor final
TargetMethodDescriptor,
TargetOverrideTableHeader,
TargetMethodOverrideDescriptor,
- TargetObjCResilientClassStubInfo> {
+ TargetObjCResilientClassStubInfo,
+ TargetCanonicalSpecializedMetadatasListCount,
+ TargetCanonicalSpecializedMetadatasListEntry,
+ TargetCanonicalSpecializedMetadataAccessorsListEntry> {
private:
using TrailingGenericContextObjects =
swift::TrailingGenericContextObjects,
@@ -4002,7 +4027,10 @@ class TargetClassDescriptor final
TargetMethodDescriptor,
TargetOverrideTableHeader,
TargetMethodOverrideDescriptor,
- TargetObjCResilientClassStubInfo>;
+ TargetObjCResilientClassStubInfo,
+ TargetCanonicalSpecializedMetadatasListCount,
+ TargetCanonicalSpecializedMetadatasListEntry,
+ TargetCanonicalSpecializedMetadataAccessorsListEntry>;
using TrailingObjects =
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4020,6 +4048,16 @@ class TargetClassDescriptor final
TargetSingletonMetadataInitialization;
using ObjCResilientClassStubInfo =
TargetObjCResilientClassStubInfo;
+ using Metadata =
+ TargetRelativeDirectPointer, /*Nullable*/ false>;
+ using MetadataListCount =
+ TargetCanonicalSpecializedMetadatasListCount;
+ using MetadataListEntry =
+ TargetCanonicalSpecializedMetadatasListEntry;
+ using MetadataAccessor =
+ TargetRelativeDirectPointer;
+ using MetadataAccessorListEntry =
+ TargetCanonicalSpecializedMetadataAccessorsListEntry;
using StoredPointer = typename Runtime::StoredPointer;
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
@@ -4139,6 +4177,24 @@ class TargetClassDescriptor final
return hasObjCResilientClassStub() ? 1 : 0;
}
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ 1
+ : 0;
+ }
+
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ this->template getTrailingObjects()->count
+ : 0;
+ }
+
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ this->template getTrailingObjects()->count
+ : 0;
+ }
+
public:
const TargetRelativeDirectPointer &
getResilientSuperclass() const {
@@ -4276,6 +4332,32 @@ class TargetClassDescriptor final
->Stub.get();
}
+ llvm::ArrayRef getCanonicicalMetadataPrespecializations() const {
+ if (!this->hasCanonicicalMetadataPrespecializations()) {
+ return {};
+ }
+
+ auto *listCount = this->template getTrailingObjects();
+ auto *list = this->template getTrailingObjects();
+ return llvm::ArrayRef(
+ reinterpret_cast(list),
+ listCount->count
+ );
+ }
+
+ llvm::ArrayRef getCanonicalMetadataPrespecializationAccessors() const {
+ if (!this->hasCanonicicalMetadataPrespecializations()) {
+ return {};
+ }
+
+ auto *listCount = this->template getTrailingObjects();
+ auto *list = this->template getTrailingObjects();
+ return llvm::ArrayRef(
+ reinterpret_cast(list),
+ listCount->count
+ );
+ }
+
static bool classof(const TargetContextDescriptor *cd) {
return cd->getKind() == ContextDescriptorKind::Class;
}
@@ -4301,19 +4383,29 @@ class TargetStructDescriptor final
TargetTypeGenericContextDescriptorHeader,
/*additional trailing objects*/
TargetForeignMetadataInitialization,
- TargetSingletonMetadataInitialization> {
+ TargetSingletonMetadataInitialization,
+ TargetCanonicalSpecializedMetadatasListCount,
+ TargetCanonicalSpecializedMetadatasListEntry> {
public:
using ForeignMetadataInitialization =
TargetForeignMetadataInitialization;
using SingletonMetadataInitialization =
TargetSingletonMetadataInitialization;
+ using Metadata =
+ TargetRelativeDirectPointer, /*Nullable*/ false>;
+ using MetadataListCount =
+ TargetCanonicalSpecializedMetadatasListCount;
+ using MetadataListEntry =
+ TargetCanonicalSpecializedMetadatasListEntry;
private:
using TrailingGenericContextObjects =
swift::TrailingGenericContextObjects,
TargetTypeGenericContextDescriptorHeader,
ForeignMetadataInitialization,
- SingletonMetadataInitialization>;
+ SingletonMetadataInitialization,
+ MetadataListCount,
+ MetadataListEntry>;
using TrailingObjects =
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4331,6 +4423,18 @@ class TargetStructDescriptor final
return this->hasSingletonMetadataInitialization() ? 1 : 0;
}
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ 1
+ : 0;
+ }
+
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ this->template getTrailingObjects()->count
+ : 0;
+ }
+
public:
using TrailingGenericContextObjects::getGenericContext;
using TrailingGenericContextObjects::getGenericContextHeader;
@@ -4363,6 +4467,19 @@ class TargetStructDescriptor final
return TargetStructMetadata::getGenericArgumentOffset();
}
+ llvm::ArrayRef getCanonicicalMetadataPrespecializations() const {
+ if (!this->hasCanonicicalMetadataPrespecializations()) {
+ return {};
+ }
+
+ auto *listCount = this->template getTrailingObjects();
+ auto *list = this->template getTrailingObjects();
+ return llvm::ArrayRef(
+ reinterpret_cast(list),
+ listCount->count
+ );
+ }
+
static bool classof(const TargetContextDescriptor *cd) {
return cd->getKind() == ContextDescriptorKind::Struct;
}
@@ -4377,19 +4494,29 @@ class TargetEnumDescriptor final
TargetTypeGenericContextDescriptorHeader,
/*additional trailing objects*/
TargetForeignMetadataInitialization,
- TargetSingletonMetadataInitialization> {
+ TargetSingletonMetadataInitialization,
+ TargetCanonicalSpecializedMetadatasListCount,
+ TargetCanonicalSpecializedMetadatasListEntry> {
public:
using SingletonMetadataInitialization =
TargetSingletonMetadataInitialization;
using ForeignMetadataInitialization =
TargetForeignMetadataInitialization;
+ using Metadata =
+ TargetRelativeDirectPointer, /*Nullable*/ false>;
+ using MetadataListCount =
+ TargetCanonicalSpecializedMetadatasListCount;
+ using MetadataListEntry =
+ TargetCanonicalSpecializedMetadatasListEntry;
private:
using TrailingGenericContextObjects =
swift::TrailingGenericContextObjects,
TargetTypeGenericContextDescriptorHeader,
ForeignMetadataInitialization,
- SingletonMetadataInitialization>;
+ SingletonMetadataInitialization,
+ MetadataListCount,
+ MetadataListEntry>;
using TrailingObjects =
typename TrailingGenericContextObjects::TrailingObjects;
@@ -4407,6 +4534,18 @@ class TargetEnumDescriptor final
return this->hasSingletonMetadataInitialization() ? 1 : 0;
}
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ 1
+ : 0;
+ }
+
+ size_t numTrailingObjects(OverloadToken) const {
+ return this->hasCanonicicalMetadataPrespecializations() ?
+ this->template getTrailingObjects()->count
+ : 0;
+ }
+
public:
using TrailingGenericContextObjects::getGenericContext;
using TrailingGenericContextObjects::getGenericContextHeader;
@@ -4453,6 +4592,19 @@ class TargetEnumDescriptor final
return *this->template getTrailingObjects();
}
+ llvm::ArrayRef getCanonicicalMetadataPrespecializations() const {
+ if (!this->hasCanonicicalMetadataPrespecializations()) {
+ return {};
+ }
+
+ auto *listCount = this->template getTrailingObjects();
+ auto *list = this->template getTrailingObjects();
+ return llvm::ArrayRef(
+ reinterpret_cast(list),
+ listCount->count
+ );
+ }
+
static bool classof(const TargetContextDescriptor *cd) {
return cd->getKind() == ContextDescriptorKind::Enum;
}
@@ -4587,6 +4739,24 @@ TargetTypeContextDescriptor::getSingletonMetadataInitialization() const
}
}
+template
+inline const llvm::ArrayRef, /*Nullable*/ false>>
+TargetTypeContextDescriptor::getCanonicicalMetadataPrespecializations() const {
+ switch (this->getKind()) {
+ case ContextDescriptorKind::Enum:
+ return llvm::cast>(this)
+ ->getCanonicicalMetadataPrespecializations();
+ case ContextDescriptorKind::Struct:
+ return llvm::cast>(this)
+ ->getCanonicicalMetadataPrespecializations();
+ case ContextDescriptorKind::Class:
+ return llvm::cast>(this)
+ ->getCanonicicalMetadataPrespecializations();
+ default:
+ swift_runtime_unreachable("Not a type context descriptor.");
+ }
+}
+
/// An entry in the chain of dynamic replacement functions.
struct DynamicReplacementChainEntry {
void *implementationFunction;
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index b5b62a7edf5f0..54232972ca9fd 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -1326,6 +1326,10 @@ class TypeContextDescriptorFlags : public FlagSet {
/// Meaningful for all type-descriptor kinds.
HasImportInfo = 2,
+ /// Set if the type descriptor has a pointer to a list of canonical
+ /// prespecializations.
+ HasCanonicalMetadataPrespecializations = 3,
+
// Type-specific flags:
/// The kind of reference that this class makes to its resilient superclass
@@ -1393,6 +1397,8 @@ class TypeContextDescriptorFlags : public FlagSet {
FLAGSET_DEFINE_FLAG_ACCESSORS(HasImportInfo, hasImportInfo, setHasImportInfo)
+ FLAGSET_DEFINE_FLAG_ACCESSORS(HasCanonicalMetadataPrespecializations, hasCanonicalMetadataPrespecializations, setHasCanonicalMetadataPrespecializations)
+
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasVTable,
class_hasVTable,
class_setHasVTable)
diff --git a/include/swift/ABI/ObjectFile.h b/include/swift/ABI/ObjectFile.h
new file mode 100644
index 0000000000000..cd570132cdc0a
--- /dev/null
+++ b/include/swift/ABI/ObjectFile.h
@@ -0,0 +1,99 @@
+//===--- ObjectFile.h - Object File Related Information ------*- C++ -*-===//
+//
+// Object File related data structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_ABI_OBJECTFILE_H
+#define SWIFT_ABI_OBJECTFILE_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace swift {
+
+/// Represents the six reflection sections used by Swift
+enum ReflectionSectionKind : uint8_t {
+ fieldmd,
+ assocty,
+ builtin,
+ capture,
+ typeref,
+ reflstr
+};
+
+/// Abstract base class responsible for providing the correct reflection section
+/// string identifier for a given object file type (Mach-O, ELF, COFF).
+class SwiftObjectFileFormat {
+public:
+ virtual ~SwiftObjectFileFormat() {}
+ virtual llvm::StringRef getSectionName(ReflectionSectionKind section) = 0;
+};
+
+/// Responsible for providing the Mach-O reflection section identifiers.
+class SwiftObjectFileFormatMachO : SwiftObjectFileFormat {
+public:
+ llvm::StringRef getSectionName(ReflectionSectionKind section) override {
+ switch (section) {
+ case fieldmd:
+ return "__swift5_fieldmd";
+ case assocty:
+ return "__swift5_assocty";
+ case builtin:
+ return "__swift5_builtin";
+ case capture:
+ return "__swift5_capture";
+ case typeref:
+ return "__swift5_typeref";
+ case reflstr:
+ return "__swift5_reflstr";
+ }
+ llvm_unreachable("Section type not found.");
+ }
+};
+
+/// Responsible for providing the ELF reflection section identifiers.
+class SwiftObjectFileFormatELF : SwiftObjectFileFormat {
+public:
+ llvm::StringRef getSectionName(ReflectionSectionKind section) override {
+ switch (section) {
+ case fieldmd:
+ return "swift5_fieldmd";
+ case assocty:
+ return "swift5_assocty";
+ case builtin:
+ return "swift5_builtin";
+ case capture:
+ return "swift5_capture";
+ case typeref:
+ return "swift5_typeref";
+ case reflstr:
+ return "swift5_reflstr";
+ }
+ llvm_unreachable("Section type not found.");
+ }
+};
+
+/// Responsible for providing the COFF reflection section identifiers
+class SwiftObjectFileFormatCOFF : SwiftObjectFileFormat {
+public:
+ llvm::StringRef getSectionName(ReflectionSectionKind section) override {
+ switch (section) {
+ case fieldmd:
+ return ".sw5flmd";
+ case assocty:
+ return ".sw5asty";
+ case builtin:
+ return ".sw5bltn";
+ case capture:
+ return ".sw5cptr";
+ case typeref:
+ return ".sw5tyrf";
+ case reflstr:
+ return ".sw5rfst";
+ }
+ llvm_unreachable("Section not found.");
+ }
+};
+} // namespace swift
+#endif // SWIFT_ABI_OBJECTFILE_H
diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h
index e3745be52d7b2..fd020c6eb703b 100644
--- a/include/swift/AST/ASTContext.h
+++ b/include/swift/AST/ASTContext.h
@@ -62,6 +62,7 @@ namespace swift {
class BoundGenericType;
class ClangModuleLoader;
class ClangNode;
+ class ClangTypeConverter;
class ConcreteDeclRef;
class ConstructorDecl;
class Decl;
@@ -213,7 +214,9 @@ class ASTContext final {
void operator=(const ASTContext&) = delete;
ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
- SearchPathOptions &SearchPathOpts, SourceManager &SourceMgr,
+ SearchPathOptions &SearchPathOpts,
+ ClangImporterOptions &ClangImporterOpts,
+ SourceManager &SourceMgr,
DiagnosticEngine &Diags);
public:
@@ -227,6 +230,7 @@ class ASTContext final {
static ASTContext *get(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
SearchPathOptions &SearchPathOpts,
+ ClangImporterOptions &ClangImporterOpts,
SourceManager &SourceMgr, DiagnosticEngine &Diags);
~ASTContext();
@@ -245,6 +249,9 @@ class ASTContext final {
/// The search path options used by this AST context.
SearchPathOptions &SearchPathOpts;
+ /// The clang importer options used by this AST context.
+ ClangImporterOptions &ClangImporterOpts;
+
/// The source manager object.
SourceManager &SourceMgr;
@@ -586,6 +593,10 @@ class ASTContext final {
Type getBridgedToObjC(const DeclContext *dc, Type type,
Type *bridgedValueType = nullptr) const;
+private:
+ ClangTypeConverter &getClangTypeConverter();
+
+public:
/// Get the Clang type corresponding to a Swift function type.
///
/// \param params The function parameters.
@@ -595,6 +606,14 @@ class ASTContext final {
getClangFunctionType(ArrayRef params, Type resultTy,
FunctionTypeRepresentation trueRep);
+ /// Get the canonical Clang type corresponding to a SIL function type.
+ ///
+ /// SIL analog of \c ASTContext::getClangFunctionType .
+ const clang::Type *
+ getCanonicalClangFunctionType(
+ ArrayRef params, Optional result,
+ SILFunctionType::Representation trueRep);
+
/// Get the Swift declaration that a Clang declaration was exported from,
/// if applicable.
const Decl *getSwiftDeclForExportedClangDecl(const clang::Decl *decl);
@@ -669,6 +688,10 @@ class ASTContext final {
/// compiler for the target platform.
AvailabilityContext getSwift53Availability();
+ /// Get the runtime availability of features introduced in the Swift 5.4
+ /// compiler for the target platform.
+ AvailabilityContext getSwift54Availability();
+
/// Get the runtime availability of features that have been introduced in the
/// Swift compiler for future versions of the target platform.
AvailabilityContext getSwiftFutureAvailability();
@@ -735,6 +758,12 @@ class ASTContext final {
ModuleDependenciesCache &cache,
InterfaceSubContextDelegate &delegate);
+ /// Retrieve the module dependencies for the Swift module with the given name.
+ Optional getSwiftModuleDependencies(
+ StringRef moduleName,
+ ModuleDependenciesCache &cache,
+ InterfaceSubContextDelegate &delegate);
+
/// Load extensions to the given nominal type from the external
/// module loaders.
///
diff --git a/include/swift/AST/ASTMangler.h b/include/swift/AST/ASTMangler.h
index 50c401e7ee2bc..b244e766ffc52 100644
--- a/include/swift/AST/ASTMangler.h
+++ b/include/swift/AST/ASTMangler.h
@@ -146,7 +146,8 @@ class ASTMangler : public Mangler {
std::string mangleGlobalVariableFull(const VarDecl *decl);
- std::string mangleGlobalInit(const VarDecl *decl, int counter,
+ std::string mangleGlobalInit(const PatternBindingDecl *decl,
+ unsigned entry,
bool isInitFunc);
std::string mangleReabstractionThunkHelper(CanSILFunctionType ThunkType,
diff --git a/include/swift/AST/ASTPrinter.h b/include/swift/AST/ASTPrinter.h
index 3c28d725ab6bb..3273d3ec4d7f4 100644
--- a/include/swift/AST/ASTPrinter.h
+++ b/include/swift/AST/ASTPrinter.h
@@ -325,7 +325,7 @@ class ExtraIndentStreamPrinter : public StreamPrinter {
ExtraIndentStreamPrinter(raw_ostream &out, StringRef extraIndent)
: StreamPrinter(out), ExtraIndent(extraIndent) { }
- virtual void printIndent() {
+ virtual void printIndent() override {
printText(ExtraIndent);
StreamPrinter::printIndent();
}
diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h
index 0cac9c8e61277..2f3588ec3f92c 100644
--- a/include/swift/AST/ASTScope.h
+++ b/include/swift/AST/ASTScope.h
@@ -44,11 +44,10 @@
/// try disabling it.
/// \p message must be a string literal
#define ASTScopeAssert(predicate, message) \
- assert((predicate) && message \
- " Try compiling with '-disable-astscope-lookup'.")
+ assert((predicate) && message)
#define ASTScope_unreachable(message) \
- llvm_unreachable(message " Try compiling with '-disable-astscope-lookup'.")
+ llvm_unreachable(message)
namespace swift {
diff --git a/include/swift/AST/ASTTypeIDZone.def b/include/swift/AST/ASTTypeIDZone.def
index bf6aeaf1e65dc..fa9dd1d3a8d3c 100644
--- a/include/swift/AST/ASTTypeIDZone.def
+++ b/include/swift/AST/ASTTypeIDZone.def
@@ -28,6 +28,7 @@ SWIFT_TYPEID(Requirement)
SWIFT_TYPEID(ResilienceExpansion)
SWIFT_TYPEID(FragileFunctionKind)
SWIFT_TYPEID(TangentPropertyInfo)
+SWIFT_TYPEID(SymbolSourceMap)
SWIFT_TYPEID(Type)
SWIFT_TYPEID(TypePair)
SWIFT_TYPEID(TypeWitnessAndDecl)
diff --git a/include/swift/AST/ASTTypeIDs.h b/include/swift/AST/ASTTypeIDs.h
index 973f7dc2c9836..6fc964d6fa305 100644
--- a/include/swift/AST/ASTTypeIDs.h
+++ b/include/swift/AST/ASTTypeIDs.h
@@ -60,6 +60,7 @@ class Requirement;
enum class ResilienceExpansion : unsigned;
struct FragileFunctionKind;
class SourceFile;
+class SymbolSourceMap;
struct TangentPropertyInfo;
class Type;
class TypeAliasDecl;
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index b6fea6459d533..2c744e4c0769a 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -53,6 +53,7 @@ TYPE_ATTR(noescape)
TYPE_ATTR(escaping)
TYPE_ATTR(differentiable)
TYPE_ATTR(noDerivative)
+TYPE_ATTR(async)
// SIL-specific attributes
TYPE_ATTR(block_storage)
@@ -560,6 +561,11 @@ SIMPLE_DECL_ATTR(noDerivative, NoDerivative,
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
100)
+SIMPLE_DECL_ATTR(asyncHandler, AsyncHandler,
+ OnFunc | UserInaccessible |
+ ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
+ 101)
+
#undef TYPE_ATTR
#undef DECL_ATTR_ALIAS
#undef CONTEXTUAL_DECL_ATTR_ALIAS
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index 25fa621adf0bc..0c67ece50d09f 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -1427,7 +1427,7 @@ class SpecializeAttr : public DeclAttribute {
TrailingWhereClause *getTrailingWhereClause() const;
- GenericSignature getSpecializedSgnature() const {
+ GenericSignature getSpecializedSignature() const {
return specializedSignature;
}
diff --git a/include/swift/AST/Builtins.h b/include/swift/AST/Builtins.h
index 1654e7cc4cc3d..516f7dce7376a 100644
--- a/include/swift/AST/Builtins.h
+++ b/include/swift/AST/Builtins.h
@@ -26,7 +26,7 @@
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
-enum class AtomicOrdering;
+enum class AtomicOrdering : unsigned;
}
namespace swift {
diff --git a/include/swift/AST/ClangModuleLoader.h b/include/swift/AST/ClangModuleLoader.h
index 64bc7e7d58413..06c41a3d8e61e 100644
--- a/include/swift/AST/ClangModuleLoader.h
+++ b/include/swift/AST/ClangModuleLoader.h
@@ -109,7 +109,7 @@ class StableSerializationPath {
class ClangModuleLoader : public ModuleLoader {
private:
- virtual void anchor();
+ virtual void anchor() override;
protected:
using ModuleLoader::ModuleLoader;
diff --git a/include/swift/AST/ClangNode.h b/include/swift/AST/ClangNode.h
index cbf120840b661..ec8299843ac1d 100644
--- a/include/swift/AST/ClangNode.h
+++ b/include/swift/AST/ClangNode.h
@@ -13,6 +13,7 @@
#ifndef SWIFT_CLANGNODE_H
#define SWIFT_CLANGNODE_H
+#include "swift/Basic/Debug.h"
#include "llvm/ADT/PointerUnion.h"
namespace clang {
@@ -48,8 +49,8 @@ class ClangNode {
template
using Box = detail::ClangNodeBox;
- llvm::PointerUnion4, Box,
- Box, Box> Ptr;
+ llvm::PointerUnion, Box,
+ Box, Box> Ptr;
public:
ClangNode() = default;
@@ -98,6 +99,8 @@ class ClangNode {
clang::SourceLocation getLocation() const;
clang::SourceRange getSourceRange() const;
+ SWIFT_DEBUG_DUMP;
+
void *getOpaqueValue() const { return Ptr.getOpaqueValue(); }
static inline ClangNode getFromOpaqueValue(void *VP) {
ClangNode N;
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index e3fb02109d10b..48d31fcafcb92 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -63,6 +63,7 @@ namespace swift {
class Type;
class Expr;
class DeclRefExpr;
+ class ForeignAsyncConvention;
class ForeignErrorConvention;
class LiteralExpr;
class BraceStmt;
@@ -300,7 +301,13 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Whether this declaration was added to the surrounding
/// DeclContext of an active #if config clause.
- EscapedFromIfConfig : 1
+ EscapedFromIfConfig : 1,
+
+ /// Whether this declaration is syntactically scoped inside of
+ /// a local context, but should behave like a top-level
+ /// declaration for name lookup purposes. This is used by
+ /// lldb.
+ Hoisted : 1
);
SWIFT_INLINE_BITFIELD_FULL(PatternBindingDecl, Decl, 1+2+16,
@@ -385,7 +392,7 @@ class alignas(1 << DeclAlignInBits) Decl {
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
StaticSpelling : 2
);
- SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1+1,
+ SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1,
/// \see AbstractFunctionDecl::BodyKind
BodyKind : 3,
@@ -689,6 +696,7 @@ class alignas(1 << DeclAlignInBits) Decl {
Bits.Decl.Implicit = false;
Bits.Decl.FromClang = false;
Bits.Decl.EscapedFromIfConfig = false;
+ Bits.Decl.Hoisted = false;
}
/// Get the Clang node associated with this declaration.
@@ -836,6 +844,16 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Mark this declaration as implicit.
void setImplicit(bool implicit = true) { Bits.Decl.Implicit = implicit; }
+ /// Determine whether this declaration is syntactically scoped inside of
+ /// a local context, but should behave like a top-level declaration
+ /// for name lookup purposes. This is used by lldb.
+ bool isHoisted() const { return Bits.Decl.Hoisted; }
+
+ /// Set whether this declaration should be syntactically scoped inside
+ /// of a local context, but should behave like a top-level declaration,
+ /// but should behave like a top-level declaration. This is used by lldb.
+ void setHoisted(bool hoisted = true) { Bits.Decl.Hoisted = hoisted; }
+
public:
bool escapedFromIfConfig() const {
return Bits.Decl.EscapedFromIfConfig;
@@ -2996,11 +3014,29 @@ class TypeAliasDecl : public GenericTypeDecl {
/// Retrieve a sugared interface type containing the structure of the interface
/// type before any semantic validation has occured.
Type getStructuralType() const;
-
+
+ /// Whether the typealias forwards perfectly to its underlying type.
+ ///
+ /// If true, this typealias was created by ClangImporter to preserve source
+ /// compatibility with a previous language version's name for a type. Many
+ /// checks in Sema look through compatibility aliases even when they would
+ /// operate on other typealiases.
+ ///
+ /// \warning This has absolutely nothing to do with the Objective-C
+ /// \c compatibility_alias keyword.
bool isCompatibilityAlias() const {
return Bits.TypeAliasDecl.IsCompatibilityAlias;
}
+ /// Sets whether the typealias forwards perfectly to its underlying type.
+ ///
+ /// Marks this typealias as having been created by ClangImporter to preserve
+ /// source compatibility with a previous language version's name for a type.
+ /// Many checks in Sema look through compatibility aliases even when they
+ /// would operate on other typealiases.
+ ///
+ /// \warning This has absolutely nothing to do with the Objective-C
+ /// \c compatibility_alias keyword.
void markAsCompatibilityAlias(bool newValue = true) {
Bits.TypeAliasDecl.IsCompatibilityAlias = newValue;
}
@@ -3867,7 +3903,7 @@ class ClassDecl final : public NominalTypeDecl {
friend class SuperclassDeclRequest;
friend class SuperclassTypeRequest;
- friend class EmittedMembersRequest;
+ friend class SemanticMembersRequest;
friend class HasMissingDesignatedInitializersRequest;
friend class InheritsSuperclassInitializersRequest;
@@ -4055,10 +4091,6 @@ class ClassDecl final : public NominalTypeDecl {
/// Record the presence of an @objc method with the given selector.
void recordObjCMethod(AbstractFunctionDecl *method, ObjCSelector selector);
- /// Get all the members of this class, synthesizing any implicit members
- /// that appear in the vtable if needed.
- ArrayRef getEmittedMembers() const;
-
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == DeclKind::Class;
@@ -4851,9 +4883,9 @@ enum class PropertyWrapperSynthesizedPropertyKind {
/// The backing storage property, which is a stored property of the
/// wrapper type.
Backing,
- /// A storage wrapper (e.g., `$foo`), which is a wrapper over the
- /// wrapper instance's `projectedValue` property.
- StorageWrapper,
+ /// A projection (e.g., `$foo`), which is a computed property to access the
+ /// wrapper instance's \c projectedValue property.
+ Projection,
};
/// VarDecl - 'var' and 'let' declarations.
@@ -5176,9 +5208,9 @@ class VarDecl : public AbstractStorageDecl {
/// bound generic version.
VarDecl *getPropertyWrapperBackingProperty() const;
- /// Retreive the storage wrapper for a property that has an attached
- /// property wrapper.
- VarDecl *getPropertyWrapperStorageWrapper() const;
+ /// Retreive the projection var for a property that has an attached
+ /// property wrapper with a \c projectedValue .
+ VarDecl *getPropertyWrapperProjectionVar() const;
/// Retrieve the backing storage property for a lazy property.
VarDecl *getLazyStorageProperty() const;
@@ -5598,17 +5630,20 @@ enum class ObjCSubscriptKind {
/// signatures (indices and element type) are distinct.
///
class SubscriptDecl : public GenericContext, public AbstractStorageDecl {
+ friend class ResultTypeRequest;
+
SourceLoc StaticLoc;
SourceLoc ArrowLoc;
SourceLoc EndLoc;
ParameterList *Indices;
TypeLoc ElementTy;
-public:
+ void setElementInterfaceType(Type type);
+
SubscriptDecl(DeclName Name,
SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
SourceLoc SubscriptLoc, ParameterList *Indices,
- SourceLoc ArrowLoc, TypeLoc ElementTy, DeclContext *Parent,
+ SourceLoc ArrowLoc, TypeRepr *ElementTyR, DeclContext *Parent,
GenericParamList *GenericParams)
: GenericContext(DeclContextKind::SubscriptDecl, Parent, GenericParams),
AbstractStorageDecl(DeclKind::Subscript,
@@ -5616,10 +5651,31 @@ class SubscriptDecl : public GenericContext, public AbstractStorageDecl {
Parent, Name, SubscriptLoc,
/*will be overwritten*/ StorageIsNotMutable),
StaticLoc(StaticLoc), ArrowLoc(ArrowLoc),
- Indices(nullptr), ElementTy(ElementTy) {
+ Indices(nullptr), ElementTy(ElementTyR) {
Bits.SubscriptDecl.StaticSpelling = static_cast(StaticSpelling);
setIndices(Indices);
}
+
+public:
+ /// Factory function only for use by deserialization.
+ static SubscriptDecl *createDeserialized(ASTContext &Context, DeclName Name,
+ StaticSpellingKind StaticSpelling,
+ Type ElementTy, DeclContext *Parent,
+ GenericParamList *GenericParams);
+
+ static SubscriptDecl *create(ASTContext &Context, DeclName Name,
+ SourceLoc StaticLoc,
+ StaticSpellingKind StaticSpelling,
+ SourceLoc SubscriptLoc, ParameterList *Indices,
+ SourceLoc ArrowLoc, TypeRepr *ElementTyR,
+ DeclContext *Parent,
+ GenericParamList *GenericParams);
+
+ static SubscriptDecl *createImported(ASTContext &Context, DeclName Name,
+ SourceLoc SubscriptLoc,
+ ParameterList *Indices,
+ SourceLoc ArrowLoc, Type ElementTy,
+ DeclContext *Parent, ClangNode ClangN);
/// \returns the way 'static'/'class' was spelled in the source.
StaticSpellingKind getStaticSpelling() const {
@@ -5646,8 +5702,11 @@ class SubscriptDecl : public GenericContext, public AbstractStorageDecl {
/// Retrieve the type of the element referenced by a subscript
/// operation.
Type getElementInterfaceType() const;
- TypeLoc &getElementTypeLoc() { return ElementTy; }
- const TypeLoc &getElementTypeLoc() const { return ElementTy; }
+
+ TypeRepr *getElementTypeRepr() const { return ElementTy.getTypeRepr(); }
+ SourceRange getElementTypeSourceRange() const {
+ return ElementTy.getSourceRange();
+ }
/// Determine the kind of Objective-C subscripting this declaration
/// implies.
@@ -5888,6 +5947,16 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
/// type of the function will be `async` as well.
bool hasAsync() const { return Bits.AbstractFunctionDecl.Async; }
+ /// Returns true if the function is a suitable 'async' context.
+ ///
+ /// Functions that are an 'async' context can make calls to 'async' functions.
+ bool isAsyncContext() const {
+ return hasAsync() || isAsyncHandler();
+ }
+
+ /// Returns true if the function is an @asyncHandler.
+ bool isAsyncHandler() const;
+
/// Returns true if the function body throws.
bool hasThrows() const { return Bits.AbstractFunctionDecl.Throws; }
@@ -5935,13 +6004,14 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
/// Note that parsing for the body was delayed.
void setBodyDelayed(SourceRange bodyRange) {
- assert(getBodyKind() == BodyKind::None ||
- getBodyKind() == BodyKind::Skipped);
+ assert(getBodyKind() == BodyKind::None);
assert(bodyRange.isValid());
BodyRange = bodyRange;
setBodyKind(BodyKind::Unparsed);
}
+ void setBodyToBeReparsed(SourceRange bodyRange);
+
/// Provide the parsed body for the function.
void setBodyParsed(BraceStmt *S) {
setBody(S, BodyKind::Parsed);
@@ -6007,6 +6077,19 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
/// Retrieve the source range of the function body.
SourceRange getBodySourceRange() const;
+ /// Keep current \c getBodySourceRange() as the "original" body source range
+ /// iff the this method hasn't been called on this object. The current body
+ /// source range must be in the same buffer as the location of the declaration
+ /// itself.
+ void keepOriginalBodySourceRange();
+
+ /// Retrieve the source range of the *original* function body.
+ ///
+ /// This may be different from \c getBodySourceRange() that returns the source
+ /// range of the *current* body. It happens when the body is parsed from other
+ /// source buffers for e.g. code-completion.
+ SourceRange getOriginalBodySourceRange() const;
+
/// Retrieve the source range of the function declaration name + patterns.
SourceRange getSignatureSourceRange() const;
@@ -6079,7 +6162,15 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
/// being dropped altogether. `None` is returned for a normal function
/// or method.
Optional getForeignFunctionAsMethodSelfParameterIndex() const;
-
+
+ /// Set information about the foreign async convention used by this
+ /// declaration.
+ void setForeignAsyncConvention(const ForeignAsyncConvention &convention);
+
+ /// Get information about the foreign async convention used by this
+ /// declaration, given that it is @objc and 'async'.
+ Optional getForeignAsyncConvention() const;
+
static bool classof(const Decl *D) {
return D->getKind() >= DeclKind::First_AbstractFunctionDecl &&
D->getKind() <= DeclKind::Last_AbstractFunctionDecl;
@@ -6122,6 +6213,7 @@ class FuncDecl : public AbstractFunctionDecl {
friend class AbstractFunctionDecl;
friend class SelfAccessKindRequest;
friend class IsStaticRequest;
+ friend class ResultTypeRequest;
SourceLoc StaticLoc; // Location of the 'static' token or invalid.
SourceLoc FuncLoc; // Location of the 'func' token.
@@ -6156,6 +6248,8 @@ class FuncDecl : public AbstractFunctionDecl {
Bits.FuncDecl.HasTopLevelLocalContextCaptures = false;
}
+ void setResultInterfaceType(Type type);
+
private:
static FuncDecl *createImpl(ASTContext &Context, SourceLoc StaticLoc,
StaticSpellingKind StaticSpelling,
@@ -6183,25 +6277,32 @@ class FuncDecl : public AbstractFunctionDecl {
public:
/// Factory function only for use by deserialization.
- static FuncDecl *createDeserialized(ASTContext &Context, SourceLoc StaticLoc,
+ static FuncDecl *createDeserialized(ASTContext &Context,
StaticSpellingKind StaticSpelling,
- SourceLoc FuncLoc,
- DeclName Name, SourceLoc NameLoc,
- bool Async, SourceLoc AsyncLoc,
- bool Throws, SourceLoc ThrowsLoc,
+ DeclName Name, bool Async, bool Throws,
GenericParamList *GenericParams,
- DeclContext *Parent);
+ Type FnRetType, DeclContext *Parent);
static FuncDecl *create(ASTContext &Context, SourceLoc StaticLoc,
- StaticSpellingKind StaticSpelling,
- SourceLoc FuncLoc,
- DeclName Name, SourceLoc NameLoc,
- bool Async, SourceLoc AsyncLoc,
- bool Throws, SourceLoc ThrowsLoc,
+ StaticSpellingKind StaticSpelling, SourceLoc FuncLoc,
+ DeclName Name, SourceLoc NameLoc, bool Async,
+ SourceLoc AsyncLoc, bool Throws, SourceLoc ThrowsLoc,
GenericParamList *GenericParams,
- ParameterList *ParameterList,
- TypeLoc FnRetType, DeclContext *Parent,
- ClangNode ClangN = ClangNode());
+ ParameterList *BodyParams, TypeRepr *ResultTyR,
+ DeclContext *Parent);
+
+ static FuncDecl *createImplicit(ASTContext &Context,
+ StaticSpellingKind StaticSpelling,
+ DeclName Name, SourceLoc NameLoc, bool Async,
+ bool Throws, GenericParamList *GenericParams,
+ ParameterList *BodyParams, Type FnRetType,
+ DeclContext *Parent);
+
+ static FuncDecl *createImported(ASTContext &Context, SourceLoc FuncLoc,
+ DeclName Name, SourceLoc NameLoc,
+ bool Async, bool Throws,
+ ParameterList *BodyParams, Type FnRetType,
+ DeclContext *Parent, ClangNode ClangN);
bool isStatic() const;
@@ -6245,8 +6346,10 @@ class FuncDecl : public AbstractFunctionDecl {
}
SourceRange getSourceRange() const;
- TypeLoc &getBodyResultTypeLoc() { return FnRetType; }
- const TypeLoc &getBodyResultTypeLoc() const { return FnRetType; }
+ TypeRepr *getResultTypeRepr() const { return FnRetType.getTypeRepr(); }
+ SourceRange getResultTypeSourceRange() const {
+ return FnRetType.getSourceRange();
+ }
/// Retrieve the result interface type of this function.
Type getResultInterfaceType() const;
@@ -6367,15 +6470,12 @@ class AccessorDecl final : public FuncDecl {
public:
static AccessorDecl *createDeserialized(ASTContext &ctx,
- SourceLoc declLoc,
- SourceLoc accessorKeywordLoc,
- AccessorKind accessorKind,
- AbstractStorageDecl *storage,
- SourceLoc staticLoc,
- StaticSpellingKind staticSpelling,
- bool throws, SourceLoc throwsLoc,
- GenericParamList *genericParams,
- DeclContext *parent);
+ AccessorKind accessorKind,
+ AbstractStorageDecl *storage,
+ StaticSpellingKind staticSpelling,
+ bool throws,
+ GenericParamList *genericParams,
+ Type fnRetType, DeclContext *parent);
static AccessorDecl *create(ASTContext &ctx, SourceLoc declLoc,
SourceLoc accessorKeywordLoc,
@@ -6386,7 +6486,7 @@ class AccessorDecl final : public FuncDecl {
bool throws, SourceLoc throwsLoc,
GenericParamList *genericParams,
ParameterList *parameterList,
- TypeLoc fnRetType, DeclContext *parent,
+ Type fnRetType, DeclContext *parent,
ClangNode clangNode = ClangNode());
SourceLoc getAccessorKeywordLoc() const { return AccessorKeywordLoc; }
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index 36e1f07a2db56..c41eaa46a8b40 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -783,6 +783,16 @@ class IterableDeclContext {
/// Retrieve the set of members in this context.
DeclRange getMembers() const;
+ /// Get the members that were syntactically present in the source code,
+ /// and will not contain any members that are implicitly synthesized by
+ /// the implementation.
+ ArrayRef getParsedMembers() const;
+
+ /// Get all the members that are semantically within this context,
+ /// including any implicitly-synthesized members.
+ /// The resulting list of members will be stable across translation units.
+ ArrayRef getSemanticMembers() const;
+
/// Retrieve the set of members in this context without loading any from the
/// associated lazy loader; this should only be used as part of implementing
/// abstractions on top of member loading, such as a name lookup table.
diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h
index ee3c776cd9db6..338f146922b5e 100644
--- a/include/swift/AST/DiagnosticEngine.h
+++ b/include/swift/AST/DiagnosticEngine.h
@@ -20,8 +20,9 @@
#include "swift/AST/DeclNameLoc.h"
#include "swift/AST/DiagnosticConsumer.h"
-#include "swift/AST/LocalizationFormat.h"
#include "swift/AST/TypeLoc.h"
+#include "swift/Localization/LocalizationFormat.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/FileSystem.h"
@@ -987,7 +988,8 @@ namespace swift {
void emitTentativeDiagnostics();
public:
- const char *diagnosticStringFor(const DiagID id, bool printDiagnosticName);
+ llvm::StringRef diagnosticStringFor(const DiagID id,
+ bool printDiagnosticName);
/// If there is no clear .dia file for a diagnostic, put it in the one
/// corresponding to the SourceLoc given here.
@@ -1056,6 +1058,21 @@ namespace swift {
}
}
+ bool hasErrors() const {
+ ArrayRef diagnostics(Engine.TentativeDiagnostics.begin() +
+ PrevDiagnostics,
+ Engine.TentativeDiagnostics.end());
+
+ for (auto &diagnostic : diagnostics) {
+ auto behavior = Engine.state.determineBehavior(diagnostic.getID());
+ if (behavior == DiagnosticState::Behavior::Fatal ||
+ behavior == DiagnosticState::Behavior::Error)
+ return true;
+ }
+
+ return false;
+ }
+
/// Abort and close this transaction and erase all diagnostics
/// record while it was open.
void abort() {
diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def
index cdeef09e3058e..72d8d64bbecb7 100644
--- a/include/swift/AST/DiagnosticsCommon.def
+++ b/include/swift/AST/DiagnosticsCommon.def
@@ -185,5 +185,22 @@ WARNING(cross_imported_by_both_modules, none,
ERROR(scanner_find_cycle, none,
"dependency scanner detected dependency cycle: '%0'", (StringRef))
+ERROR(scanner_arguments_invalid, none,
+ "dependencies scanner cannot be configured with arguments: '%0'", (StringRef))
+
+//------------------------------------------------------------------------------
+// MARK: custom attribute diagnostics
+//------------------------------------------------------------------------------
+
+ERROR(ambiguous_custom_attribute_ref,none,
+ "ambiguous use of attribute %0", (Identifier))
+NOTE(ambiguous_custom_attribute_ref_fix,none,
+ "use '%0.' to reference the attribute %1 in module %2",
+ (StringRef, Identifier, Identifier))
+NOTE(found_attribute_candidate,none,
+ "found this attribute", ())
+ERROR(unknown_attribute,none,
+ "unknown attribute '%0'", (StringRef))
+
#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def
index 6f88d42b6b517..5f15d3a2bde46 100644
--- a/include/swift/AST/DiagnosticsFrontend.def
+++ b/include/swift/AST/DiagnosticsFrontend.def
@@ -121,6 +121,8 @@ ERROR(error_mode_cannot_emit_module_source_info,none,
"this mode does not support emitting module source info files", ())
ERROR(error_mode_cannot_emit_interface,none,
"this mode does not support emitting module interface files", ())
+ERROR(error_mode_cannot_emit_module_summary,none,
+ "this mode does not support emitting module summary files", ())
ERROR(cannot_emit_ir_skipping_function_bodies,none,
"-experimental-skip-non-inlinable-function-bodies does not support "
"emitting IR", ())
@@ -270,6 +272,14 @@ ERROR(placeholder_dependency_module_map_corrupted,none,
"Swift placeholder dependency module map from %0 is malformed",
(StringRef))
+ERROR(batch_scan_input_file_missing,none,
+ "cannot open batch dependencies scan input file from %0",
+ (StringRef))
+
+ERROR(batch_scan_input_file_corrupted,none,
+ "batch dependencies scan input file from %0 is malformed",
+ (StringRef))
+
REMARK(default_previous_install_name, none,
"default previous install name for %0 is %1", (StringRef, StringRef))
@@ -316,11 +326,11 @@ ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
(StringRef, StringRef))
ERROR(error_invalid_debug_prefix_map, none,
- "invalid argument '%0' to -debug-prefix-map; it must be of the form "
- "'original=remapped'", (StringRef))
+ "values for '-debug-prefix-map' must be in the format 'original=remapped'"
+ ", but '%0' was provided", (StringRef))
ERROR(error_invalid_coverage_prefix_map, none,
- "invalid argument '%0' to -coverage-prefix-map; it must be of the form "
- "'original=remapped'", (StringRef))
+ "values for '-coverage-prefix-map' must be in the format "
+ "'original=remapped', but '%0' was provided", (StringRef))
ERROR(error_unable_to_write_swift_ranges_file, none,
@@ -354,6 +364,9 @@ ERROR(error_extracting_flags_from_module_interface,none,
"error extracting flags from module interface", ())
REMARK(rebuilding_module_from_interface,none,
"rebuilding module '%0' from interface '%1'", (StringRef, StringRef))
+NOTE(sdk_version_pbm_version,none,
+ "SDK build version is '%0'; prebuilt modules were "
+ "built using SDK build version: '%1'", (StringRef, StringRef))
NOTE(out_of_date_module_here,none,
"%select{compiled|cached|forwarding|prebuilt}0 module is out of date: '%1'",
(unsigned, StringRef))
diff --git a/include/swift/AST/DiagnosticsModuleDiffer.def b/include/swift/AST/DiagnosticsModuleDiffer.def
index d4aba30553186..dbcc194ba4ca6 100644
--- a/include/swift/AST/DiagnosticsModuleDiffer.def
+++ b/include/swift/AST/DiagnosticsModuleDiffer.def
@@ -74,7 +74,7 @@ ERROR(param_ownership_change,none,"%0 has %1 changing from %2 to %3", (StringRef
ERROR(type_witness_change,none,"%0 has type witness type for %1 changing from %2 to %3", (StringRef, StringRef, StringRef, StringRef))
-ERROR(decl_new_witness_table_entry,none,"%0 now requires %select{|no}1 new witness table entry", (StringRef, bool))
+ERROR(decl_new_witness_table_entry,none,"%0 now requires%select{| no}1 new witness table entry", (StringRef, bool))
ERROR(new_decl_without_intro,none,"%0 is a new API without @available attribute", (StringRef))
@@ -88,5 +88,7 @@ ERROR(not_inheriting_convenience_inits,none,"%0 no longer inherits convenience i
ERROR(enum_case_added,none,"%0 has been added as a new enum case", (StringRef))
+WARNING(cannot_read_allowlist,none,"cannot read breakage allowlist at '%0'", (StringRef))
+
#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 6c7f4e6533b04..eaae1b7f858be 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -882,8 +882,6 @@ ERROR(expected_parameter_colon,PointsToFirstBadToken,
"expected ':' following argument label and parameter name", ())
ERROR(expected_assignment_instead_of_comparison_operator,none,
"expected '=' instead of '==' to assign default value for parameter", ())
-ERROR(multiple_parameter_ellipsis,none,
- "only a single variadic parameter '...' is permitted", ())
ERROR(parameter_vararg_default,none,
"variadic parameter cannot have a default value", ())
ERROR(parameter_specifier_as_attr_disallowed,none,
@@ -916,6 +914,8 @@ ERROR(initializer_as_typed_pattern,none,
ERROR(unlabeled_parameter_following_variadic_parameter,none,
"a parameter following a variadic parameter requires a label", ())
+ERROR(closure_unlabeled_parameter_following_variadic_parameter,none,
+ "no parameters may follow a variadic parameter in a closure", ())
ERROR(enum_element_empty_arglist,none,
"enum element with associated values must have at least one "
@@ -1324,8 +1324,6 @@ ERROR(replace_equal_with_colon_for_value,none,
"'=' has been replaced with ':' in attribute arguments", ())
ERROR(expected_attribute_name,none,
"expected an attribute name", ())
-ERROR(unknown_attribute,none,
- "unknown attribute '%0'", (StringRef))
ERROR(unexpected_lparen_in_attribute,none,
"unexpected '(' in attribute '%0'", (StringRef))
ERROR(duplicate_attribute,none,
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 1998449474d87..5de6c959c74fc 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -112,6 +112,9 @@ ERROR(expected_argument_in_contextual_member,none,
"member %0 expects argument of type %1", (DeclName, Type))
ERROR(expected_parens_in_contextual_member,none,
"member %0 is a function; did you mean to call it?", (DeclName))
+ERROR(expected_parens_in_contextual_member_type,none,
+ "member %0 is a function that produces expected type %1; did you mean to "
+ "call it?", (DeclName, Type))
ERROR(expected_result_in_contextual_member,none,
"member %0 in %2 produces result of type %1, but context expects %2",
@@ -453,6 +456,10 @@ ERROR(cannot_convert_closure_result_nil,none,
ERROR(cannot_convert_parent_type,none,
"cannot convert parent type %0 to expected type %1",
(Type, Type))
+ERROR(cannot_convert_chain_result_type,none,
+ "member chain produces result of type %0 but contextual base was "
+ "inferred as %1",
+ (Type, Type))
NOTE(generic_argument_mismatch,none,
"arguments to generic parameter %0 (%1 and %2) are expected to be equal",
@@ -708,12 +715,12 @@ ERROR(sema_opening_import,Fatal,
ERROR(serialization_load_failed,Fatal,
"failed to load module '%0'", (StringRef))
ERROR(module_interface_build_failed,Fatal,
- "failed to build module '%0' from its module interface; "
- "%select{the compiler that produced it, '%2', may have used features "
- "that aren't supported by this compiler, '%3'"
- "|it may have been damaged or it may have triggered a bug in the Swift "
- "compiler when it was produced}1",
- (StringRef, bool, StringRef, StringRef))
+ "failed to %select{build module '%1' from its module interface|verify "
+ "module interface of '%1'}0; %select{the compiler that produced it, "
+ "'%3', may have used features that aren't supported by this compiler, "
+ "'%4'|it may have been damaged or it may have triggered a bug in the "
+ "Swift compiler when it was produced}2",
+ (bool, StringRef, bool, StringRef, StringRef))
ERROR(serialization_malformed_module,Fatal,
"malformed compiled module: %0", (StringRef))
ERROR(serialization_module_too_new,Fatal,
@@ -1038,9 +1045,6 @@ WARNING(downcast_to_unrelated,none,
"cast from %0 to unrelated type %1 always fails", (Type, Type))
NOTE(downcast_to_unrelated_fixit,none,
"did you mean to call %0 with '()'?", (Identifier))
-ERROR(downcast_to_more_optional,none,
- "cannot downcast from %0 to a more optional type %1",
- (Type, Type))
ERROR(optional_chain_noop,none,
"optional chain has no effect, expression already produces %0",
(Type))
@@ -1082,6 +1086,9 @@ NOTE(unwrap_with_guard,none,
ERROR(optional_base_not_unwrapped,none,
"value of optional type %0 must be unwrapped to refer to member %1 of "
"wrapped base type %2", (Type, DeclNameRef, Type))
+ERROR(invalid_optional_infered_keypath_root, none,
+ "key path root inferred as optional type %0 must be unwrapped to refer to member %1 "
+ "of unwrapped type %2", (Type, DeclNameRef, Type))
NOTE(optional_base_chain,none,
"chain the optional using '?' to access member %0 only for non-'nil' "
"base values", (DeclNameRef))
@@ -1089,6 +1096,12 @@ NOTE(optional_base_remove_optional_for_keypath_root, none,
"use unwrapped type %0 as key path root", (Type))
NOTE(optional_keypath_application_base, none,
"use '?' to access key path subscript only for non-'nil' base values", ())
+NOTE(optional_key_path_root_base_chain, none,
+ "chain the optional using '?.' to access unwrapped type member %0",
+ (DeclNameRef))
+NOTE(optional_key_path_root_base_unwrap, none,
+ "unwrap the optional using '!.' to access unwrapped type member %0",
+ (DeclNameRef))
ERROR(missing_unwrap_optional_try,none,
"value of optional type %0 not unwrapped; did you mean to use 'try!' "
@@ -1294,8 +1307,9 @@ ERROR(nominal_type_not_attribute,none,
ERROR(mutating_invalid_global_scope,none, "%0 is only valid on methods",
(SelfAccessKind))
-ERROR(mutating_invalid_classes,none, "%0 isn't valid on methods in "
- "classes or class-bound protocols", (SelfAccessKind))
+ERROR(mutating_invalid_classes,none, "%0 is not valid on %1s in "
+ "%select{classes|class-bound protocols}2",
+ (SelfAccessKind, DescriptiveDeclKind, bool))
ERROR(functions_mutating_and_not,none,
"method must not be declared both %0 and %1",
@@ -1370,6 +1384,8 @@ ERROR(cdecl_empty_name,none,
"@_cdecl symbol name cannot be empty", ())
ERROR(cdecl_throws,none,
"raising errors from @_cdecl functions is not supported", ())
+ERROR(cdecl_async,none,
+ "@_cdecl functions cannot be asynchronous", ())
ERROR(attr_methods_only,none,
"only methods can be declared %0", (DeclAttribute))
@@ -2174,9 +2190,6 @@ NOTE(protocol_witness_settable_conflict,none,
"candidate is not settable, but protocol requires it", ())
NOTE(protocol_witness_rethrows_conflict,none,
"candidate is not 'rethrows', but protocol requires it", ())
-NOTE(protocol_witness_async_conflict,none,
- "candidate is %select{not |}0'async', but protocol requirement is%select{| not}0",
- (bool))
NOTE(protocol_witness_throws_conflict,none,
"candidate throws, but protocol does not allow it", ())
NOTE(protocol_witness_not_objc,none,
@@ -2728,13 +2741,17 @@ WARNING(decl_from_hidden_module_warn,none,
ERROR(conformance_from_implementation_only_module,none,
"cannot use conformance of %0 to %1 %select{here|as property wrapper here|"
"in an extension with public or '@usableFromInline' members|"
- "in an extension with conditional conformances}2; %3 has been imported "
- "as implementation-only",
- (Type, Identifier, unsigned, Identifier))
+ "in an extension with conditional conformances}2; "
+ "%select{%3 has been imported as implementation-only|"
+ "the conformance is declared as SPI in %3|"
+ "the conformance is declared as SPI}4",
+ (Type, Identifier, unsigned, Identifier, unsigned))
ERROR(assoc_conformance_from_implementation_only_module,none,
"cannot use conformance of %0 to %1 in associated type %3 (inferred as "
- "%4); %2 has been imported as implementation-only",
- (Type, Identifier, Identifier, Type, Type))
+ "%4); %select{%2 has been imported as implementation-only|"
+ "the conformance is declared as SPI in %2|"
+ "the conformance is declared as SPI}5",
+ (Type, Identifier, Identifier, Type, Type, unsigned))
ERROR(unexportable_clang_function_type,none,
"cannot export the underlying C type of the function type %0; "
"it may use anonymous types or types defined outside of a module",
@@ -2765,8 +2782,9 @@ ERROR(cannot_synthesize_init_in_extension_of_nonfinal,none,
"be satisfied by a 'required' initializer in the class definition",
(Type, DeclName))
ERROR(cannot_synthesize_in_crossfile_extension,none,
- "implementation of %0 cannot be automatically synthesized in an extension "
- "in a different file to the type", (Type))
+ "extension outside of file declaring %0 %1 prevents automatic synthesis "
+ "of %2 for protocol %3",
+ (DescriptiveDeclKind, DeclName, DeclName, Type))
ERROR(broken_additive_arithmetic_requirement,none,
"AdditiveArithmetic protocol is broken: unexpected requirement", ())
@@ -2808,15 +2826,16 @@ WARNING(differentiable_nondiff_type_implicit_noderivative_fixit,none,
/*nominalCanDeriveAdditiveArithmetic*/ bool))
WARNING(differentiable_immutable_wrapper_implicit_noderivative_fixit,none,
"synthesis of the 'Differentiable.move(along:)' requirement for %1 "
- "requires 'wrappedValue' in property wrapper %0 to be mutable; "
- "add an explicit '@noDerivative' attribute"
+ "requires 'wrappedValue' in property wrapper %0 to be mutable or have a "
+ "non-mutating 'move(along:)'; add an explicit '@noDerivative' attribute"
"%select{|, or conform %1 to 'AdditiveArithmetic'}2",
(/*wrapperType*/ Identifier, /*nominalName*/ Identifier,
/*nominalCanDeriveAdditiveArithmetic*/ bool))
WARNING(differentiable_let_property_implicit_noderivative_fixit,none,
"synthesis of the 'Differentiable.move(along:)' requirement for %0 "
"requires all stored properties not marked with `@noDerivative` to be "
- "mutable; use 'var' instead, or add an explicit '@noDerivative' attribute"
+ "mutable or have a non-mutating 'move(along:)'; use 'var' instead, or "
+ "add an explicit '@noDerivative' attribute "
"%select{|, or conform %0 to 'AdditiveArithmetic'}1",
(/*nominalName*/ Identifier, /*nominalCanDeriveAdditiveArithmetic*/ bool))
@@ -4016,10 +4035,13 @@ ERROR(throw_in_nonexhaustive_catch,none,
"error is not handled because the enclosing catch is not exhaustive", ())
ERROR(throwing_call_in_illegal_context,none,
- "call can throw, but errors cannot be thrown out of %0",
- (StringRef))
+ "call can throw, but errors cannot be thrown out of "
+ "%select{<>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
+ (unsigned))
ERROR(throw_in_illegal_context,none,
- "errors cannot be thrown out of %0", (StringRef))
+ "errors cannot be thrown out of "
+ "%select{<>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
+ (unsigned))
ERROR(throwing_operator_without_try,none,
"operator can throw but expression is not marked with 'try'", ())
@@ -4033,10 +4055,6 @@ NOTE(note_error_to_optional,none,
"did you mean to handle error as optional value?", ())
NOTE(note_disable_error_propagation,none,
"did you mean to disable error propagation?", ())
-ERROR(async_call_without_await,none,
- "call is 'async' but is not marked with 'await'", ())
-WARNING(no_async_in_await,none,
- "no calls to 'async' functions occur within 'await' expression", ())
WARNING(no_throw_in_try,none,
"no calls to throwing functions occur within 'try' expression", ())
@@ -4044,6 +4062,76 @@ WARNING(no_throw_in_try,none,
WARNING(no_throw_in_do_with_catch,none,
"'catch' block is unreachable because no errors are thrown in 'do' block", ())
+//------------------------------------------------------------------------------
+// MARK: Concurrency
+//------------------------------------------------------------------------------
+ERROR(async_call_without_await,none,
+ "call is 'async' but is not marked with 'await'", ())
+ERROR(async_call_without_await_in_autoclosure,none,
+ "call is 'async' in an autoclosure argument that is not marked with 'await'", ())
+WARNING(no_async_in_await,none,
+ "no calls to 'async' functions occur within 'await' expression", ())
+ERROR(async_call_in_illegal_context,none,
+ "'async' call cannot occur in "
+ "%select{<>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
+ (unsigned))
+ERROR(await_in_illegal_context,none,
+ "'await' operation cannot occur in "
+ "%select{<>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
+ (unsigned))
+ERROR(async_in_nonasync_function,none,
+ "%select{'async'|'await'}0 in %select{a function|an autoclosure}1 that "
+ "does not support concurrency",
+ (bool, bool))
+NOTE(note_add_async_to_function,none,
+ "add 'async' to function %0 to make it asynchronous", (DeclName))
+NOTE(note_add_asynchandler_to_function,none,
+ "add '@asyncHandler' to function %0 to create an implicit asynchronous context", (DeclName))
+ERROR(not_objc_function_async,none,
+ "'async' function cannot be represented in Objective-C", ())
+NOTE(not_objc_function_type_async,none,
+ "'async' function types cannot be represented in Objective-C", ())
+NOTE(protocol_witness_async_conflict,none,
+ "candidate is %select{not |}0'async', but protocol requirement is%select{| not}0",
+ (bool))
+ERROR(async_autoclosure_nonasync_function,none,
+ "'async' autoclosure parameter in a non-'async' function", ())
+
+ERROR(asynchandler_attr_requires_concurrency,none,
+ "'@asyncHandler' is only valid when experimental concurrency is enabled",
+ ())
+ERROR(asynchandler_non_func,none,
+ "'@asyncHandler' can only be applied to functions",
+ ())
+ERROR(asynchandler_returns_value,none,
+ "'@asyncHandler' function can only return 'Void'",
+ ())
+ERROR(asynchandler_throws,none,
+ "'@asyncHandler' function cannot throw",
+ ())
+ERROR(asynchandler_async,none,
+ "'@asyncHandler' function cannot be 'async' itself",
+ ())
+ERROR(asynchandler_inout_parameter,none,
+ "'inout' parameter is not allowed in '@asyncHandler' function",
+ ())
+ERROR(asynchandler_mutating,none,
+ "'@asyncHandler' function cannot be 'mutating'",
+ ())
+
+ERROR(objc_ambiguous_async_convention,none,
+ "%0 overrides or implements protocol requirements for Objective-C "
+ "declarations with incompatible async conventions",
+ (DeclName))
+NOTE(objc_ambiguous_async_convention_candidate,none,
+ "%0 provides async here", (DeclName))
+
+ERROR(satisfy_async_objc,none,
+ "satisfying an asychronous @objc %select{method|initializer}0 with "
+ "a synchronous %select{method|initializer}0 is not supported", (bool))
+ERROR(async_objc_dynamic_self,none,
+ "asynchronous method returning 'Self' cannot be '@objc'", ())
+
//------------------------------------------------------------------------------
// MARK: Type Check Types
//------------------------------------------------------------------------------
@@ -4398,10 +4486,6 @@ NOTE(not_objc_generic_type_param,none,
NOTE(not_objc_function_type_param,none,
"function types cannot be represented in Objective-C unless their "
"parameters and returns can be", ())
-ERROR(not_objc_function_async,none,
- "'async' function cannot be represented in Objective-C", ())
-NOTE(not_objc_function_type_async,none,
- "'async' function types cannot be represented in Objective-C", ())
NOTE(not_objc_function_type_throwing,none,
"throwing function types cannot be represented in Objective-C", ())
NOTE(objc_inferring_on_objc_protocol_member,none,
@@ -5181,6 +5265,16 @@ WARNING(function_builder_missing_limited_availability, none,
"function builder %0 does not implement 'buildLimitedAvailability'; "
"this code may crash on earlier versions of the OS",
(Type))
+ERROR(function_builder_static_buildblock, none,
+ "function builder must provide at least one static 'buildBlock' "
+ "method", ())
+NOTE(function_builder_non_static_buildblock, none,
+ "did you mean to make instance method 'buildBlock' static?", ())
+NOTE(function_builder_buildblock_enum_case, none,
+ "enum case 'buildBlock' cannot be used to satisfy the function builder "
+ "requirement", ())
+NOTE(function_builder_buildblock_not_static_method, none,
+ "potential match 'buildBlock' is not a static method", ())
//------------------------------------------------------------------------------
// MARK: Tuple Shuffle Diagnostics
diff --git a/include/swift/AST/Evaluator.h b/include/swift/AST/Evaluator.h
index 5235343ebe779..212682d0bc121 100644
--- a/include/swift/AST/Evaluator.h
+++ b/include/swift/AST/Evaluator.h
@@ -65,7 +65,7 @@ class PrettyStackTraceRequest : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceRequest(const Request &request) : request(request) { }
- void print(llvm::raw_ostream &out) const {
+ void print(llvm::raw_ostream &out) const override {
out << "While evaluating request ";
simple_display(out, request);
out << "\n";
@@ -85,9 +85,9 @@ struct CyclicalRequestError :
CyclicalRequestError(const Request &request, const Evaluator &evaluator)
: request(request), evaluator(evaluator) {}
- virtual void log(llvm::raw_ostream &out) const;
+ virtual void log(llvm::raw_ostream &out) const override;
- virtual std::error_code convertToErrorCode() const {
+ virtual std::error_code convertToErrorCode() const override {
// This is essentially unused, but is a temporary requirement for
// llvm::ErrorInfo subclasses.
llvm_unreachable("shouldn't get std::error_code from CyclicalRequestError");
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index a75d9d56b39e4..b53a279a93b4c 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -249,17 +249,8 @@ class alignas(8) Expr {
NumArgLabels : 16
);
- SWIFT_INLINE_BITFIELD_FULL(UnresolvedMemberExpr, Expr, 1+1+1+16,
- /// Whether the UnresolvedMemberExpr has arguments.
- HasArguments : 1,
- /// Whether the UnresolvedMemberExpr also has source locations for the
- /// argument label.
- HasArgLabelLocs : 1,
- /// Whether the last argument is a trailing closure.
- HasTrailingClosure : 1,
- : NumPadBits,
- /// # of argument labels stored after the UnresolvedMemberExpr.
- NumArgLabels : 16
+ SWIFT_INLINE_BITFIELD_FULL(UnresolvedMemberExpr, Expr, 2,
+ FunctionRefKind : 2
);
SWIFT_INLINE_BITFIELD(OverloadSetRefExpr, Expr, 2,
@@ -1841,71 +1832,49 @@ class DynamicSubscriptExpr final
/// member, which is to be resolved with context sensitive type information into
/// bar.foo. These always have unresolved type.
class UnresolvedMemberExpr final
- : public Expr,
- public TrailingCallArguments {
+ : public Expr {
SourceLoc DotLoc;
DeclNameLoc NameLoc;
DeclNameRef Name;
- Expr *Argument;
-
- UnresolvedMemberExpr(SourceLoc dotLoc, DeclNameLoc nameLoc,
- DeclNameRef name, Expr *argument,
- ArrayRef argLabels,
- ArrayRef argLabelLocs,
- bool hasTrailingClosure,
- bool implicit);
public:
- /// Create a new unresolved member expression with no arguments.
- static UnresolvedMemberExpr *create(ASTContext &ctx, SourceLoc dotLoc,
- DeclNameLoc nameLoc, DeclNameRef name,
- bool implicit);
-
- /// Create a new unresolved member expression.
- static UnresolvedMemberExpr *create(ASTContext &ctx, SourceLoc dotLoc,
- DeclNameLoc nameLoc, DeclNameRef name,
- SourceLoc lParenLoc,
- ArrayRef args,
- ArrayRef argLabels,
- ArrayRef argLabelLocs,
- SourceLoc rParenLoc,
- ArrayRef trailingClosures,
- bool implicit);
+ UnresolvedMemberExpr(SourceLoc dotLoc, DeclNameLoc nameLoc, DeclNameRef name,
+ bool implicit)
+ : Expr(ExprKind::UnresolvedMember, implicit), DotLoc(dotLoc),
+ NameLoc(nameLoc), Name(name) {
+ // FIXME: Really, we should be setting this to `FunctionRefKind::Compound`
+ // if `NameLoc` is compound, but this would be a source break for cases like
+ // ```
+ // struct S {
+ // static func makeS(_: Int) -> S! { S() }
+ // }
+ //
+ // let s: S = .makeS(_:)(0)
+ // ```
+ // Instead, we should store compound-ness as a separate bit from applied/
+ // unapplied.
+ Bits.UnresolvedMemberExpr.FunctionRefKind =
+ static_cast(FunctionRefKind::Unapplied);
+ }
DeclNameRef getName() const { return Name; }
DeclNameLoc getNameLoc() const { return NameLoc; }
SourceLoc getDotLoc() const { return DotLoc; }
- Expr *getArgument() const { return Argument; }
- void setArgument(Expr *argument) { Argument = argument; }
-
- /// Whether this reference has arguments.
- bool hasArguments() const {
- return Bits.UnresolvedMemberExpr.HasArguments;
- }
- unsigned getNumArguments() const {
- return Bits.UnresolvedMemberExpr.NumArgLabels;
- }
-
- bool hasArgumentLabelLocs() const {
- return Bits.UnresolvedMemberExpr.HasArgLabelLocs;
- }
+ SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
- /// Whether this call with written with a trailing closure.
- bool hasTrailingClosure() const {
- return Bits.UnresolvedMemberExpr.HasTrailingClosure;
- }
+ SourceLoc getStartLoc() const { return DotLoc; }
+ SourceLoc getEndLoc() const { return NameLoc.getSourceRange().End; }
- /// Return the index of the unlabeled trailing closure argument.
- Optional getUnlabeledTrailingClosureIndex() const {
- return getArgument()->getUnlabeledTrailingClosureIndexOfPackedArgument();
+ /// Retrieve the kind of function reference.
+ FunctionRefKind getFunctionRefKind() const {
+ return static_cast(
+ Bits.UnresolvedMemberExpr.FunctionRefKind);
}
- SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
-
- SourceLoc getStartLoc() const { return DotLoc; }
- SourceLoc getEndLoc() const {
- return (Argument ? Argument->getEndLoc() : NameLoc.getSourceRange().End);
+ /// Set the kind of function reference.
+ void setFunctionRefKind(FunctionRefKind refKind) {
+ Bits.UnresolvedMemberExpr.FunctionRefKind = static_cast(refKind);
}
static bool classof(const Expr *E) {
@@ -2088,6 +2057,31 @@ class ParenExpr : public IdentityExpr {
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Paren; }
};
+
+/// Represents the result of a chain of accesses or calls hanging off of an
+/// \c UnresolvedMemberExpr at the root. This is only used during type checking
+/// to give the result type of such a chain representation in the AST. This
+/// expression type is always implicit.
+class UnresolvedMemberChainResultExpr : public IdentityExpr {
+ /// The base of this chain of member accesses.
+ UnresolvedMemberExpr *ChainBase;
+public:
+ UnresolvedMemberChainResultExpr(Expr *subExpr, UnresolvedMemberExpr *base,
+ Type ty = Type())
+ : IdentityExpr(ExprKind::UnresolvedMemberChainResult, subExpr, ty,
+ /*isImplicit=*/true),
+ ChainBase(base) {
+ assert(base);
+ }
+
+ UnresolvedMemberExpr *getChainBase() const { return ChainBase; }
+
+ SWIFT_FORWARD_SOURCE_LOCS_TO(getSubExpr())
+
+ static bool classof(const Expr *E) {
+ return E->getKind() == ExprKind::UnresolvedMemberChainResult;
+ }
+};
/// AwaitExpr - An 'await' surrounding an expression, marking that the
/// expression contains code which is a coroutine that may block.
@@ -3815,6 +3809,9 @@ class ClosureExpr : public AbstractClosureExpr {
/// this information directly on the ClosureExpr.
VarDecl * CapturedSelfDecl;
+ /// The location of the "async", if present.
+ SourceLoc AsyncLoc;
+
/// The location of the "throws", if present.
SourceLoc ThrowsLoc;
@@ -3833,14 +3830,15 @@ class ClosureExpr : public AbstractClosureExpr {
llvm::PointerIntPair Body;
public:
ClosureExpr(SourceRange bracketRange, VarDecl *capturedSelfDecl,
- ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc,
- SourceLoc inLoc, TypeExpr *explicitResultType,
+ ParameterList *params, SourceLoc asyncLoc, SourceLoc throwsLoc,
+ SourceLoc arrowLoc, SourceLoc inLoc, TypeExpr *explicitResultType,
unsigned discriminator, DeclContext *parent)
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
discriminator, parent),
BracketRange(bracketRange),
CapturedSelfDecl(capturedSelfDecl),
- ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc),
+ AsyncLoc(asyncLoc), ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc),
+ InLoc(inLoc),
ExplicitResultTypeAndBodyState(explicitResultType, BodyState::Parsed),
Body(nullptr) {
setParameterList(params);
@@ -3888,7 +3886,12 @@ class ClosureExpr : public AbstractClosureExpr {
SourceLoc getInLoc() const {
return InLoc;
}
-
+
+ /// Retrieve the location of the 'async' for a closure that has it.
+ SourceLoc getAsyncLoc() const {
+ return AsyncLoc;
+ }
+
/// Retrieve the location of the 'throws' for a closure that has it.
SourceLoc getThrowsLoc() const {
return ThrowsLoc;
@@ -5648,7 +5651,13 @@ class KeyPathExpr : public Expr {
/// components from the argument array.
void resolveComponents(ASTContext &C,
ArrayRef resolvedComponents);
-
+
+ /// Indicates if the key path expression is composed by a single invalid
+ /// component. e.g. missing component `\Root`
+ bool hasSingleInvalidComponent() const {
+ return Components.size() == 1 && !Components.front().isValid();
+ }
+
/// Retrieve the string literal expression, which will be \c NULL prior to
/// type checking and a string literal after type checking for an
/// @objc key path.
diff --git a/include/swift/AST/ExprNodes.def b/include/swift/AST/ExprNodes.def
index 53ee2da310a42..7c98a83c0afd9 100644
--- a/include/swift/AST/ExprNodes.def
+++ b/include/swift/AST/ExprNodes.def
@@ -104,7 +104,8 @@ ABSTRACT_EXPR(Identity, Expr)
EXPR(Paren, IdentityExpr)
EXPR(DotSelf, IdentityExpr)
EXPR(Await, IdentityExpr)
- EXPR_RANGE(Identity, Paren, Await)
+ EXPR(UnresolvedMemberChainResult, IdentityExpr)
+ EXPR_RANGE(Identity, Paren, UnresolvedMemberChainResult)
ABSTRACT_EXPR(AnyTry, Expr)
EXPR(Try, AnyTryExpr)
EXPR(ForceTry, AnyTryExpr)
diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h
index 639b982d25e73..6f258723fb887 100644
--- a/include/swift/AST/ExtInfo.h
+++ b/include/swift/AST/ExtInfo.h
@@ -30,6 +30,7 @@
namespace clang {
class Type;
+class ASTContext;
} // namespace clang
namespace swift {
@@ -77,7 +78,7 @@ class ClangTypeInfo {
/// Use the ClangModuleLoader to print the Clang type as a string.
void printType(ClangModuleLoader *cml, llvm::raw_ostream &os) const;
- void dump(llvm::raw_ostream &os) const;
+ void dump(llvm::raw_ostream &os, const clang::ASTContext &ctx) const;
};
// MARK: - FunctionTypeRepresentation
@@ -194,16 +195,8 @@ class ASTExtInfoBuilder {
using Representation = FunctionTypeRepresentation;
- static void assertIsFunctionType(const clang::Type *);
-
ASTExtInfoBuilder(unsigned bits, ClangTypeInfo clangTypeInfo)
- : bits(bits), clangTypeInfo(clangTypeInfo) {
- // TODO: [clang-function-type-serialization] Once we start serializing
- // the Clang type, we should also assert that the pointer is non-null.
- auto Rep = Representation(bits & RepresentationMask);
- if ((Rep == Representation::CFunctionPointer) && clangTypeInfo.type)
- assertIsFunctionType(clangTypeInfo.type);
- }
+ : bits(bits), clangTypeInfo(clangTypeInfo) {}
public:
// Constructor with all defaults.
@@ -254,10 +247,7 @@ class ASTExtInfoBuilder {
DifferentiabilityKind::NonDifferentiable;
}
- /// Get the underlying ClangTypeInfo value if it is not the default value.
- Optional getClangTypeInfo() const {
- return clangTypeInfo.empty() ? Optional() : clangTypeInfo;
- }
+ ClangTypeInfo getClangTypeInfo() const { return clangTypeInfo; }
constexpr SILFunctionTypeRepresentation getSILRepresentation() const {
unsigned rawRep = bits & RepresentationMask;
@@ -404,9 +394,7 @@ class ASTExtInfo {
constexpr bool isDifferentiable() const { return builder.isDifferentiable(); }
- Optional getClangTypeInfo() const {
- return builder.getClangTypeInfo();
- }
+ ClangTypeInfo getClangTypeInfo() const { return builder.getClangTypeInfo(); }
constexpr bool hasSelfParam() const { return builder.hasSelfParam(); }
@@ -436,6 +424,14 @@ class ASTExtInfo {
return builder.withThrows(throws).build();
}
+ /// Helper method for changing only the async field.
+ ///
+ /// Prefer using \c ASTExtInfoBuilder::withAsync for chaining.
+ LLVM_NODISCARD
+ ASTExtInfo withAsync(bool async = true) const {
+ return builder.withAsync(async).build();
+ }
+
bool isEqualTo(ASTExtInfo other, bool useClangTypes) const {
return builder.isEqualTo(other.builder, useClangTypes);
}
@@ -487,16 +483,17 @@ class SILExtInfoBuilder {
// If bits are added or removed, then TypeBase::SILFunctionTypeBits
// and NumMaskBits must be updated, and they must match.
- // |representation|pseudogeneric| noescape |differentiability|
- // | 0 .. 3 | 4 | 5 | 6 .. 7 |
+ // |representation|pseudogeneric| noescape | async | differentiability|
+ // | 0 .. 3 | 4 | 5 | 6 | 7 .. 8 |
//
enum : unsigned {
RepresentationMask = 0xF << 0,
PseudogenericMask = 1 << 4,
NoEscapeMask = 1 << 5,
- DifferentiabilityMaskOffset = 6,
+ AsyncMask = 1 << 6,
+ DifferentiabilityMaskOffset = 7,
DifferentiabilityMask = 0x3 << DifferentiabilityMaskOffset,
- NumMaskBits = 8
+ NumMaskBits = 9
};
unsigned bits; // Naturally sized for speed.
@@ -509,19 +506,32 @@ class SILExtInfoBuilder {
SILExtInfoBuilder(unsigned bits, ClangTypeInfo clangTypeInfo)
: bits(bits), clangTypeInfo(clangTypeInfo) {}
+ static constexpr unsigned makeBits(Representation rep, bool isPseudogeneric,
+ bool isNoEscape, bool isAsync,
+ DifferentiabilityKind diffKind) {
+ return ((unsigned)rep) | (isPseudogeneric ? PseudogenericMask : 0) |
+ (isNoEscape ? NoEscapeMask : 0) | (isAsync ? AsyncMask : 0) |
+ (((unsigned)diffKind << DifferentiabilityMaskOffset) &
+ DifferentiabilityMask);
+ }
+
public:
// Constructor with all defaults.
- SILExtInfoBuilder() : bits(0), clangTypeInfo(ClangTypeInfo(nullptr)) {}
+ SILExtInfoBuilder() : SILExtInfoBuilder(0, ClangTypeInfo(nullptr)) {}
// Constructor for polymorphic type.
SILExtInfoBuilder(Representation rep, bool isPseudogeneric, bool isNoEscape,
- DifferentiabilityKind diffKind, const clang::Type *type)
- : SILExtInfoBuilder(
- ((unsigned)rep) | (isPseudogeneric ? PseudogenericMask : 0) |
- (isNoEscape ? NoEscapeMask : 0) |
- (((unsigned)diffKind << DifferentiabilityMaskOffset) &
- DifferentiabilityMask),
- ClangTypeInfo(type)) {}
+ bool isAsync, DifferentiabilityKind diffKind,
+ const clang::Type *type)
+ : SILExtInfoBuilder(makeBits(rep, isPseudogeneric, isNoEscape, isAsync,
+ diffKind),
+ ClangTypeInfo(type)) {}
+
+ SILExtInfoBuilder(ASTExtInfoBuilder info, bool isPseudogeneric)
+ : SILExtInfoBuilder(makeBits(info.getSILRepresentation(), isPseudogeneric,
+ info.isNoEscape(), info.isAsync(),
+ info.getDifferentiabilityKind()),
+ info.getClangTypeInfo()) {}
void checkInvariants() const;
@@ -544,6 +554,8 @@ class SILExtInfoBuilder {
// Is this function guaranteed to be no-escape by the type system?
constexpr bool isNoEscape() const { return bits & NoEscapeMask; }
+ constexpr bool isAsync() const { return bits & AsyncMask; }
+
constexpr DifferentiabilityKind getDifferentiabilityKind() const {
return DifferentiabilityKind((bits & DifferentiabilityMask) >>
DifferentiabilityMaskOffset);
@@ -554,10 +566,8 @@ class SILExtInfoBuilder {
DifferentiabilityKind::NonDifferentiable;
}
- /// Get the underlying ClangTypeInfo value if it is not the default value.
- Optional getClangTypeInfo() const {
- return clangTypeInfo.empty() ? Optional() : clangTypeInfo;
- }
+ /// Get the underlying ClangTypeInfo value.
+ ClangTypeInfo getClangTypeInfo() const { return clangTypeInfo; }
constexpr bool hasSelfParam() const {
switch (getRepresentation()) {
@@ -608,6 +618,10 @@ class SILExtInfoBuilder {
: (bits & ~NoEscapeMask),
clangTypeInfo);
}
+ SILExtInfoBuilder withAsync(bool isAsync = true) const {
+ return SILExtInfoBuilder(isAsync ? (bits | AsyncMask) : (bits & ~AsyncMask),
+ clangTypeInfo);
+ }
SILExtInfoBuilder
withDifferentiabilityKind(DifferentiabilityKind differentiability) const {
return SILExtInfoBuilder(
@@ -649,8 +663,8 @@ class SILExtInfo {
static SILExtInfo getThin() {
return SILExtInfoBuilder(SILExtInfoBuilder::Representation::Thin, false,
- false, DifferentiabilityKind::NonDifferentiable,
- nullptr)
+ false, false,
+ DifferentiabilityKind::NonDifferentiable, nullptr)
.build();
}
@@ -673,15 +687,15 @@ class SILExtInfo {
constexpr bool isNoEscape() const { return builder.isNoEscape(); }
+ constexpr bool isAsync() const { return builder.isAsync(); }
+
constexpr DifferentiabilityKind getDifferentiabilityKind() const {
return builder.getDifferentiabilityKind();
}
constexpr bool isDifferentiable() const { return builder.isDifferentiable(); }
- Optional getClangTypeInfo() const {
- return builder.getClangTypeInfo();
- }
+ ClangTypeInfo getClangTypeInfo() const { return builder.getClangTypeInfo(); }
constexpr bool hasSelfParam() const { return builder.hasSelfParam(); }
diff --git a/include/swift/AST/ForeignAsyncConvention.h b/include/swift/AST/ForeignAsyncConvention.h
new file mode 100644
index 0000000000000..35b6c64b6304c
--- /dev/null
+++ b/include/swift/AST/ForeignAsyncConvention.h
@@ -0,0 +1,124 @@
+//===--- ForeignAsyncConvention.h - Async conventions -----------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ForeignAsyncConvention structure, which
+// describes the rules for how to detect that a foreign API is asynchronous.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_FOREIGN_ASYNC_CONVENTION_H
+#define SWIFT_FOREIGN_ASYNC_CONVENTION_H
+
+#include "swift/AST/Type.h"
+
+namespace swift {
+
+/// A small structure describing the async convention of a foreign declaration.
+class ForeignAsyncConvention {
+public:
+ struct Info {
+ /// The index of the completion handler parameters.
+ unsigned CompletionHandlerParamIndex;
+
+ /// When non-zero, indicates which parameter to the completion handler is
+ /// the Error? parameter (minus one) that makes this async function also
+ /// throwing.
+ unsigned CompletionHandlerErrorParamIndex;
+
+ Info()
+ : CompletionHandlerParamIndex(0), CompletionHandlerErrorParamIndex(0) { }
+
+ Info(
+ unsigned completionHandlerParamIndex,
+ Optional completionHandlerErrorParamIndex)
+ : CompletionHandlerParamIndex(completionHandlerParamIndex),
+ CompletionHandlerErrorParamIndex(
+ completionHandlerErrorParamIndex
+ ? *completionHandlerErrorParamIndex + 1
+ : 0) {}
+
+ /// Retrieve the index of the \c Error? parameter in the completion handler's
+ /// parameter list. When argument passed to this parameter is non-null, the
+ /// provided error will be thrown by the async function.
+ Optional completionHandlerErrorParamIndex() const {
+ if (CompletionHandlerErrorParamIndex == 0)
+ return None;
+
+ return CompletionHandlerErrorParamIndex - 1;
+ }
+
+ /// Whether the async function is throwing due to the completion handler
+ /// having an \c Error? parameter.
+ ///
+ /// Equivalent to \c static_cast(completionHandlerErrorParamIndex()).
+ bool isThrowing() const {
+ return CompletionHandlerErrorParamIndex != 0;
+ }
+ };
+
+ /// The type of the completion handler parameter.
+ CanType CompletionHandlerType;
+
+ /// Information about the async convention that can be determined from an
+ /// Objective-C declaration by itself.
+ Info TheInfo;
+
+public:
+ ForeignAsyncConvention() : TheInfo() { }
+
+ ForeignAsyncConvention(CanType completionHandlerType,
+ unsigned completionHandlerParamIndex,
+ Optional completionHandlerErrorParamIndex)
+ : CompletionHandlerType(completionHandlerType),
+ TheInfo(completionHandlerParamIndex, completionHandlerErrorParamIndex)
+ { }
+
+ /// Retrieve the type of the completion handler parameter.
+ CanType completionHandlerType() const { return CompletionHandlerType; }
+
+ /// Retrieve the index of the completion handler parameter, which will be
+ /// erased from the Swift signature of the imported async function.
+ unsigned completionHandlerParamIndex() const {
+ return TheInfo.CompletionHandlerParamIndex;
+ }
+
+ /// Retrieve the index of the \c Error? parameter in the completion handler's
+ /// parameter list. When argument passed to this parameter is non-null, the
+ /// provided error will be thrown by the async function.
+ Optional completionHandlerErrorParamIndex() const {
+ return TheInfo.completionHandlerErrorParamIndex();
+ }
+
+ /// Whether the async function is throwing due to the completion handler
+ /// having an \c Error? parameter.
+ ///
+ /// Equivalent to \c static_cast(completionHandlerErrorParamIndex()).
+ bool isThrowing() const {
+ return TheInfo.isThrowing();
+ }
+
+ bool operator==(ForeignAsyncConvention other) const {
+ return CompletionHandlerType == other.CompletionHandlerType
+ && TheInfo.CompletionHandlerParamIndex ==
+ other.TheInfo.CompletionHandlerParamIndex
+ && TheInfo.CompletionHandlerErrorParamIndex ==
+ other.TheInfo.CompletionHandlerErrorParamIndex;
+ }
+
+ bool operator!=(ForeignAsyncConvention other) const {
+ return !(*this == other);
+ }
+};
+
+}
+
+#endif
diff --git a/include/swift/AST/ForeignErrorConvention.h b/include/swift/AST/ForeignErrorConvention.h
index 48d65d4612856..d09a7a80c0d86 100644
--- a/include/swift/AST/ForeignErrorConvention.h
+++ b/include/swift/AST/ForeignErrorConvention.h
@@ -81,6 +81,10 @@ class ForeignErrorConvention {
}
Info() = default;
+
+ Kind getKind() const {
+ return static_cast(TheKind);
+ }
};
private:
@@ -178,11 +182,24 @@ class ForeignErrorConvention {
/// Returns the physical result type of the function, for functions
/// that completely erase this information.
CanType getResultType() const {
- assert(getKind() == ZeroResult ||
- getKind() == NonZeroResult);
+ assert(resultTypeErasedToVoid(getKind()));
return ResultType;
}
-
+
+ /// Whether this kind of error import erases the result type to 'Void'.
+ static bool resultTypeErasedToVoid(Kind kind) {
+ switch (kind) {
+ case ZeroResult:
+ case NonZeroResult:
+ return true;
+
+ case ZeroPreservedResult:
+ case NilResult:
+ case NonNilError:
+ return false;
+ }
+ }
+
bool operator==(ForeignErrorConvention other) const {
return info.TheKind == other.info.TheKind
&& info.ErrorIsOwned == other.info.ErrorIsOwned
diff --git a/include/swift/AST/GenericEnvironment.h b/include/swift/AST/GenericEnvironment.h
index 144ed20c6621e..a47067b940fa7 100644
--- a/include/swift/AST/GenericEnvironment.h
+++ b/include/swift/AST/GenericEnvironment.h
@@ -149,13 +149,6 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
std::pair
mapConformanceRefIntoContext(Type conformingType,
ProtocolConformanceRef conformance) const;
-
- /// Get the sugared form of a generic parameter type.
- GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const;
-
- /// Get the sugared form of a type by substituting any
- /// generic parameter types by their sugared form.
- Type getSugaredType(Type type) const;
SubstitutionMap getForwardingSubstitutionMap() const;
diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h
index 6f840022dba9a..3a29d21fbd890 100644
--- a/include/swift/AST/GenericSignature.h
+++ b/include/swift/AST/GenericSignature.h
@@ -397,11 +397,18 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
///
/// then this will return 0 for t_0_0, 1 for t_0_1, and 2 for t_1_0.
unsigned getGenericParamOrdinal(GenericTypeParamType *param) const;
-
+
/// Get a substitution map that maps all of the generic signature's
/// generic parameters to themselves.
SubstitutionMap getIdentitySubstitutionMap() const;
+ /// Get the sugared form of a generic parameter type.
+ GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const;
+
+ /// Get the sugared form of a type by substituting any
+ /// generic parameter types by their sugared form.
+ Type getSugaredType(Type type) const;
+
/// Whether this generic signature involves a type variable.
bool hasTypeVariable() const;
diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def
index a9e0f46cb4783..37898169a6707 100644
--- a/include/swift/AST/KnownIdentifiers.def
+++ b/include/swift/AST/KnownIdentifiers.def
@@ -33,7 +33,6 @@ IDENTIFIER(atIndexedSubscript)
IDENTIFIER_(bridgeToObjectiveC)
IDENTIFIER(buildArray)
IDENTIFIER(buildBlock)
-IDENTIFIER(buildDo)
IDENTIFIER(buildEither)
IDENTIFIER(buildExpression)
IDENTIFIER(buildFinalResult)
diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h
index 0a1ff8f42ba2a..5a9334a41b8f0 100644
--- a/include/swift/AST/Module.h
+++ b/include/swift/AST/Module.h
@@ -685,6 +685,12 @@ class ModuleDecl : public DeclContext, public TypeDecl {
void
getImportedModulesForLookup(SmallVectorImpl &imports) const;
+ /// Has \p module been imported via an '@_implementationOnly' import
+ /// instead of another kind of import?
+ ///
+ /// This assumes that \p module was imported.
+ bool isImportedImplementationOnly(const ModuleDecl *module) const;
+
/// Uniques the items in \p imports, ignoring the source locations of the
/// access paths.
///
diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h
index 44cceb47af7ba..5eab3844b32d8 100644
--- a/include/swift/AST/ModuleDependencies.h
+++ b/include/swift/AST/ModuleDependencies.h
@@ -107,6 +107,9 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
/// The hash value that will be used for the generated module
const std::string contextHash;
+ /// A flag that indicates this dependency is a framework
+ const bool isFramework;
+
/// Bridging header file, if there is one.
Optional bridgingHeaderFile;
@@ -125,7 +128,8 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
ArrayRef compiledModuleCandidates,
ArrayRef buildCommandLine,
ArrayRef extraPCMArgs,
- StringRef contextHash
+ StringRef contextHash,
+ bool isFramework
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Swift,
compiledModulePath),
swiftInterfaceFile(swiftInterfaceFile),
@@ -133,7 +137,7 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
compiledModuleCandidates.end()),
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()),
- contextHash(contextHash) { }
+ contextHash(contextHash), isFramework(isFramework) { }
ModuleDependenciesStorageBase *clone() const override {
return new SwiftModuleDependenciesStorage(*this);
@@ -242,21 +246,22 @@ class ModuleDependencies {
ArrayRef compiledCandidates,
ArrayRef buildCommands,
ArrayRef extraPCMArgs,
- StringRef contextHash) {
+ StringRef contextHash,
+ bool isFramework) {
std::string compiledModulePath;
return ModuleDependencies(
std::make_unique(
compiledModulePath, swiftInterfaceFile, compiledCandidates, buildCommands,
- extraPCMArgs, contextHash));
+ extraPCMArgs, contextHash, isFramework));
}
/// Describe the module dependencies for a serialized or parsed Swift module.
static ModuleDependencies forSwiftModule(
- const std::string &compiledModulePath) {
+ const std::string &compiledModulePath, bool isFramework) {
return ModuleDependencies(
std::make_unique(
compiledModulePath, None, ArrayRef(), ArrayRef(),
- ArrayRef(), StringRef()));
+ ArrayRef(), StringRef(), isFramework));
}
/// Describe the main Swift module.
@@ -265,7 +270,7 @@ class ModuleDependencies {
return ModuleDependencies(
std::make_unique(
compiledModulePath, None, ArrayRef(),
- ArrayRef(), extraPCMArgs, StringRef()));
+ ArrayRef(), extraPCMArgs, StringRef(), false));
}
/// Describe the module dependencies for a Clang module that can be
diff --git a/include/swift/AST/ModuleLoader.h b/include/swift/AST/ModuleLoader.h
index 1460daf9f44c1..3660f00461f94 100644
--- a/include/swift/AST/ModuleLoader.h
+++ b/include/swift/AST/ModuleLoader.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "swift/AST/ModuleDependencies.h"
+#include
namespace llvm {
class FileCollector;
@@ -103,17 +104,18 @@ struct SubCompilerInstanceInfo {
/// Abstract interface to run an action in a sub ASTContext.
struct InterfaceSubContextDelegate {
- virtual bool runInSubContext(StringRef moduleName,
- StringRef interfacePath,
- StringRef outputPath,
- SourceLoc diagLoc,
- llvm::function_ref,
- ArrayRef, StringRef)> action) = 0;
- virtual bool runInSubCompilerInstance(StringRef moduleName,
- StringRef interfacePath,
- StringRef outputPath,
- SourceLoc diagLoc,
- llvm::function_ref action) = 0;
+ virtual std::error_code runInSubContext(StringRef moduleName,
+ StringRef interfacePath,
+ StringRef outputPath,
+ SourceLoc diagLoc,
+ llvm::function_ref,
+ ArrayRef, StringRef)> action) = 0;
+ virtual std::error_code runInSubCompilerInstance(StringRef moduleName,
+ StringRef interfacePath,
+ StringRef outputPath,
+ SourceLoc diagLoc,
+ llvm::function_ref action) = 0;
virtual ~InterfaceSubContextDelegate() = default;
};
diff --git a/include/swift/AST/NameLookup.h b/include/swift/AST/NameLookup.h
index ea847ce01c1ba..3411da322aa83 100644
--- a/include/swift/AST/NameLookup.h
+++ b/include/swift/AST/NameLookup.h
@@ -375,7 +375,7 @@ class LambdaDeclConsumer : public VisibleDeclConsumer {
public:
LambdaDeclConsumer(Fn &&callback) : Callback(std::move(callback)) {}
- void foundDecl(ValueDecl *VD, DeclVisibilityKind reason, DynamicLookupInfo) {
+ void foundDecl(ValueDecl *VD, DeclVisibilityKind reason, DynamicLookupInfo) override {
Callback(VD, reason);
}
};
@@ -741,8 +741,6 @@ class ASTScope {
return Mem;
}
- static bool areInactiveIfConfigClausesSupported();
-
private:
static ast_scope::ASTSourceFileScope *createScopeTree(SourceFile *);
diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h
index 6424dd12a72f2..13630507bb3a5 100644
--- a/include/swift/AST/Pattern.h
+++ b/include/swift/AST/Pattern.h
@@ -554,6 +554,9 @@ class EnumElementPattern : public Pattern {
bool hasUnresolvedOriginalExpr() const {
return ElementDeclOrUnresolvedOriginalExpr.is();
}
+ void setUnresolvedOriginalExpr(Expr *e) {
+ ElementDeclOrUnresolvedOriginalExpr = e;
+ }
DeclNameLoc getNameLoc() const { return NameLoc; }
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
diff --git a/include/swift/AST/PrettyStackTrace.h b/include/swift/AST/PrettyStackTrace.h
index 51d047ecbb1b5..001c7609cb9f6 100644
--- a/include/swift/AST/PrettyStackTrace.h
+++ b/include/swift/AST/PrettyStackTrace.h
@@ -26,6 +26,7 @@
namespace clang {
class Type;
+ class ASTContext;
}
namespace swift {
@@ -51,7 +52,7 @@ class PrettyStackTraceLocation : public llvm::PrettyStackTraceEntry {
PrettyStackTraceLocation(const ASTContext &C, const char *action,
SourceLoc loc)
: Context(C), Loc(loc), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printDeclDescription(llvm::raw_ostream &out, const Decl *D,
@@ -65,7 +66,7 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceDecl(const char *action, const Decl *D)
: TheDecl(D), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
/// PrettyStackTraceAnyFunctionRef - Observe that we are processing a specific
@@ -76,7 +77,7 @@ class PrettyStackTraceAnyFunctionRef : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceAnyFunctionRef(const char *action, AnyFunctionRef ref)
: TheRef(ref), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printExprDescription(llvm::raw_ostream &out, Expr *E,
@@ -91,7 +92,7 @@ class PrettyStackTraceExpr : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceExpr(const ASTContext &C, const char *action, Expr *E)
: Context(C), TheExpr(E), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printStmtDescription(llvm::raw_ostream &out, Stmt *S,
@@ -106,7 +107,7 @@ class PrettyStackTraceStmt : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceStmt(const ASTContext &C, const char *action, Stmt *S)
: Context(C), TheStmt(S), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printPatternDescription(llvm::raw_ostream &out, Pattern *P,
@@ -121,7 +122,7 @@ class PrettyStackTracePattern : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTracePattern(const ASTContext &C, const char *action, Pattern *P)
: Context(C), ThePattern(P), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printTypeDescription(llvm::raw_ostream &out, Type T,
@@ -135,18 +136,20 @@ class PrettyStackTraceType : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceType(const ASTContext &C, const char *action, Type type)
: Context(C), TheType(type), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
/// PrettyStackTraceClangType - Observe that we are processing a
/// specific Clang type.
class PrettyStackTraceClangType : public llvm::PrettyStackTraceEntry {
+ const clang::ASTContext &Context;
const clang::Type *TheType;
const char *Action;
public:
- PrettyStackTraceClangType(const char *action, const clang::Type *type)
- : TheType(type), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ PrettyStackTraceClangType(clang::ASTContext &ctx,
+ const char *action, const clang::Type *type)
+ : Context(ctx), TheType(type), Action(action) {}
+ virtual void print(llvm::raw_ostream &OS) const override;
};
/// Observe that we are processing a specific type representation.
@@ -158,7 +161,7 @@ class PrettyStackTraceTypeRepr : public llvm::PrettyStackTraceEntry {
PrettyStackTraceTypeRepr(const ASTContext &C, const char *action,
TypeRepr *type)
: Context(C), TheType(type), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
/// PrettyStackTraceConformance - Observe that we are processing a
@@ -171,7 +174,7 @@ class PrettyStackTraceConformance : public llvm::PrettyStackTraceEntry {
PrettyStackTraceConformance(const ASTContext &C, const char *action,
const ProtocolConformance *conformance)
: Context(C), Conformance(conformance), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printConformanceDescription(llvm::raw_ostream &out,
@@ -217,7 +220,7 @@ class PrettyStackTraceDifferentiabilityWitness
PrettyStackTraceDifferentiabilityWitness(
const char *action, const SILDifferentiabilityWitnessKey key)
: Key(key), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
void printDifferentiabilityWitnessDescription(
@@ -232,7 +235,7 @@ class PrettyStackTraceDeclContext : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceDeclContext(const char *action, const DeclContext *DC)
: DC(DC), Action(action) {}
- virtual void print(llvm::raw_ostream &OS) const;
+ virtual void print(llvm::raw_ostream &OS) const override;
};
} // end namespace swift
diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h
index 38611e1245b56..2b99e4ac1e66b 100644
--- a/include/swift/AST/PrintOptions.h
+++ b/include/swift/AST/PrintOptions.h
@@ -24,7 +24,7 @@
namespace swift {
class ASTPrinter;
-class GenericEnvironment;
+class GenericSignatureImpl;
class CanType;
class Decl;
class Pattern;
@@ -380,10 +380,13 @@ struct PrintOptions {
/// has no associated doc-comment by itself.
bool CascadeDocComment = false;
+ static const std::function
+ defaultPrintExtensionContentAsMembers;
+
/// Whether to print the content of an extension decl inside the type decl where it
/// extends from.
std::function printExtensionContentAsMembers =
- [] (const ExtensionDecl *) { return false; };
+ PrintOptions::defaultPrintExtensionContentAsMembers;
/// How to print the keyword argument and parameter name in functions.
ArgAndParamPrintingMode ArgAndParamPrinting =
@@ -423,8 +426,8 @@ struct PrintOptions {
/// Replaces the name of private and internal properties of types with '_'.
bool OmitNameOfInaccessibleProperties = false;
- /// Print dependent types as references into this generic environment.
- GenericEnvironment *GenericEnv = nullptr;
+ /// Use this signature to re-sugar dependent types.
+ const GenericSignatureImpl *GenericSig = nullptr;
/// Print types with alternative names from their canonical names.
llvm::DenseMap