Skip to content

Commit 12f8b3d

Browse files
Merge pull request #4596 from swiftwasm/katei/merge-main-2022-05-27
Merge main 2022-05-27
2 parents 090d45d + f7cfc7f commit 12f8b3d

File tree

182 files changed

+2716
-1127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+2716
-1127
lines changed

CHANGELOG.md

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,83 @@ _**Note:** This is in reverse chronological order, so newer entries are added to
55

66
## Swift 5.7
77

8+
* [SE-0338][]:
9+
10+
Non-isolated async functions now always execute on the global concurrent pool,
11+
so calling a non-isolated async function from actor-isolated code will leave
12+
the actor. For example:
13+
14+
```swift
15+
class C { }
16+
17+
func f(_: C) async { /* always executes on the global concurrent pool */ }
18+
19+
actor A {
20+
func g(c: C) async {
21+
/* always executes on the actor */
22+
print("on the actor")
23+
24+
await f(c)
25+
}
26+
}
27+
```
28+
29+
Prior to this change, the call from `f` to `g` might have started execution of
30+
`g` on the actor, which could lead to actors being busy longer than strictly
31+
necessary. Now, the non-isolated async function will always hop to the global
32+
cooperative pool, not run on the actor. This can result in a behavior change
33+
for programs that assumed that a non-isolated async function called from a
34+
`@MainActor` context will be executed on the main actor, although such
35+
programs were already technically incorrect.
36+
37+
Additionally, when leaving an actor to execution on the global cooperative
38+
pool, `Sendable` checking will be performed, so the compiler will emit a
39+
diagnostic in the call to `f` if `c` is not of `Sendable` type.
40+
41+
* [SE-0350][]:
42+
43+
The standard library has a new `Regex<Output>` type.
44+
45+
This type represents an _extended regular expression_, allowing more fluent
46+
string processing operations. A `Regex` may be created by
47+
[initialization from a string][SE-0355]:
48+
```
49+
let pattern = "a[bc]+" // matches "a" followed by one or more instances
50+
// of either "b" or "c"
51+
let regex = try! Regex(pattern)
52+
```
53+
Or via a [regex literal][SE-0354]:
54+
```
55+
let regex = #/a[bc]+/#
56+
```
57+
In Swift 6, `/` will also be supported as a delimiter for `Regex` literals.
58+
You can enable this mode in Swift 5.7 with the `-enable-bare-slash-regex`
59+
flag. Doing so will cause some existing expressions that use `/` as an
60+
operator to no longer compile; you can add parentheses or line breaks as a
61+
workaround.
62+
63+
There are [new string-processing algorithms][SE-0357] that support
64+
`String`, `Regex` and arbitrary `Collection` types.
65+
66+
* [SE-0329][]:
67+
New types representing time and clocks were introduced. This includes a protocol `Clock` defining clocks which allow for defining a concept of now and a way to wake up after a given instant. Additionally a new protocol `InstantProtocol` for defining instants in time was added. Furthermore a new protocol `DurationProtocol` was added to define an elapsed duration between two given `InstantProtocol` types. Most commonly the `Clock` types for general use are the `SuspendingClock` and `ContinuousClock` which represent the most fundamental clocks for the system. The `SuspendingClock` type does not progress while the machine is suspended whereas the `ContinuousClock` progresses no matter the state of the machine.
68+
69+
```swift
70+
func delayedHello() async throws {
71+
try await Task.sleep(until: .now + .milliseconds(123), clock: .continuous)
72+
print("hello delayed world")
73+
}
74+
```
75+
76+
`Clock` also has methods to measure the elapsed duration of the execution of work. In the case of the `SuspendingClock` and `ContinuousClock` this measures with high resolution and is suitable for benchmarks.
77+
78+
```swift
79+
let clock = ContinuousClock()
80+
let elapsed = clock.measure {
81+
someLongRunningWork()
82+
}
83+
```
84+
885
* [SE-0309][]:
986

1087
Protocols with associated types and `Self` requirements can now be used as the
@@ -72,10 +149,26 @@ _**Note:** This is in reverse chronological order, so newer entries are added to
72149

73150
* [SE-0353][]:
74151

75-
Further generalizing the above, protocol-constrained types can also be used with `any`:
152+
Protocols with primary associated types can now be used in existential types,
153+
enabling same-type constraints on those associated types.
154+
155+
```
156+
let strings: any Collection<String> = [ "Hello" ]
157+
```
158+
159+
Note that language features requiring runtime support like dynamic casts
160+
(`is`, `as?`, `as!`), as well as generic usages of parameterized existentials
161+
in generic types (e.g. `Array<any Collection<Int>>`) involve additional
162+
availability checks to use. Back-deploying usages in generic position can be
163+
worked around with a generic type-erasing wrapper struct, which is now much
164+
simpler to implement:
76165

77166
```swift
78-
func findBestGraph(_: [any Graph<Int>]) -> any Graph<Int> {...}
167+
struct AnyCollection<T> {
168+
var wrapped: any Collection<T>
169+
}
170+
171+
let arrayOfCollections: [AnyCollection<T>] = [ /**/ ]
79172
```
80173

81174
* [SE-0358][]:
@@ -9354,21 +9447,27 @@ Swift 1.0
93549447
[SE-0326]: <https://github.com/apple/swift-evolution/blob/main/proposals/0326-extending-multi-statement-closure-inference.md>
93559448
[SE-0327]: <https://github.com/apple/swift-evolution/blob/main/proposals/0327-actor-initializers.md>
93569449
[SE-0328]: <https://github.com/apple/swift-evolution/blob/main/proposals/0328-structural-opaque-result-types.md>
9450+
[SE-0329]: <https://github.com/apple/swift-evolution/blob/main/proposals/0329-clock-instant-duration.md>
93579451
[SE-0331]: <https://github.com/apple/swift-evolution/blob/main/proposals/0331-remove-sendable-from-unsafepointer.md>
93589452
[SE-0333]: <https://github.com/apple/swift-evolution/blob/main/proposals/0333-with-memory-rebound.md>
93599453
[SE-0334]: <https://github.com/apple/swift-evolution/blob/main/proposals/0334-pointer-usability-improvements.md>
93609454
[SE-0335]: <https://github.com/apple/swift-evolution/blob/main/proposals/0335-existential-any.md>
93619455
[SE-0336]: <https://github.com/apple/swift-evolution/blob/main/proposals/0336-distributed-actor-isolation.md>
93629456
[SE-0337]: <https://github.com/apple/swift-evolution/blob/main/proposals/0337-support-incremental-migration-to-concurrency-checking.md>
9457+
[SE-0338]: <https://github.com/apple/swift-evolution/blob/main/proposals/0338-clarify-execution-non-actor-async.md>
93639458
[SE-0340]: <https://github.com/apple/swift-evolution/blob/main/proposals/0340-swift-noasync.md>
93649459
[SE-0341]: <https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md>
93659460
[SE-0343]: <https://github.com/apple/swift-evolution/blob/main/proposals/0343-top-level-concurrency.md>
93669461
[SE-0345]: <https://github.com/apple/swift-evolution/blob/main/proposals/0345-if-let-shorthand.md>
93679462
[SE-0346]: <https://github.com/apple/swift-evolution/blob/main/proposals/0346-light-weight-same-type-syntax.md>
93689463
[SE-0347]: <https://github.com/apple/swift-evolution/blob/main/proposals/0347-type-inference-from-default-exprs.md>
93699464
[SE-0349]: <https://github.com/apple/swift-evolution/blob/main/proposals/0349-unaligned-loads-and-stores.md>
9465+
[SE-0350]: <https://github.com/apple/swift-evolution/blob/main/proposals/0350-regex-type-overview.md>
93709466
[SE-0352]: <https://github.com/apple/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md>
93719467
[SE-0353]: <https://github.com/apple/swift-evolution/blob/main/proposals/0353-constrained-existential-types.md>
9468+
[SE-0354]: <https://github.com/apple/swift-evolution/blob/main/proposals/0354-regex-literals.md>
9469+
[SE-0355]: <https://github.com/apple/swift-evolution/blob/main/proposals/0355-regex-syntax-run-time-construction.md>
9470+
[SE-0357]: <https://github.com/apple/swift-evolution/blob/main/proposals/0357-regex-string-processing-algorithms.md>
93729471
[SE-0358]: <https://github.com/apple/swift-evolution/blob/main/proposals/0358-primary-associated-types-in-stdlib.md>
93739472

93749473
[SR-75]: <https://bugs.swift.org/browse/SR-75>

include/swift/AST/Availability.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ class VersionRange {
9393
return getLowerEndpoint() >= Other.getLowerEndpoint();
9494
}
9595

96+
// Returns true if all the versions in the Other range are versions in this
97+
// range and the ranges are not equal.
98+
bool isSupersetOf(const VersionRange &Other) const {
99+
if (isEmpty() || Other.isAll())
100+
return false;
101+
102+
if (isAll() || Other.isEmpty())
103+
return true;
104+
105+
return getLowerEndpoint() < Other.getLowerEndpoint();
106+
}
107+
96108
/// Mutates this range to be a best-effort underapproximation of
97109
/// the intersection of itself and Other. This is the
98110
/// meet operation (greatest lower bound) in the version range lattice.
@@ -244,10 +256,17 @@ class AvailabilityContext {
244256
/// Returns true if \p other makes stronger guarantees than this context.
245257
///
246258
/// That is, `a.isContainedIn(b)` implies `a.union(b) == b`.
247-
bool isContainedIn(AvailabilityContext other) const {
259+
bool isContainedIn(const AvailabilityContext &other) const {
248260
return OSVersion.isContainedIn(other.OSVersion);
249261
}
250262

263+
/// Returns true if \p other is a strict subset of this context.
264+
///
265+
/// That is, `a.isSupersetOf(b)` implies `a != b` and `a.union(b) == a`.
266+
bool isSupersetOf(const AvailabilityContext &other) const {
267+
return OSVersion.isSupersetOf(other.OSVersion);
268+
}
269+
251270
/// Returns true if this context has constraints that make it impossible to
252271
/// actually occur.
253272
///
@@ -272,7 +291,7 @@ class AvailabilityContext {
272291
///
273292
/// As an example, this is used when figuring out the required availability
274293
/// for a type that references multiple nominal decls.
275-
void intersectWith(AvailabilityContext other) {
294+
void intersectWith(const AvailabilityContext &other) {
276295
OSVersion.intersectWith(other.getOSVersion());
277296
}
278297

@@ -283,7 +302,7 @@ class AvailabilityContext {
283302
/// treating some invalid deployment environments as available.
284303
///
285304
/// As an example, this is used for the true branch of `#available`.
286-
void constrainWith(AvailabilityContext other) {
305+
void constrainWith(const AvailabilityContext &other) {
287306
OSVersion.constrainWith(other.getOSVersion());
288307
}
289308

@@ -295,7 +314,7 @@ class AvailabilityContext {
295314
///
296315
/// As an example, this is used for the else branch of a conditional with
297316
/// multiple `#available` checks.
298-
void unionWith(AvailabilityContext other) {
317+
void unionWith(const AvailabilityContext &other) {
299318
OSVersion.unionWith(other.getOSVersion());
300319
}
301320

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1816,7 +1816,10 @@ ERROR(version_component_not_number,none,
18161816
ERROR(compiler_version_too_many_components,none,
18171817
"compiler version must not have more than five components", ())
18181818
WARNING(unused_compiler_version_component,NoUsage,
1819-
"the second version component is not used for comparison", ())
1819+
"the second version component is not used for comparison in legacy "
1820+
"compiler versions%select{|; are you trying to encode a new Swift "
1821+
"compiler version for compatibility with legacy compilers?}0",
1822+
(bool))
18201823
ERROR(empty_version_component,none,
18211824
"found empty version component", ())
18221825
ERROR(compiler_version_component_out_of_range,none,

include/swift/AST/DiagnosticsSema.def

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,9 @@ NOTE(non_sendable_nominal,none,
19651965
NOTE(add_nominal_sendable_conformance,none,
19661966
"consider making %0 %1 conform to the 'Sendable' protocol",
19671967
(DescriptiveDeclKind, DeclName))
1968+
NOTE(add_generic_parameter_sendable_conformance,none,
1969+
"consider making generic parameter %0 conform to the 'Sendable' protocol",
1970+
(Type))
19681971
REMARK(add_predates_concurrency_import,none,
19691972
"add '@preconcurrency' to %select{suppress|treat}0 "
19701973
"'Sendable'-related %select{warnings|errors}0 from module %1"
@@ -4570,6 +4573,12 @@ ERROR(concurrent_access_of_inout_param,none,
45704573
ERROR(non_sendable_capture,none,
45714574
"capture of %1 with non-sendable type %0 in a `@Sendable` closure",
45724575
(Type, DeclName))
4576+
ERROR(implicit_async_let_non_sendable_capture,none,
4577+
"capture of %1 with non-sendable type %0 in 'async let' binding",
4578+
(Type, DeclName))
4579+
ERROR(implicit_non_sendable_capture,none,
4580+
"implicit capture of %1 requires that %0 conforms to `Sendable`",
4581+
(Type, DeclName))
45734582

45744583
NOTE(actor_isolated_sync_func,none,
45754584
"calls to %0 %1 from outside of its actor context are "
@@ -4648,9 +4657,10 @@ ERROR(isolated_parameter_not_actor,none,
46484657

46494658
WARNING(non_sendable_param_type,none,
46504659
"non-sendable type %0 %select{passed in call to %4 %2 %3|"
4660+
"exiting %4 context in call to non-isolated %2 %3|"
46514661
"passed in implicitly asynchronous call to %4 %2 %3|"
4652-
"in parameter of %4 %2 %3 satisfying non-isolated protocol "
4653-
"requirement|"
4662+
"in parameter of %4 %2 %3 satisfying protocol requirement|"
4663+
"in parameter of %4 overriding %2 %3|"
46544664
"in parameter of %4 '@objc' %2 %3}1 cannot cross actor boundary",
46554665
(Type, unsigned, DescriptiveDeclKind, DeclName, ActorIsolation))
46564666
WARNING(non_sendable_call_param_type,none,
@@ -4659,8 +4669,10 @@ WARNING(non_sendable_call_param_type,none,
46594669
(Type, bool, ActorIsolation))
46604670
WARNING(non_sendable_result_type,none,
46614671
"non-sendable type %0 returned by %select{call to %4 %2 %3|"
4672+
"call from %4 context to non-isolated %2 %3|"
46624673
"implicitly asynchronous call to %4 %2 %3|"
4663-
"%4 %2 %3 satisfying non-isolated protocol requirement|"
4674+
"%4 %2 %3 satisfying protocol requirement|"
4675+
"%4 overriding %2 %3|"
46644676
"%4 '@objc' %2 %3}1 cannot cross actor boundary",
46654677
(Type, unsigned, DescriptiveDeclKind, DeclName, ActorIsolation))
46664678
WARNING(non_sendable_call_result_type,none,
@@ -4670,8 +4682,10 @@ WARNING(non_sendable_call_result_type,none,
46704682
WARNING(non_sendable_property_type,none,
46714683
"non-sendable type %0 in %select{"
46724684
"%select{asynchronous access to %5 %1 %2|"
4685+
"asynchronous access from %5 context to non-isolated %1 %2|"
46734686
"implicitly asynchronous access to %5 %1 %2|"
4674-
"conformance of %5 %1 %2 to non-isolated protocol requirement|"
4687+
"conformance of %5 %1 %2 to protocol requirement|"
4688+
"%5 overriding %1 %2|"
46754689
"%5 '@objc' %1 %2}4|captured local %1 %2}3 cannot "
46764690
"cross %select{actor|task}3 boundary",
46774691
(Type, DescriptiveDeclKind, DeclName, bool, unsigned, ActorIsolation))

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ struct PrintOptions {
285285
/// types.
286286
bool PrintExplicitAny = false;
287287

288+
/// Whether to desugar the constraint for an existential type.
289+
bool DesugarExistentialConstraint = false;
290+
288291
/// Whether to skip keywords with a prefix of underscore such as __consuming.
289292
bool SkipUnderscoredKeywords = false;
290293

include/swift/AST/TypeRefinementContext.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,19 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
5454
/// The root refinement context.
5555
Root,
5656

57-
/// The context was introduced by a declaration (e.g., the body of a
58-
/// function declaration or the contents of a class declaration).
57+
/// The context was introduced by a declaration with an explicit
58+
/// availability attribute. The context contains both the signature and the
59+
/// body of the declaration.
5960
Decl,
6061

61-
/// The context was introduced by an API boundary; that is, we are in
62-
/// a module with library evolution enabled and the parent context's
63-
/// contents can be visible to the module's clients, but this context's
64-
/// contents are not.
65-
APIBoundary,
62+
/// The context was introduced implicitly by a declaration. The context may
63+
/// cover the entire declaration or it may cover a subset of it. For
64+
/// example, a public, non-inlinable function declaration in an API module
65+
/// will have at least two associated contexts: one for the entire
66+
/// declaration at the declared availability of the API and a nested
67+
/// implicit context for the body of the function, which will always run at
68+
/// the deployment target of the library.
69+
DeclImplicit,
6670

6771
/// The context was introduced for the Then branch of an IfStmt.
6872
IfStmtThenBranch,
@@ -131,7 +135,8 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
131135
}
132136

133137
Decl *getAsDecl() const {
134-
assert(IntroReason == Reason::Decl || IntroReason == Reason::APIBoundary);
138+
assert(IntroReason == Reason::Decl ||
139+
IntroReason == Reason::DeclImplicit);
135140
return D;
136141
}
137142

@@ -163,8 +168,8 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
163168

164169
SourceRange SrcRange;
165170

166-
/// A canonical availability info for this context, computed top-down from the root
167-
/// context (compilation deployment target).
171+
/// A canonical availability info for this context, computed top-down from the
172+
/// root context.
168173
AvailabilityContext AvailabilityInfo;
169174

170175
/// If this context was annotated with an availability attribute, this property captures that.
@@ -194,8 +199,8 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
194199

195200
/// Create a refinement context for the given declaration.
196201
static TypeRefinementContext *
197-
createForAPIBoundary(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent,
198-
const AvailabilityContext &Info, SourceRange SrcRange);
202+
createForDeclImplicit(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent,
203+
const AvailabilityContext &Info, SourceRange SrcRange);
199204

200205
/// Create a refinement context for the Then branch of the given IfStmt.
201206
static TypeRefinementContext *

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,6 @@ namespace swift {
326326
/// in calls to generic functions.
327327
bool EnableOpenedExistentialTypes = false;
328328

329-
/// Enable support for parameterized protocol types in existential
330-
/// position.
331-
bool EnableParameterizedExistentialTypes = false;
332-
333329
/// Enable experimental flow-sensitive concurrent captures.
334330
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;
335331

include/swift/Basic/Version.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,12 @@ class Version {
129129
/// Return this Version struct as the appropriate version string for APINotes.
130130
std::string asAPINotesVersionString() const;
131131

132-
/// Parse a version in the form used by the _compiler_version \#if condition.
132+
/// Parse a version in the form used by the _compiler_version(string-literal)
133+
/// \#if condition.
134+
///
135+
/// \note This is \em only used for the string literal version, so it includes
136+
/// backwards-compatibility logic to convert it to something that can be
137+
/// compared with a modern SWIFT_COMPILER_VERSION.
133138
static Optional<Version> parseCompilerVersionString(StringRef VersionString,
134139
SourceLoc Loc,
135140
DiagnosticEngine *Diags);

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,6 @@ def enable_explicit_existential_types :
543543
Flag<["-"], "enable-explicit-existential-types">,
544544
HelpText<"Enable experimental support for explicit existential types">;
545545

546-
def enable_parameterized_existential_types :
547-
Flag<["-"], "enable-parameterized-existential-types">,
548-
HelpText<"Enable experimental support for parameterized existential types">;
549-
550546
def enable_experimental_opened_existential_types :
551547
Flag<["-"], "enable-experimental-opened-existential-types">,
552548
HelpText<"Enable experimental support for implicitly opened existentials">;

include/swift/SILOptimizer/Analysis/Reachability.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class BackwardReachability {
149149
/// Effect effectForPhi(SILBasicBlock *);
150150
///
151151
/// /// The uses from which reachability will begin.
152-
/// ArrayRef<SILInstruction *> gens();
152+
/// iterable gens();
153153
/// }
154154
template <typename Effects>
155155
class IterativeBackwardReachability final {

0 commit comments

Comments
 (0)