Skip to content

Commit

Permalink
Merge pull request #4587 from swiftwasm/main
Browse files Browse the repository at this point in the history
[pull] swiftwasm from main
  • Loading branch information
kateinoigakukun committed May 25, 2022
2 parents f8cea25 + 3c0b1ab commit 090d45d
Show file tree
Hide file tree
Showing 55 changed files with 4,426 additions and 391 deletions.
84 changes: 84 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,86 @@ _**Note:** This is in reverse chronological order, so newer entries are added to

## Swift 5.7

* [SE-0309][]:

Protocols with associated types and `Self` requirements can now be used as the
types of values with the `any` keyword.

Protocol methods that return associated types can be called on an `any` type;
the result is type-erased to the associated type's upper bound, which is another
`any` type having the same constraints as the associated type. For example:

```swift
protocol Surface {...}

protocol Solid {
associatedtype SurfaceType: Surface
func boundary() -> SurfaceType
}

let solid: any Solid = ...

// Type of 'boundary' is 'any Surface'
let boundary = solid.boundary()
```

Protocol methods that take an associated type or `Self` cannot be used with `any`,
however in conjunction with [SE-0352][], you can pass the `any` type to a function
taking a generic parameter constrained to the protocol. Within the generic context,
type relationships are explicit and all protocol methods can be used.

* [SE-0346][]:

Protocols can now declare a list of one or more primary associated types:

```swift
protocol Graph<Vertex, Edge> {
associatedtype Vertex
associatedtype Edge
}
```

A protocol-constrained type like `Graph<Int>` can now be written anywhere that
expects the right-hand side of a protocol conformance requirement:

```swift
func shortestPath<V, E>(_: some Graph<V>, from: V, to: V) -> [E]

extension Graph<Int> {...}

func build() -> some Graph<String> {}
```

A protocol-constrained type is equivalent to a conformance requirement to the protocol
itself together with a same-type requirement constraining the primary associated type.
The first two examples above are equivalent to the following:

```swift
func shortestPath<V, E, G>(_: G, from: V, to: V) -> [E]
where G: Graph, G.Vertex == V, G.Edge == V

extension Graph where Vertex == Int {...}
```

The `build()` function returning `some Graph<String>` cannot be written using a `where`
clause; this is an example of a constrained opaque result type, which could not be written
before.

* [SE-0353][]:

Further generalizing the above, protocol-constrained types can also be used with `any`:

```swift
func findBestGraph(_: [any Graph<Int>]) -> any Graph<Int> {...}
```

* [SE-0358][]:

Various protocols in the standard library now declare primary associated types, for
example `Sequence` and `Collection` declare a single primary associated type `Element`.
For example, this allows writing down the types `some Collection<Int>` and
`any Collection<Int>`.

* References to `optional` methods on a protocol metatype, as well as references to dynamically looked up methods on the `AnyObject` metatype are now supported. These references always have the type of a function that accepts a single argument and returns an optional value of function type:

```swift
Expand Down Expand Up @@ -9261,6 +9341,7 @@ Swift 1.0
[SE-0300]: <https://github.com/apple/swift-evolution/blob/main/proposals/0300-continuation.md>
[SE-0302]: <https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md>
[SE-0306]: <https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md>
[SE-0309]: <https://github.com/apple/swift-evolution/blob/main/proposals/0309-unlock-existential-types-for-all-protocols.md>
[SE-0310]: <https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md>
[SE-0311]: <https://github.com/apple/swift-evolution/blob/main/proposals/0311-task-locals.md>
[SE-0313]: <https://github.com/apple/swift-evolution/blob/main/proposals/0313-actor-isolation-control.md>
Expand All @@ -9283,9 +9364,12 @@ Swift 1.0
[SE-0341]: <https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md>
[SE-0343]: <https://github.com/apple/swift-evolution/blob/main/proposals/0343-top-level-concurrency.md>
[SE-0345]: <https://github.com/apple/swift-evolution/blob/main/proposals/0345-if-let-shorthand.md>
[SE-0346]: <https://github.com/apple/swift-evolution/blob/main/proposals/0346-light-weight-same-type-syntax.md>
[SE-0347]: <https://github.com/apple/swift-evolution/blob/main/proposals/0347-type-inference-from-default-exprs.md>
[SE-0349]: <https://github.com/apple/swift-evolution/blob/main/proposals/0349-unaligned-loads-and-stores.md>
[SE-0352]: <https://github.com/apple/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md>
[SE-0353]: <https://github.com/apple/swift-evolution/blob/main/proposals/0353-constrained-existential-types.md>
[SE-0358]: <https://github.com/apple/swift-evolution/blob/main/proposals/0358-primary-associated-types-in-stdlib.md>

[SR-75]: <https://bugs.swift.org/browse/SR-75>
[SR-106]: <https://bugs.swift.org/browse/SR-106>
Expand Down
45 changes: 45 additions & 0 deletions docs/DevelopmentTips.md
Expand Up @@ -20,6 +20,25 @@ Going further, for various reasons the standard library has lots of warnings. Th

Copy the invocation that has ` -o <build-path>/swift-macosx-x86_64/stdlib/public/core/iphonesimulator/i386/Swift.o`, so that we can perform the actual call to swiftc ourselves. Tack on `-suppress-warnings` at the end, and now we have the command to just build `Swift.o` for i386 while only displaying the actual errors.

### Choosing the bootstrapping mode
By default, the compiler builds with the `boostrapping-with-hostlibs` (macOS) or `bootstrapping` (Linux) bootstrapping mode. To speed up local development it's recommended to build with the `hosttools` mode: `utils/build-script --bootstrapping=hosttools`.

It requires a recently new swift toolchain to be installed on your build machine. On macOS this comes with your Xcode installation.

Not that changing the bootstrapping mode needs a reconfiguration.

### Working with two build directories
For developing and debugging you are probably building a debug configuration of swift. But it's often beneficial to also build a release-assert configuration in parallel (`utils/build-script -R`).

The standard library takes very long to build with a debug compiler. It's much faster to build everything (including the standard library) with a release compiler and only the swift-frontend (with `ninja swift-frontend`) in debug. Then copy the release-built standard library to the debug build:
```
src=/path/to/build/Ninja-ReleaseAssert/swift-macosx-x86_64
dst=/path/to/build/Ninja-DebugAssert/swift-macosx-x86_64
cp -r $src/stdlib $dst/
cp -r $src/lib/swift/macosx $dst/lib/swift/
cp -r $src/lib/swift/shims $dst/lib/swift/
```

### Use sccache to cache build artifacts

Compilation times for the compiler and the standard library can be agonizing, especially for cold builds. This is particularly painful if
Expand Down Expand Up @@ -65,3 +84,29 @@ For example, to have `build-script` spawn only one link job at a time, we can in
```
build-script --llvm-cmake-options==-DLLVM_PARALLEL_LINK_JOBS=1 --swift-cmake-options=-DSWIFT_PARALLEL_LINK_JOBS=1
```

## Using ninja with Xcode

Although it's possible to build the swift compiler entirely with Xcode (`--xcode`), often it's better to build with _ninja_ and use Xcode for editing and debugging.
This is very convenient because you get the benefits of the ninja build system and all the benefits of the Xcode IDE, like code completion, refactoring, debugging, etc.

To setup this environment a few steps are necessary:
* Create a new workspace.
* Create Xcode projects for LLVM and Swift with `utils/build-script --skip-build --xcode --skip-early-swift-driver`. Beside configuring, this needs to build a few LLVM files which are needed to configure the swift project.
* Add the generated LLVM and Swift projects to your workspace. They can be found in the build directories `build/Xcode-DebugAssert/llvm-macosx-x86_64/LLVM.xcodeproj` and `build/Xcode-DebugAssert/swift-macosx-x86_64/Swift.xcodeproj`.
* Add the `swift/SwiftCompilerSources` package to the workspace.
* Create a new empty project `build-targets` (or however you want to name it) in the workspace, using the "External Build System" template.
* For each compiler tool you want to build (`swift-frontend`, `sil-opt`, etc.), add an "External Build System" target to the `build-targets` project.
* In the "Info" section of the target configuration, set:
* the _Build Tool_ to the full path of the `ninja` command
* the _Argument_ to the tool name (e.g. `swift-frontend`)
* the _Directory_ to the ninja swift build directory, e.g. `/absolute/path/to/build/Ninja-DebugAssert/swift-macosx-x86_64`. For debugging to work, this has to be a debug build of course.
* For each target, create a new scheme:
* In the _Build_ section add the corresponding build target that you created before.
* In the _Run/Info_ section select the built _Executable_ in the build directory (e.g. `/absolute/path/to/build/Ninja-DebugAssert/swift-macosx-x86_64/bin/swift-frontend`).
* In the _Run/Arguments_ section you can set the command line arguments with which you want to run the compiler tool.
* In the _Run/Options_ section you can set the working directory for debugging.

Now you are all set. You can build and debug like with a native Xcode project.

If the project structure changes, e.g. new source files are added or deleted, you just have to re-create the LLVM and Swift projects with `utils/build-script --skip-build --xcode --skip-early-swift-driver`.
2 changes: 2 additions & 0 deletions docs/HowToGuides/GettingStarted.md
Expand Up @@ -282,6 +282,8 @@ The additional flexibility comes with two issues: (1) consuming much more disk
space and (2) you need to maintain the two builds in sync, which needs extra
care when moving across branches.

It is even possible to integrate the Ninja build into Xcode. For details on how to set this up see [Using Ninja with Xcode in DevelopmentTips.md](/docs/DevelopmentTips.md#using-ninja-with-xcode).

### Troubleshooting build issues

- Double-check that all projects are checked out at the right branches.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/DiagnosticsClangImporter.def
Expand Up @@ -118,7 +118,7 @@ WARNING(nonmutating_without_mutable_fields,none,
ERROR(module_map_not_found, none, "module map file '%0' not found", (StringRef))

WARNING(libstdcxx_not_found, none,
"libstdc++ not found for '$0'; C++ stdlib may be unavailable",
"libstdc++ not found for '%0'; C++ stdlib may be unavailable",
(StringRef))

NOTE(macro_not_imported_unsupported_operator, none, "operator not supported in macro arithmetic", ())
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Expand Up @@ -4709,6 +4709,9 @@ ERROR(unchecked_not_inheritance_clause,none,
ERROR(unchecked_not_existential,none,
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))

ERROR(redundant_any_in_existential,none,
"redundant 'any' has no effect on existential type %0",
(Type))
ERROR(any_not_existential,none,
"'any' has no effect on %select{concrete type|type parameter}0 %1",
(bool, Type))
Expand Down
21 changes: 21 additions & 0 deletions include/swift/Parse/SyntaxRegexFallbackLexing.h
@@ -0,0 +1,21 @@
//===--- SyntaxRegexFallbackLexing.h --------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 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
//
//===----------------------------------------------------------------------===//

namespace swift {
/// SwiftSyntax parsing currently doesn't link against
/// SwiftExperimentalStringProcessing and is thus missing the regex lexing
/// functions defined in it. This registers a fallback regex-lexing function
/// implemented in C++ that is sufficient to generate a valid SwiftSyntax tree.
/// The regex parser registered by this function will accept all regex literals
/// and is not suited for normal compilation.
void registerSyntaxFallbackRegexParser();
} // end namespace swift
78 changes: 77 additions & 1 deletion include/swift/SIL/BasicBlockUtils.h
Expand Up @@ -13,8 +13,9 @@
#ifndef SWIFT_SIL_BASICBLOCKUTILS_H
#define SWIFT_SIL_BASICBLOCKUTILS_H

#include "swift/SIL/SILValue.h"
#include "swift/SIL/BasicBlockBits.h"
#include "swift/SIL/BasicBlockDatastructures.h"
#include "swift/SIL/SILValue.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
Expand Down Expand Up @@ -155,6 +156,81 @@ void findJointPostDominatingSet(
bool checkDominates(SILBasicBlock *sourceBlock, SILBasicBlock *destBlock);
#endif

/// Walk depth-first the region backwards reachable from the provided roots
/// constrained by \p region's \p isInRegion member function.
///
/// interface Region {
/// /// Whether the indicated basic block is within the region of the graph
/// /// that should be traversed.
/// bool isInRegion(SILBasicBlock *)
/// }
template <typename Region>
struct SILCFGBackwardDFS {
Region &region;
ArrayRef<SILBasicBlock *> roots;
Optional<SmallVector<SILBasicBlock *, 16>> cachedPostOrder;
Optional<BasicBlockSet> cachedVisited;

SILCFGBackwardDFS(Region &region, ArrayRef<SILBasicBlock *> roots)
: region(region), roots(roots) {}

/// Visit the blocks of the region in post-order.
///
/// interface Visitor {
/// /// Visit each block in topological order.
/// void visit(SILBasicBlock *)
/// }
template <typename Visitor>
void visitPostOrder(Visitor &visitor) {
if (roots.empty())
return;
auto *function = roots.front()->getParent();
cachedVisited.emplace(function);
for (auto *root : roots) {
SmallVector<std::pair<SILBasicBlock *, SILBasicBlock::pred_iterator>, 32>
stack;
if (!region.isInRegion(root))
continue;
stack.push_back({root, root->pred_begin()});
while (!stack.empty()) {
while (stack.back().second != stack.back().first->pred_end()) {
auto predecessor = *stack.back().second;
stack.back().second++;
if (!region.isInRegion(predecessor))
continue;
if (cachedVisited->insert(predecessor))
stack.push_back({predecessor, predecessor->pred_begin()});
}
visitor.visit(stack.back().first);
stack.pop_back();
}
}
}

/// Visit the region in post-order and cache the visited blocks.
void cachePostOrder() {
if (cachedPostOrder)
return;
struct Visitor {
SILCFGBackwardDFS<Region> &dfs;
void visit(SILBasicBlock *block) {
dfs.cachedPostOrder->push_back(block);
}
};
cachedPostOrder.emplace();
Visitor visitor{*this};
visitPostOrder(visitor);
}

/// The region in post-order.
ArrayRef<SILBasicBlock *> postOrder() {
cachePostOrder();
return *cachedPostOrder;
};

/// The region in reverse post-order.
auto reversePostOrder() { return llvm::reverse(postOrder()); }
};
} // namespace swift

#endif
2 changes: 1 addition & 1 deletion include/swift/SIL/SILBasicBlock.h
Expand Up @@ -48,7 +48,7 @@ public SwiftObjectHeader {
/// A backreference to the containing SILFunction.
SILFunction *Parent;

/// PrevList - This is a list of all of the terminator operands that are
/// PredList - This is a list of all of the terminator operands that are
/// branching to this block, forming the predecessor list. This is
/// automatically managed by the SILSuccessor class.
SILSuccessor *PredList = nullptr;
Expand Down

0 comments on commit 090d45d

Please sign in to comment.