Skip to content

Commit 7fe6916

Browse files
author
Max Moiseev
committed
Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines
2 parents 43a5d4c + 3d424b5 commit 7fe6916

File tree

178 files changed

+3421
-1976
lines changed

Some content is hidden

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

178 files changed

+3421
-1976
lines changed

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
Swift 3
33
-------
44

5+
* The @noescape attribute has been extended to be a more general type attribute.
6+
You can now declare values of @noescape function type, e.g. in manually
7+
curried function signatures. You can now also declare local variables of
8+
@noescape type, and use @noescape in typealiases. For example, this is now
9+
valid code:
10+
11+
func apply<T, U>(@noescape f: T -> U,
12+
@noescape g: (@noescape T -> U) -> U) -> U {
13+
return g(f)
14+
}
15+
516
* Curried function syntax has been removed, and now produces a compile-time
617
error.
718

benchmark/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ The benchmark driver will measure the time taken for `N = 1` and automatically c
177177
the necessary number of iterations `N` to run each benchmark in approximately one second,
178178
so the test should ideally run in a few milliseconds for `N = 1`. If the test contains
179179
any setup code before the loop, ensure the time spent on setup is insignificant compared to
180-
the time spent inside the loop (for `N = 1`) otherwise the automatic calculation of `N` might be
180+
the time spent inside the loop (for `N = 1`) -- otherwise the automatic calculation of `N` might be
181181
significantly off and any performance gains/regressions will be masked by the fixed setup time.
182182
If needed you can multiply N by a fixed amount (e.g. `1...100*N`) to achieve this.
183183

benchmark/scripts/Benchmark_Driver

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ def instrument_test(driver_path, test, num_samples):
106106
float(len(test_outputs))))
107107
avg_test_output[num_samples_index] = num_samples
108108
avg_test_output[min_index] = min(test_outputs,
109-
key=lambda x: x[min_index])[min_index]
109+
key=lambda x: int(x[min_index]))[min_index]
110110
avg_test_output[max_index] = max(test_outputs,
111-
key=lambda x: x[max_index])[max_index]
111+
key=lambda x: int(x[max_index]))[max_index]
112112
avg_test_output = map(str, avg_test_output)
113113

114114
return avg_test_output

benchmark/single-source/UTF8Decode.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import TestsUtils
1515
@inline(never)
1616
public func run_UTF8Decode(N: Int) {
1717
// 1-byte sequences
18-
// This test case is the longest as it's the most perfomance sensitive.
18+
// This test case is the longest as it's the most performance sensitive.
1919
let ascii = "Swift is a multi-paradigm, compiled programming language created for iOS, OS X, watchOS, tvOS and Linux development by Apple Inc. Swift is designed to work with Apple's Cocoa and Cocoa Touch frameworks and the large body of existing Objective-C code written for Apple products. Swift is intended to be more resilient to erroneous code (\"safer\") than Objective-C and also more concise. It is built with the LLVM compiler framework included in Xcode 6 and later and uses the Objective-C runtime, which allows C, Objective-C, C++ and Swift code to run within a single program."
2020
// 2-byte sequences
2121
let russian = "Ру́сский язы́к один из восточнославянских языков, национальный язык русского народа."

benchmark/utils/DriverUtils.swift

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ struct BenchResults {
2929
self.mean = mean
3030
self.sd = sd
3131
self.median = median
32+
33+
// Sanity the bounds of our results
34+
precondition(self.min <= self.max, "min should always be <= max")
35+
precondition(self.min <= self.mean, "min should always be <= mean")
36+
precondition(self.min <= self.median, "min should always be <= median")
37+
precondition(self.max >= self.mean, "max should always be >= mean")
38+
precondition(self.max >= self.median, "max should always be >= median")
3239
}
3340
}
3441

cmake/modules/AddSwift.cmake

+9-10
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,14 @@ function(_compile_swift_files dependency_target_out_var_name)
459459
FILES "${module_file}" "${module_doc_file}"
460460
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${library_subdir}")
461461

462+
set(line_directive_tool "${SWIFT_SOURCE_DIR}/utils/line-directive")
463+
set(swift_compiler_tool "${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swiftc")
464+
set(swift_compiler_tool_dep)
465+
if(SWIFT_BUILD_TOOLS)
466+
# Depend on the binary itself, in addition to the symlink.
467+
set(swift_compiler_tool_dep "swift")
468+
endif()
469+
462470
# Generate API notes if requested.
463471
set(command_create_apinotes)
464472
set(depends_create_apinotes)
@@ -470,11 +478,10 @@ function(_compile_swift_files dependency_target_out_var_name)
470478
set(apinote_file "${module_dir}/${apinote_module}.apinotesc")
471479
set(apinote_input_file
472480
"${SWIFT_API_NOTES_PATH}/${apinote_module}.apinotes")
473-
set(CLANG_APINOTES "${SWIFT_NATIVE_CLANG_TOOLS_PATH}/clang")
474481

475482
list(APPEND command_create_apinotes
476483
COMMAND
477-
"${CLANG_APINOTES}" "-cc1apinotes" "-yaml-to-binary"
484+
"${swift_compiler_tool}" "-apinotes" "-yaml-to-binary"
478485
"-o" "${apinote_file}"
479486
"-target" "${SWIFT_SDK_${SWIFTFILE_SDK}_ARCH_${SWIFTFILE_ARCHITECTURE}_TRIPLE}"
480487
"${apinote_input_file}")
@@ -487,14 +494,6 @@ function(_compile_swift_files dependency_target_out_var_name)
487494
endforeach()
488495
endif()
489496

490-
set(line_directive_tool "${SWIFT_SOURCE_DIR}/utils/line-directive")
491-
set(swift_compiler_tool "${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swiftc")
492-
set(swift_compiler_tool_dep)
493-
if(SWIFT_BUILD_TOOLS)
494-
# Depend on the binary itself, in addition to the symlink.
495-
set(swift_compiler_tool_dep "swift")
496-
endif()
497-
498497
# If there are more than one output files, we assume that they are specified
499498
# otherwise e.g. with an output file map.
500499
set(output_option)

docs/StdlibRationales.rst

+6-1
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,17 @@ functions don't return lazy collection wrappers that refer to users' closures.
159159
The consequence is that all users' closures are ``@noescape``, except in an
160160
explicitly lazy context.
161161

162-
Based on this rule, we conclude that ``enumerate(), ``zip()`` and
162+
Based on this rule, we conclude that ``enumerate()``, ``zip()`` and
163163
``reverse()`` return lazy wrappers, but ``filter()`` and ``map()`` don't. For
164164
the first three functions being lazy is the right default, since usually the
165165
result is immediately consumed by for-in, so we don't want to allocate memory
166166
for it.
167167

168+
Note that neither of the two ``sorted()`` methods (neither one that accepts a
169+
custom comparator closure, nor one that uses the ``Comparable`` conformance)
170+
can't be lazy, because the lazy version would be less efficient than the eager
171+
one.
172+
168173
A different design that was rejected is to preserve consistency with other
169174
strict functions by making these methods strict, but then client code needs to
170175
call an API with a different name, say ``lazyEnumerate()`` to opt into

include/swift/ABI/MetadataValues.h

+19-15
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,9 @@ enum class FunctionMetadataConvention: uint8_t {
448448
};
449449

450450
/// Flags in a function type metadata record.
451-
class FunctionTypeFlags {
452-
typedef size_t int_type;
451+
template <typename Runtime>
452+
class TargetFunctionTypeFlags {
453+
using int_type = typename Runtime::StoredSize;
453454
enum : int_type {
454455
NumArgumentsMask = 0x00FFFFFFU,
455456
ConventionMask = 0x0F000000U,
@@ -458,22 +459,24 @@ class FunctionTypeFlags {
458459
};
459460
int_type Data;
460461

461-
constexpr FunctionTypeFlags(int_type Data) : Data(Data) {}
462+
constexpr TargetFunctionTypeFlags(int_type Data) : Data(Data) {}
462463
public:
463-
constexpr FunctionTypeFlags() : Data(0) {}
464+
constexpr TargetFunctionTypeFlags() : Data(0) {}
464465

465-
constexpr FunctionTypeFlags withNumArguments(unsigned numArguments) const {
466-
return FunctionTypeFlags((Data & ~NumArgumentsMask) | numArguments);
466+
constexpr TargetFunctionTypeFlags withNumArguments(unsigned numArguments) const {
467+
return TargetFunctionTypeFlags((Data & ~NumArgumentsMask) | numArguments);
467468
}
468469

469-
constexpr FunctionTypeFlags withConvention(FunctionMetadataConvention c) const {
470-
return FunctionTypeFlags((Data & ~ConventionMask)
470+
constexpr TargetFunctionTypeFlags<Runtime>
471+
withConvention(FunctionMetadataConvention c) const {
472+
return TargetFunctionTypeFlags((Data & ~ConventionMask)
471473
| (int_type(c) << ConventionShift));
472474
}
473475

474-
constexpr FunctionTypeFlags withThrows(bool throws) const {
475-
return FunctionTypeFlags((Data & ~ThrowsMask)
476-
| (throws ? ThrowsMask : 0));
476+
constexpr TargetFunctionTypeFlags<Runtime>
477+
withThrows(bool throws) const {
478+
return TargetFunctionTypeFlags<Runtime>((Data & ~ThrowsMask) |
479+
(throws ? ThrowsMask : 0));
477480
}
478481

479482
unsigned getNumArguments() const {
@@ -492,17 +495,18 @@ class FunctionTypeFlags {
492495
return Data;
493496
}
494497

495-
static FunctionTypeFlags fromIntValue(int_type Data) {
496-
return FunctionTypeFlags(Data);
498+
static TargetFunctionTypeFlags<Runtime> fromIntValue(int_type Data) {
499+
return TargetFunctionTypeFlags(Data);
497500
}
498501

499-
bool operator==(FunctionTypeFlags other) const {
502+
bool operator==(TargetFunctionTypeFlags<Runtime> other) const {
500503
return Data == other.Data;
501504
}
502-
bool operator!=(FunctionTypeFlags other) const {
505+
bool operator!=(TargetFunctionTypeFlags<Runtime> other) const {
503506
return Data != other.Data;
504507
}
505508
};
509+
using FunctionTypeFlags = TargetFunctionTypeFlags<InProcess>;
506510

507511
/// Field types and flags as represented in a nominal type's field/case type
508512
/// vector.

include/swift/AST/ASTPrinter.h

+58-36
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,35 @@ enum class PrintNameContext {
4343
/// not escaped.
4444
FunctionParameterExternal,
4545
FunctionParameterLocal,
46+
/// Tuple element context, similar to \c FunctionParameterExternal.
47+
TupleElement,
48+
/// Attributes, which are escaped as 'Normal', but differentiated for
49+
/// the purposes of printName* callbacks.
50+
Attribute,
4651
};
4752

48-
/// Describes the kind of parameter-like entity being printed.
53+
/// Describes the kind of structured entity being printed.
54+
///
55+
/// This includes printables with sub-structure that cannot be completely
56+
/// handled by the printDeclPre/printDeclPost callbacks.
4957
/// E.g.
5058
/// \code
5159
/// func foo(<FunctionParameter>x: Int = 2</FunctionParameter>, ...)
5260
/// \endcode
53-
enum class PrintParameterKind {
61+
enum class PrintStructureKind {
62+
GenericParameter,
63+
GenericRequirement,
5464
FunctionParameter,
65+
FunctionType,
66+
FunctionReturnType,
67+
BuiltinAttribute,
68+
TupleElement,
5569
};
5670

5771
/// An abstract class used to print an AST.
5872
class ASTPrinter {
5973
unsigned CurrentIndentation = 0;
6074
unsigned PendingNewlines = 0;
61-
/// The queue of pending printDeclPre callbacks that will be run when we print
62-
/// a non-whitespace character.
63-
SmallVector<const Decl *, 4> PendingDeclPreCallbacks;
64-
const Decl *PendingDeclLocCallback = nullptr;
65-
Optional<PrintNameContext> PendingNamePreCallback;
6675
const NominalTypeDecl *SynthesizeTarget = nullptr;
6776

6877
void printTextImpl(StringRef Text);
@@ -117,10 +126,14 @@ class ASTPrinter {
117126
virtual void printSynthesizedExtensionPost(const ExtensionDecl *ED,
118127
const NominalTypeDecl *NTD) {}
119128

120-
/// Called before printing a parameter-like entity.
121-
virtual void printParameterPre(PrintParameterKind Kind) {}
122-
/// Called after printing a parameter-like entity.
123-
virtual void printParameterPost(PrintParameterKind Kind) {}
129+
/// Called before printing a structured entity.
130+
///
131+
/// Callers should use callPrintStructurePre().
132+
virtual void printStructurePre(PrintStructureKind Kind,
133+
const Decl *D = nullptr) {}
134+
/// Called after printing a structured entity.
135+
virtual void printStructurePost(PrintStructureKind Kind,
136+
const Decl *D = nullptr) {}
124137

125138
/// Called before printing a name in the given context.
126139
virtual void printNamePre(PrintNameContext Context) {}
@@ -153,6 +166,14 @@ class ASTPrinter {
153166
printNamePost(PrintNameContext::Keyword);
154167
}
155168

169+
void printAttrName(StringRef Name, bool needAt = false) {
170+
callPrintNamePre(PrintNameContext::Attribute);
171+
if (needAt)
172+
*this << "@";
173+
*this << Name;
174+
printNamePost(PrintNameContext::Attribute);
175+
}
176+
156177
void printName(Identifier Name,
157178
PrintNameContext Context = PrintNameContext::Normal);
158179

@@ -171,51 +192,52 @@ class ASTPrinter {
171192
PendingNewlines++;
172193
}
173194

195+
void forceNewlines() {
196+
if (PendingNewlines > 0) {
197+
llvm::SmallString<16> Str;
198+
for (unsigned i = 0; i != PendingNewlines; ++i)
199+
Str += '\n';
200+
PendingNewlines = 0;
201+
printText(Str);
202+
printIndent();
203+
}
204+
}
205+
174206
virtual void printIndent();
175207

176208
// MARK: Callback interface wrappers that perform ASTPrinter bookkeeping.
177209

178-
/// Schedule a \c printDeclPre callback to be called as soon as a
179-
/// non-whitespace character is printed.
180-
void callPrintDeclPre(const Decl *D) {
181-
PendingDeclPreCallbacks.emplace_back(D);
182-
}
210+
/// Make a callback to printDeclPre(), performing any necessary bookeeping.
211+
void callPrintDeclPre(const Decl *D);
183212

184213
/// Make a callback to printDeclPost(), performing any necessary bookeeping.
185214
void callPrintDeclPost(const Decl *D) {
186-
if (!PendingDeclPreCallbacks.empty() &&
187-
PendingDeclPreCallbacks.back() == D) {
188-
// Nothing printed for D; skip both pre and post callbacks.
189-
// Ideally we wouldn't get as far as setting up the callback if we aren't
190-
// going to print anything, but currently that would mean walking the
191-
// children of top-level code decls to determine.
192-
PendingDeclPreCallbacks.pop_back();
193-
return;
194-
}
195215
printDeclPost(D);
196216
}
197217

198218
/// Make a callback to avoidPrintDeclPost(), performing any necessary
199219
/// bookkeeping.
200220
void callAvoidPrintDeclPost(const Decl *D) {
201-
assert((PendingDeclPreCallbacks.empty() ||
202-
PendingDeclPreCallbacks.back() != D) &&
203-
"printDeclPre should not be called on avoided decl");
204221
avoidPrintDeclPost(D);
205222
}
206223

207-
/// Schedule a \c printDeclLoc callback to be called as soon as a
208-
/// non-whitespace character is printed.
224+
/// Make a callback to printDeclLoc(), performing any necessary bookeeping.
209225
void callPrintDeclLoc(const Decl *D) {
210-
assert(!PendingDeclLocCallback && "unexpected nested callPrintDeclLoc");
211-
PendingDeclLocCallback = D;
226+
forceNewlines();
227+
printDeclLoc(D);
212228
}
213229

214-
/// Schedule a \c printNamePre callback to be called as soon as a
215-
/// non-whitespace character is printed.
230+
/// Make a callback to printNamePre(), performing any necessary bookeeping.
216231
void callPrintNamePre(PrintNameContext Context) {
217-
assert(!PendingNamePreCallback && "unexpected nested callPrintNamePre");
218-
PendingNamePreCallback = Context;
232+
forceNewlines();
233+
printNamePre(Context);
234+
}
235+
236+
/// Make a callback to printStructurePre(), performing any necessary
237+
/// bookkeeping.
238+
void callPrintStructurePre(PrintStructureKind Kind, const Decl *D = nullptr) {
239+
forceNewlines();
240+
printStructurePre(Kind, D);
219241
}
220242

221243
/// To sanitize a malformed utf8 string to a well-formed one.

include/swift/AST/Attr.def

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ TYPE_ATTR(in)
4646
TYPE_ATTR(inout)
4747
TYPE_ATTR(inout_aliasable)
4848
TYPE_ATTR(in_guaranteed)
49-
TYPE_ATTR(noescape) // Only valid in sil mode.
49+
TYPE_ATTR(noescape)
5050
TYPE_ATTR(owned)
5151
TYPE_ATTR(unowned_inner_pointer)
5252
TYPE_ATTR(guaranteed)

include/swift/AST/Attr.h

+4
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ class DeclAttribute : public AttributeBase {
361361
return getOptions(getKind());
362362
}
363363

364+
/// Prints this attribute (if applicable), returning `true` if anything was
365+
/// printed.
366+
bool printImpl(ASTPrinter &Printer, const PrintOptions &Options) const;
367+
364368
public:
365369
DeclAttrKind getKind() const {
366370
return static_cast<DeclAttrKind>(DeclAttrBits.Kind);

0 commit comments

Comments
 (0)