Merge pull request #10754 from gottesmm/sil-mode-fixes
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index cd3c392..2d44cbf 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3294,8 +3294,7 @@
LookUpConformanceInModule(module));
builder.addGenericParameter(selfType);
auto selfPA =
- builder.resolveArchetype(selfType,
- ArchetypeResolutionKind::CompleteWellFormed);
+ builder.resolveArchetype(selfType, ArchetypeResolutionKind::WellFormed);
builder.addRequirement(
requirement,
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 9870f8f..e41522e 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -488,21 +488,25 @@
builder.resolveArchetype(type, ArchetypeResolutionKind::CompleteWellFormed);
if (!pa) return false;
- pa = pa->getRepresentative();
+ if (pa->isConcreteType()) return false;
// If this type was mapped to a concrete type, then there is no
// requirement.
+ pa = pa->getRepresentative();
+
if (pa->isConcreteType()) return false;
// If there is a layout constraint, it might be a class.
- if (auto layout = pa->getLayout())
- if (layout->isClass())
- return true;
+ if (auto layout = pa->getLayout()) {
+ if (layout->isClass()) return true;
+ }
// If there is a superclass bound, then obviously it must be a class.
+ // FIXME: We shouldn't need this?
if (pa->getSuperclass()) return true;
// If any of the protocols are class-bound, then it must be a class.
+ // FIXME: We shouldn't need this?
for (auto proto : pa->getConformsTo()) {
if (proto->requiresClass()) return true;
}
@@ -519,8 +523,6 @@
builder.resolveArchetype(type, ArchetypeResolutionKind::CompleteWellFormed);
if (!pa) return nullptr;
- pa = pa->getRepresentative();
-
// If this type was mapped to a concrete type, then there is no
// requirement.
if (pa->isConcreteType()) return nullptr;
@@ -540,8 +542,6 @@
builder.resolveArchetype(type, ArchetypeResolutionKind::CompleteWellFormed);
if (!pa) return { };
- pa = pa->getRepresentative();
-
// If this type was mapped to a concrete type, then there are no
// requirements.
if (pa->isConcreteType()) return { };
@@ -567,8 +567,6 @@
builder.resolveArchetype(type, ArchetypeResolutionKind::CompleteWellFormed);
if (!pa) return false;
- pa = pa->getRepresentative();
-
// FIXME: Deal with concrete conformances here?
if (pa->isConcreteType()) return false;
@@ -596,9 +594,6 @@
builder.resolveArchetype(type, ArchetypeResolutionKind::CompleteWellFormed);
if (!pa) return Type();
- pa = pa->getRepresentative();
- if (!pa->isConcreteType()) return Type();
-
return pa->getConcreteType();
}
@@ -611,7 +606,6 @@
builder.resolveArchetype(type, ArchetypeResolutionKind::CompleteWellFormed);
if (!pa) return LayoutConstraint();
- pa = pa->getRepresentative();
return pa->getLayout();
}
@@ -882,7 +876,7 @@
auto pa =
inProtoSigBuilder.resolveArchetype(
storedType,
- ArchetypeResolutionKind::WellFormed);
+ ArchetypeResolutionKind::CompleteWellFormed);
auto equivClass = pa->getOrCreateEquivalenceClass();
// Find the conformance of this potential archetype to the protocol in
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 981d26e..a95d2bb 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -1063,37 +1063,6 @@
return true;
}
- // For a nested type match, look for another type with that name.
- // FIXME: Actually, look for 5 of them. This is totally bogus.
- if (kind == NestedTypeNameMatch) {
- unsigned grossCount = 0;
- auto pa = storage.dyn_cast<const RequirementSource *>()
- ->getAffectedPotentialArchetype();
- while (auto parent = pa->getParent()) {
- if (pa->getNestedName() == nestedName) {
- if (++grossCount > 4) {
- ++NumRecursive;
- return true;
- }
- }
-
- pa = parent;
- }
-
- // Also check the root type.
- grossCount = 0;
- for (Type type = rootType;
- auto depTy = type->getAs<DependentMemberType>();
- type = depTy->getBase()) {
- if (depTy->getName() == nestedName) {
- if (++grossCount > 4) {
- ++NumRecursive;
- return true;
- }
- }
- }
- }
-
return false;
}
@@ -1960,14 +1929,10 @@
}
case ArchetypeResolutionKind::AlreadyKnown:
- break;
+ return nullptr;
}
}
- // If we still don't have a result potential archetype, we're done.
- if (!resultPA)
- return nullptr;
-
// If we have a potential archetype that requires more processing, do so now.
if (shouldUpdatePA) {
// For concrete types, introduce a same-type requirement to the aliased
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 9032dc3..8a88786 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -994,6 +994,15 @@
llvm::sys::path::append(libPath, "clang", "lib", "darwin");
}
+static void getClangLibraryPathOnLinux(SmallVectorImpl<char> &libPath,
+ const ArgList &args,
+ const ToolChain &TC) {
+ getRuntimeLibraryPath(libPath, args, TC);
+ // Remove platform name.
+ llvm::sys::path::remove_filename(libPath);
+ llvm::sys::path::append(libPath, "clang", "lib", "linux");
+}
+
/// Get the runtime library link path for static linking,
/// which is platform-specific and found relative to the compiler.
static void getRuntimeStaticLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
@@ -1061,6 +1070,12 @@
+ getDarwinLibraryNameSuffixForTriple(Triple) + "_dynamic.dylib").str();
}
+static std::string
+getSanitizerRuntimeLibNameForLinux(StringRef Sanitizer, const llvm::Triple &Triple) {
+ return (Twine("libclang_rt.") + Sanitizer + "-" +
+ Triple.getArchName() + ".a").str();
+}
+
bool toolchains::Darwin::sanitizerRuntimeLibExists(
const ArgList &args, StringRef sanitizer) const {
SmallString<128> sanitizerLibPath;
@@ -1070,6 +1085,15 @@
return llvm::sys::fs::exists(sanitizerLibPath.str());
}
+bool toolchains::GenericUnix::sanitizerRuntimeLibExists(
+ const ArgList &args, StringRef sanitizer) const {
+ SmallString<128> sanitizerLibPath;
+ getClangLibraryPathOnLinux(sanitizerLibPath, args, *this);
+ llvm::sys::path::append(sanitizerLibPath,
+ getSanitizerRuntimeLibNameForLinux(sanitizer, this->getTriple()));
+ return llvm::sys::fs::exists(sanitizerLibPath.str());
+}
+
static void
addLinkRuntimeLibForDarwin(const ArgList &Args, ArgStringList &Arguments,
@@ -1102,6 +1126,20 @@
}
static void
+addLinkRuntimeLibForLinux(const ArgList &Args, ArgStringList &Arguments,
+ StringRef LinuxLibName,
+ const ToolChain &TC) {
+ SmallString<128> Dir;
+ getRuntimeLibraryPath(Dir, Args, TC);
+ // Remove platform name.
+ llvm::sys::path::remove_filename(Dir);
+ llvm::sys::path::append(Dir, "clang", "lib", "linux");
+ SmallString<128> P(Dir);
+ llvm::sys::path::append(P, LinuxLibName);
+ Arguments.push_back(Args.MakeArgString(P));
+}
+
+static void
addLinkSanitizerLibArgsForDarwin(const ArgList &Args,
ArgStringList &Arguments,
StringRef Sanitizer, const ToolChain &TC) {
@@ -1116,6 +1154,28 @@
/*AddRPath=*/ true, TC);
}
+static void
+addLinkSanitizerLibArgsForLinux(const ArgList &Args,
+ ArgStringList &Arguments,
+ StringRef Sanitizer, const ToolChain &TC) {
+
+ addLinkRuntimeLibForLinux(Args, Arguments,
+ getSanitizerRuntimeLibNameForLinux(Sanitizer, TC.getTriple()), TC);
+
+ //Code here from https://github.com/apple/swift-clang/blob/ab3cbe7/lib/Driver/Tools.cpp#L3264-L3276
+ // There's no libpthread or librt on RTEMS.
+ if (TC.getTriple().getOS() != llvm::Triple::RTEMS) {
+ Arguments.push_back("-lpthread");
+ Arguments.push_back("-lrt");
+ }
+ Arguments.push_back("-lm");
+ // There's no libdl on FreeBSD or RTEMS.
+ if (TC.getTriple().getOS() != llvm::Triple::FreeBSD &&
+ TC.getTriple().getOS() != llvm::Triple::RTEMS)
+ Arguments.push_back("-ldl");
+
+}
+
ToolChain::InvocationInfo
toolchains::Darwin::constructInvocation(const LinkJobAction &job,
const JobContext &context) const {
@@ -1602,11 +1662,21 @@
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath));
Arguments.push_back("-lswiftCore");
}
-
-
+
// Explicitly pass the target to the linker
Arguments.push_back(context.Args.MakeArgString("--target=" + getTriple().str()));
+ if (getTriple().getOS() == llvm::Triple::Linux) {
+ //Make sure we only add SanitizerLibs for executables
+ if (job.getKind() == LinkKind::Executable) {
+ if (context.OI.SelectedSanitizer == SanitizerKind::Address)
+ addLinkSanitizerLibArgsForLinux(context.Args, Arguments, "asan", *this);
+
+ if (context.OI.SelectedSanitizer == SanitizerKind::Thread)
+ addLinkSanitizerLibArgsForLinux(context.Args, Arguments, "tsan", *this);
+ }
+ }
+
if (context.Args.hasArg(options::OPT_profile_generate)) {
SmallString<128> LibProfile(SharedRuntimeLibPath);
llvm::sys::path::remove_filename(LibProfile); // remove platform name
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 6d980cc..3e0b3f1 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -96,6 +96,9 @@
public:
GenericUnix(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {}
~GenericUnix() = default;
+ bool sanitizerRuntimeLibExists(const llvm::opt::ArgList &args,
+ StringRef sanitizerLibName)
+ const override;
};
class LLVM_LIBRARY_VISIBILITY Android : public GenericUnix {
diff --git a/lib/Option/SanitizerOptions.cpp b/lib/Option/SanitizerOptions.cpp
index 7f4abc7..0c5711f 100644
--- a/lib/Option/SanitizerOptions.cpp
+++ b/lib/Option/SanitizerOptions.cpp
@@ -143,8 +143,7 @@
return kind;
// Check if the target is supported for this sanitizer.
- // None of the sanitizers work on Linux right now.
- if (!Triple.isOSDarwin()) {
+ if (!(Triple.isOSDarwin() || Triple.isOSLinux())) {
SmallString<128> b;
Diags.diagnose(SourceLoc(), diag::error_unsupported_opt_for_target,
(A->getOption().getPrefixedName() + toStringRef(kind)).toStringRef(b),
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index b71f1f2..24575e7 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -5305,22 +5305,43 @@
SourceLoc diagLoc = firstRange.Start;
+ auto addFixIts = [&](InFlightDiagnostic diag) {
+ diag.highlight(firstRange).highlight(secondRange);
+
+ // Move the misplaced argument by removing it from one location and
+ // inserting it in another location. To maintain argument comma
+ // separation, since the argument is always moving to an earlier index
+ // the preceding comma and whitespace is removed and a new trailing
+ // comma and space is inserted with the moved argument.
+ auto &SM = TC.Context.SourceMgr;
+ auto text = SM.extractText(
+ Lexer::getCharSourceRangeFromSourceRange(SM, firstRange));
+
+ auto removalRange =
+ SourceRange(Lexer::getLocForEndOfToken(
+ SM, tuple->getElement(argIdx - 1)->getEndLoc()),
+ firstRange.End);
+ diag.fixItRemove(removalRange);
+ diag.fixItInsert(secondRange.Start, text.str() + ", ");
+ };
+
+ // There are 4 diagnostic messages variations depending on
+ // labeled/unlabeled arguments.
if (first.empty() && second.empty()) {
- TC.diagnose(diagLoc, diag::argument_out_of_order_unnamed_unnamed,
- argIdx + 1, prevArgIdx + 1)
- .fixItExchange(firstRange, secondRange);
+ addFixIts(TC.diagnose(diagLoc,
+ diag::argument_out_of_order_unnamed_unnamed,
+ argIdx + 1, prevArgIdx + 1));
} else if (first.empty() && !second.empty()) {
- TC.diagnose(diagLoc, diag::argument_out_of_order_unnamed_named,
- argIdx + 1, second)
- .fixItExchange(firstRange, secondRange);
+ addFixIts(TC.diagnose(diagLoc,
+ diag::argument_out_of_order_unnamed_named,
+ argIdx + 1, second));
} else if (!first.empty() && second.empty()) {
- TC.diagnose(diagLoc, diag::argument_out_of_order_named_unnamed, first,
- prevArgIdx + 1)
- .fixItExchange(firstRange, secondRange);
+ addFixIts(TC.diagnose(diagLoc,
+ diag::argument_out_of_order_named_unnamed, first,
+ prevArgIdx + 1));
} else {
- TC.diagnose(diagLoc, diag::argument_out_of_order_named_named, first,
- second)
- .fixItExchange(firstRange, secondRange);
+ addFixIts(TC.diagnose(diagLoc, diag::argument_out_of_order_named_named,
+ first, second));
}
Diagnosed = true;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 14a3d5b..620dfff 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -449,50 +449,46 @@
// If any arguments were provided out-of-order, check whether we have
// violated any of the reordering rules.
if (potentiallyOutOfOrder) {
- // Build a mapping from arguments to parameters.
- SmallVector<unsigned, 4> argumentBindings(numArgs);
- for (paramIdx = 0; paramIdx != numParams; ++paramIdx) {
- for (auto argIdx : parameterBindings[paramIdx])
- argumentBindings[argIdx] = paramIdx;
- }
-
- // Walk through the arguments, determining if any were bound to parameters
- // out-of-order where it is not permitted.
- unsigned prevParamIdx = argumentBindings[0];
- for (unsigned argIdx = 1; argIdx != numArgs; ++argIdx) {
- unsigned paramIdx = argumentBindings[argIdx];
-
- // If this argument binds to the same parameter as the previous one or to
- // a later parameter, just update the parameter index.
- if (paramIdx >= prevParamIdx) {
- prevParamIdx = paramIdx;
- continue;
- }
-
- unsigned prevArgIdx = parameterBindings[prevParamIdx].front();
-
- // First let's double check if out-of-order argument is nothing
- // more than a simple label mismatch, because in situation where
- // one argument requires label and another one doesn't, but caller
- // doesn't provide either, problem is going to be identified as
- // out-of-order argument instead of label mismatch.
- auto ¶meter = params[prevArgIdx];
- if (!parameter.getLabel().empty()) {
- auto expectedLabel = parameter.getLabel();
- auto argumentLabel = args[argIdx].getLabel();
-
- // If there is a label but it's incorrect it can only mean
- // situation like this: expected (x, _ y) got (y, _ x).
- if (argumentLabel.empty() ||
- (expectedLabel.compare(argumentLabel) != 0 &&
- args[prevArgIdx].getLabel().empty())) {
- listener.missingLabel(prevArgIdx);
- return true;
+ unsigned argIdx = 0;
+ // Enumerate the parameters and their bindings to see if any arguments are
+ // our of order
+ for (auto binding : parameterBindings) {
+ for (auto boundArgIdx : binding) {
+ if (boundArgIdx == argIdx) {
+ // If the argument is in the right location, just continue
+ argIdx++;
+ continue;
}
+
+ // Otherwise, we've found the (first) parameter that has an out of order
+ // argument, and know the indices of the argument the needs to move
+ // (fromArgIdx) and the argument location it should move to (toArgItd).
+ auto fromArgIdx = boundArgIdx;
+ auto toArgIdx = argIdx;
+
+ // First let's double check if out-of-order argument is nothing
+ // more than a simple label mismatch, because in situation where
+ // one argument requires label and another one doesn't, but caller
+ // doesn't provide either, problem is going to be identified as
+ // out-of-order argument instead of label mismatch.
+ auto ¶meter = params[toArgIdx];
+ if (!parameter.getLabel().empty()) {
+ auto expectedLabel = parameter.getLabel();
+ auto argumentLabel = args[fromArgIdx].getLabel();
+
+ // If there is a label but it's incorrect it can only mean
+ // situation like this: expected (x, _ y) got (y, _ x).
+ if (argumentLabel.empty() ||
+ (expectedLabel.compare(argumentLabel) != 0 &&
+ args[toArgIdx].getLabel().empty())) {
+ listener.missingLabel(toArgIdx);
+ return true;
+ }
+ }
+
+ listener.outOfOrderArgument(fromArgIdx, toArgIdx);
+ return true;
}
-
- listener.outOfOrderArgument(argIdx, prevArgIdx);
- return true;
}
}
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 0fb3173..4b96e41 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -132,9 +132,10 @@
assert(basePA && "Missing potential archetype for base");
// Retrieve the potential archetype for the nested type.
- auto nestedPA = basePA->getNestedType(ref->getIdentifier(),
- ArchetypeResolutionKind::WellFormed,
- Builder);
+ auto nestedPA =
+ basePA->getNestedType(ref->getIdentifier(),
+ ArchetypeResolutionKind::CompleteWellFormed,
+ Builder);
// If there was no such nested type, produce an error.
if (!nestedPA) {
diff --git a/stdlib/public/SDK/Foundation/Codable.swift b/stdlib/public/SDK/Foundation/Codable.swift
index 200cbb1..f12afa8 100644
--- a/stdlib/public/SDK/Foundation/Codable.swift
+++ b/stdlib/public/SDK/Foundation/Codable.swift
@@ -29,7 +29,7 @@
/// - parameter expectation: The type expected to be encountered.
/// - parameter reality: The value that was encountered instead of the expected type.
/// - returns: A `DecodingError` with the appropriate path and debug description.
- internal static func _typeMismatch(at path: [CodingKey?], expectation: Any.Type, reality: Any) -> DecodingError {
+ internal static func _typeMismatch(at path: [CodingKey], expectation: Any.Type, reality: Any) -> DecodingError {
let description = "Expected to decode \(expectation) but found \(_typeDescription(of: reality)) instead."
return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description))
}
diff --git a/stdlib/public/SDK/Foundation/JSONEncoder.swift b/stdlib/public/SDK/Foundation/JSONEncoder.swift
index c7ee7cb..f37e104 100644
--- a/stdlib/public/SDK/Foundation/JSONEncoder.swift
+++ b/stdlib/public/SDK/Foundation/JSONEncoder.swift
@@ -165,7 +165,7 @@
fileprivate let options: JSONEncoder._Options
/// The path to the current point in encoding.
- public var codingPath: [CodingKey?]
+ public var codingPath: [CodingKey]
/// Contextual user-provided information for use during encoding.
public var userInfo: [CodingUserInfoKey : Any] {
@@ -175,7 +175,7 @@
// MARK: - Initialization
/// Initializes `self` with the given top-level encoder options.
- fileprivate init(options: JSONEncoder._Options, codingPath: [CodingKey?] = []) {
+ fileprivate init(options: JSONEncoder._Options, codingPath: [CodingKey] = []) {
self.options = options
self.storage = _JSONEncodingStorage()
self.codingPath = codingPath
@@ -187,7 +187,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -304,12 +304,12 @@
private let container: NSMutableDictionary
/// The path of coding keys taken to get to this point in encoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
// MARK: - Initialization
/// Initializes `self` with the given references.
- fileprivate init(referencing encoder: _JSONEncoder, codingPath: [CodingKey?], wrapping container: NSMutableDictionary) {
+ fileprivate init(referencing encoder: _JSONEncoder, codingPath: [CodingKey], wrapping container: NSMutableDictionary) {
self.encoder = encoder
self.codingPath = codingPath
self.container = container
@@ -321,7 +321,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate mutating func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate mutating func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -384,7 +384,7 @@
}
public mutating func superEncoder() -> Encoder {
- return _JSONReferencingEncoder(referencing: self.encoder, at: _JSONSuperKey.super, wrapping: self.container)
+ return _JSONReferencingEncoder(referencing: self.encoder, at: _JSONKey.super, wrapping: self.container)
}
public mutating func superEncoder(forKey key: Key) -> Encoder {
@@ -402,12 +402,17 @@
private let container: NSMutableArray
/// The path of coding keys taken to get to this point in encoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
+
+ /// The number of elements encoded into the container.
+ public var count: Int {
+ return self.container.count
+ }
// MARK: - Initialization
/// Initializes `self` with the given references.
- fileprivate init(referencing encoder: _JSONEncoder, codingPath: [CodingKey?], wrapping container: NSMutableArray) {
+ fileprivate init(referencing encoder: _JSONEncoder, codingPath: [CodingKey], wrapping container: NSMutableArray) {
self.encoder = encoder
self.codingPath = codingPath
self.container = container
@@ -419,7 +424,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate mutating func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate mutating func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -444,39 +449,39 @@
public mutating func encode(_ value: Float) throws {
// Since the float may be invalid and throw, the coding path needs to contain this key.
- try self.encoder.with(pushedKey: nil) {
+ try self.encoder.with(pushedKey: _JSONKey(index: self.count)) {
self.container.add(try self.encoder.box(value))
}
}
public mutating func encode(_ value: Double) throws {
// Since the double may be invalid and throw, the coding path needs to contain this key.
- try self.encoder.with(pushedKey: nil) {
+ try self.encoder.with(pushedKey: _JSONKey(index: self.count)) {
self.container.add(try self.encoder.box(value))
}
}
public mutating func encode<T : Encodable>(_ value: T) throws {
- try self.encoder.with(pushedKey: nil) {
+ try self.encoder.with(pushedKey: _JSONKey(index: self.count)) {
self.container.add(try self.encoder.box(value))
}
}
public mutating func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> {
- let dictionary = NSMutableDictionary()
- self.container.add(dictionary)
+ return self.with(pushedKey: _JSONKey(index: self.count)) {
+ let dictionary = NSMutableDictionary()
+ self.container.add(dictionary)
- return self.with(pushedKey: nil) {
let container = _JSONKeyedEncodingContainer<NestedKey>(referencing: self.encoder, codingPath: self.codingPath, wrapping: dictionary)
return KeyedEncodingContainer(container)
}
}
public mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
- let array = NSMutableArray()
- self.container.add(array)
+ return self.with(pushedKey: _JSONKey(index: self.count)) {
+ let array = NSMutableArray()
+ self.container.add(array)
- return self.with(pushedKey: nil) {
return _JSONUnkeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: array)
}
}
@@ -753,7 +758,7 @@
self.reference = .array(array, index)
super.init(options: encoder.options, codingPath: encoder.codingPath)
- self.codingPath.append(nil)
+ self.codingPath.append(_JSONKey(index: index))
}
/// Initializes `self` by referencing the given dictionary container in the given encoder.
@@ -913,7 +918,7 @@
fileprivate let options: JSONDecoder._Options
/// The path to the current point in encoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
/// Contextual user-provided information for use during encoding.
public var userInfo: [CodingUserInfoKey : Any] {
@@ -923,7 +928,7 @@
// MARK: - Initialization
/// Initializes `self` with the given top-level container and options.
- fileprivate init(referencing container: Any, at codingPath: [CodingKey?] = [], options: JSONDecoder._Options) {
+ fileprivate init(referencing container: Any, at codingPath: [CodingKey] = [], options: JSONDecoder._Options) {
self.storage = _JSONDecodingStorage()
self.storage.push(container: container)
self.codingPath = codingPath
@@ -936,7 +941,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -1028,7 +1033,7 @@
private let container: [String : Any]
/// The path of coding keys taken to get to this point in decoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
// MARK: - Initialization
@@ -1308,7 +1313,7 @@
}
public func superDecoder() throws -> Decoder {
- return try _superDecoder(forKey: _JSONSuperKey.super)
+ return try _superDecoder(forKey: _JSONKey.super)
}
public func superDecoder(forKey key: Key) throws -> Decoder {
@@ -1326,10 +1331,10 @@
private let container: [Any]
/// The path of coding keys taken to get to this point in decoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
/// The index of the element we're about to decode.
- private var currentIndex: Int
+ private(set) public var currentIndex: Int
// MARK: - Initialization
@@ -1353,7 +1358,7 @@
public mutating func decodeNil() throws -> Bool {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
if self.container[self.currentIndex] is NSNull {
@@ -1366,12 +1371,12 @@
public mutating func decode(_ type: Bool.Type) throws -> Bool {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Bool.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1381,12 +1386,12 @@
public mutating func decode(_ type: Int.Type) throws -> Int {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1396,12 +1401,12 @@
public mutating func decode(_ type: Int8.Type) throws -> Int8 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int8.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1411,12 +1416,12 @@
public mutating func decode(_ type: Int16.Type) throws -> Int16 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int16.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1426,12 +1431,12 @@
public mutating func decode(_ type: Int32.Type) throws -> Int32 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int32.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1441,12 +1446,12 @@
public mutating func decode(_ type: Int64.Type) throws -> Int64 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int64.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1456,12 +1461,12 @@
public mutating func decode(_ type: UInt.Type) throws -> UInt {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1471,12 +1476,12 @@
public mutating func decode(_ type: UInt8.Type) throws -> UInt8 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt8.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1486,12 +1491,12 @@
public mutating func decode(_ type: UInt16.Type) throws -> UInt16 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt16.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1501,12 +1506,12 @@
public mutating func decode(_ type: UInt32.Type) throws -> UInt32 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt32.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1516,12 +1521,12 @@
public mutating func decode(_ type: UInt64.Type) throws -> UInt64 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt64.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1531,12 +1536,12 @@
public mutating func decode(_ type: Float.Type) throws -> Float {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Float.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1546,12 +1551,12 @@
public mutating func decode(_ type: Double.Type) throws -> Double {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Double.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1561,12 +1566,12 @@
public mutating func decode(_ type: String.Type) throws -> String {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: String.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1576,12 +1581,12 @@
public mutating func decode<T : Decodable>(_ type: T.Type) throws -> T {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: T.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1590,7 +1595,7 @@
}
public mutating func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> {
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard !self.isAtEnd else {
throw DecodingError.valueNotFound(KeyedDecodingContainer<NestedKey>.self,
DecodingError.Context(codingPath: self.codingPath,
@@ -1615,7 +1620,7 @@
}
public mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer {
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard !self.isAtEnd else {
throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self,
DecodingError.Context(codingPath: self.codingPath,
@@ -1639,7 +1644,7 @@
}
public mutating func superDecoder() throws -> Decoder {
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _JSONKey(index: self.currentIndex)) {
guard !self.isAtEnd else {
throw DecodingError.valueNotFound(Decoder.self,
DecodingError.Context(codingPath: self.codingPath,
@@ -2128,11 +2133,29 @@
}
//===----------------------------------------------------------------------===//
-// Shared Super Key
+// Shared Key Types
//===----------------------------------------------------------------------===//
-fileprivate enum _JSONSuperKey : String, CodingKey {
- case `super`
+fileprivate struct _JSONKey : CodingKey {
+ public var stringValue: String
+ public var intValue: Int?
+
+ public init?(stringValue: String) {
+ self.stringValue = stringValue
+ self.intValue = nil
+ }
+
+ public init?(intValue: Int) {
+ self.stringValue = "\(intValue)"
+ self.intValue = intValue
+ }
+
+ fileprivate init(index: Int) {
+ self.stringValue = "Index \(index)"
+ self.intValue = index
+ }
+
+ fileprivate static let `super` = _JSONKey(stringValue: "super")!
}
//===----------------------------------------------------------------------===//
@@ -2158,7 +2181,7 @@
/// - parameter value: The value that was invalid to encode.
/// - parameter path: The path of `CodingKey`s taken to encode this value.
/// - returns: An `EncodingError` with the appropriate path and debug description.
- fileprivate static func _invalidFloatingPointValue<T : FloatingPoint>(_ value: T, at codingPath: [CodingKey?]) -> EncodingError {
+ fileprivate static func _invalidFloatingPointValue<T : FloatingPoint>(_ value: T, at codingPath: [CodingKey]) -> EncodingError {
let valueDescription: String
if value == T.infinity {
valueDescription = "\(T.self).infinity"
diff --git a/stdlib/public/SDK/Foundation/PlistEncoder.swift b/stdlib/public/SDK/Foundation/PlistEncoder.swift
index 404ca71..02e14e8 100644
--- a/stdlib/public/SDK/Foundation/PlistEncoder.swift
+++ b/stdlib/public/SDK/Foundation/PlistEncoder.swift
@@ -94,7 +94,7 @@
fileprivate let options: PropertyListEncoder._Options
/// The path to the current point in encoding.
- fileprivate(set) public var codingPath: [CodingKey?]
+ fileprivate(set) public var codingPath: [CodingKey]
/// Contextual user-provided information for use during encoding.
public var userInfo: [CodingUserInfoKey : Any] {
@@ -104,7 +104,7 @@
// MARK: - Initialization
/// Initializes `self` with the given top-level encoder options.
- fileprivate init(options: PropertyListEncoder._Options, codingPath: [CodingKey?] = []) {
+ fileprivate init(options: PropertyListEncoder._Options, codingPath: [CodingKey] = []) {
self.options = options
self.storage = _PlistEncodingStorage()
self.codingPath = codingPath
@@ -116,7 +116,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -233,12 +233,12 @@
private let container: NSMutableDictionary
/// The path of coding keys taken to get to this point in encoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
// MARK: - Initialization
/// Initializes `self` with the given references.
- fileprivate init(referencing encoder: _PlistEncoder, codingPath: [CodingKey?], wrapping container: NSMutableDictionary) {
+ fileprivate init(referencing encoder: _PlistEncoder, codingPath: [CodingKey], wrapping container: NSMutableDictionary) {
self.encoder = encoder
self.codingPath = codingPath
self.container = container
@@ -250,7 +250,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate mutating func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate mutating func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -301,7 +301,7 @@
}
public mutating func superEncoder() -> Encoder {
- return _PlistReferencingEncoder(referencing: self.encoder, at: _PlistSuperKey.super, wrapping: self.container)
+ return _PlistReferencingEncoder(referencing: self.encoder, at: _PlistKey.super, wrapping: self.container)
}
public mutating func superEncoder(forKey key: Key) -> Encoder {
@@ -319,12 +319,17 @@
private let container: NSMutableArray
/// The path of coding keys taken to get to this point in encoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
+
+ /// The number of elements encoded into the container.
+ public var count: Int {
+ return self.container.count
+ }
// MARK: - Initialization
/// Initializes `self` with the given references.
- fileprivate init(referencing encoder: _PlistEncoder, codingPath: [CodingKey?], wrapping container: NSMutableArray) {
+ fileprivate init(referencing encoder: _PlistEncoder, codingPath: [CodingKey], wrapping container: NSMutableArray) {
self.encoder = encoder
self.codingPath = codingPath
self.container = container
@@ -336,7 +341,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate mutating func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate mutating func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -362,26 +367,26 @@
public mutating func encode(_ value: String) throws { self.container.add(self.encoder.box(value)) }
public mutating func encode<T : Encodable>(_ value: T) throws {
- try self.encoder.with(pushedKey: nil) {
+ try self.encoder.with(pushedKey: _PlistKey(index: self.count)) {
self.container.add(try self.encoder.box(value))
}
}
public mutating func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> {
- let dictionary = NSMutableDictionary()
- self.container.add(dictionary)
+ return self.with(pushedKey: _PlistKey(index: self.count)) {
+ let dictionary = NSMutableDictionary()
+ self.container.add(dictionary)
- return self.with(pushedKey: nil) {
let container = _PlistKeyedEncodingContainer<NestedKey>(referencing: self.encoder, codingPath: self.codingPath, wrapping: dictionary)
return KeyedEncodingContainer(container)
}
}
public mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
- let array = NSMutableArray()
- self.container.add(array)
+ return self.with(pushedKey: _PlistKey(index: self.count)) {
+ let array = NSMutableArray()
+ self.container.add(array)
- return self.with(pushedKey: nil) {
return _PlistUnkeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: array)
}
}
@@ -555,7 +560,7 @@
self.reference = .array(array, index)
super.init(options: encoder.options, codingPath: encoder.codingPath)
- self.codingPath.append(nil)
+ self.codingPath.append(_PlistKey(index: index))
}
/// Initializes `self` by referencing the given dictionary container in the given encoder.
@@ -669,7 +674,7 @@
fileprivate let options: PropertyListDecoder._Options
/// The path to the current point in encoding.
- fileprivate(set) public var codingPath: [CodingKey?]
+ fileprivate(set) public var codingPath: [CodingKey]
/// Contextual user-provided information for use during encoding.
public var userInfo: [CodingUserInfoKey : Any] {
@@ -679,7 +684,7 @@
// MARK: - Initialization
/// Initializes `self` with the given top-level container and options.
- fileprivate init(referencing container: Any, at codingPath: [CodingKey?] = [], options: PropertyListDecoder._Options) {
+ fileprivate init(referencing container: Any, at codingPath: [CodingKey] = [], options: PropertyListDecoder._Options) {
self.storage = _PlistDecodingStorage()
self.storage.push(container: container)
self.codingPath = codingPath
@@ -692,7 +697,7 @@
///
/// - parameter key: The key to push. May be nil for unkeyed containers.
/// - parameter work: The work to perform with the key in the path.
- fileprivate func with<T>(pushedKey key: CodingKey?, _ work: () throws -> T) rethrows -> T {
+ fileprivate func with<T>(pushedKey key: CodingKey, _ work: () throws -> T) rethrows -> T {
self.codingPath.append(key)
let ret: T = try work()
self.codingPath.removeLast()
@@ -784,7 +789,7 @@
private let container: [String : Any]
/// The path of coding keys taken to get to this point in decoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
// MARK: - Initialization
@@ -1068,7 +1073,7 @@
}
public func superDecoder() throws -> Decoder {
- return try _superDecoder(forKey: _PlistSuperKey.super)
+ return try _superDecoder(forKey: _PlistKey.super)
}
public func superDecoder(forKey key: Key) throws -> Decoder {
@@ -1086,10 +1091,10 @@
private let container: [Any]
/// The path of coding keys taken to get to this point in decoding.
- private(set) public var codingPath: [CodingKey?]
+ private(set) public var codingPath: [CodingKey]
/// The index of the element we're about to decode.
- private var currentIndex: Int
+ private(set) public var currentIndex: Int
// MARK: - Initialization
@@ -1113,7 +1118,7 @@
public mutating func decodeNil() throws -> Bool {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
if self.container[self.currentIndex] is NSNull {
@@ -1126,12 +1131,12 @@
public mutating func decode(_ type: Bool.Type) throws -> Bool {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Bool.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1141,12 +1146,12 @@
public mutating func decode(_ type: Int.Type) throws -> Int {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1156,12 +1161,12 @@
public mutating func decode(_ type: Int8.Type) throws -> Int8 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int8.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1171,12 +1176,12 @@
public mutating func decode(_ type: Int16.Type) throws -> Int16 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int16.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1186,12 +1191,12 @@
public mutating func decode(_ type: Int32.Type) throws -> Int32 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int32.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1201,12 +1206,12 @@
public mutating func decode(_ type: Int64.Type) throws -> Int64 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int64.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1216,12 +1221,12 @@
public mutating func decode(_ type: UInt.Type) throws -> UInt {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1231,12 +1236,12 @@
public mutating func decode(_ type: UInt8.Type) throws -> UInt8 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt8.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1246,12 +1251,12 @@
public mutating func decode(_ type: UInt16.Type) throws -> UInt16 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt16.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1261,12 +1266,12 @@
public mutating func decode(_ type: UInt32.Type) throws -> UInt32 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt32.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1276,12 +1281,12 @@
public mutating func decode(_ type: UInt64.Type) throws -> UInt64 {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt64.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1291,12 +1296,12 @@
public mutating func decode(_ type: Float.Type) throws -> Float {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Float.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1306,12 +1311,12 @@
public mutating func decode(_ type: Double.Type) throws -> Double {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Double.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1321,12 +1326,12 @@
public mutating func decode(_ type: String.Type) throws -> String {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: String.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1336,12 +1341,12 @@
public mutating func decode<T : Decodable>(_ type: T.Type) throws -> T {
guard !self.isAtEnd else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Unkeyed container is at end."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end."))
}
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: T.self) else {
- throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [nil], debugDescription: "Expected \(type) but found null instead."))
+ throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_PlistKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead."))
}
self.currentIndex += 1
@@ -1350,7 +1355,7 @@
}
public mutating func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> {
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard !self.isAtEnd else {
throw DecodingError.valueNotFound(KeyedDecodingContainer<NestedKey>.self,
DecodingError.Context(codingPath: self.codingPath,
@@ -1375,7 +1380,7 @@
}
public mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer {
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard !self.isAtEnd else {
throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self,
DecodingError.Context(codingPath: self.codingPath,
@@ -1399,7 +1404,7 @@
}
public mutating func superDecoder() throws -> Decoder {
- return try self.decoder.with(pushedKey: nil) {
+ return try self.decoder.with(pushedKey: _PlistKey(index: self.currentIndex)) {
guard !self.isAtEnd else {
throw DecodingError.valueNotFound(Decoder.self, DecodingError.Context(codingPath: self.codingPath,
debugDescription: "Cannot get superDecoder() -- unkeyed container is at end."))
@@ -1765,9 +1770,27 @@
fileprivate let _plistNullNSString = NSString(string: _plistNull)
//===----------------------------------------------------------------------===//
-// Shared Super Key
+// Shared Key Types
//===----------------------------------------------------------------------===//
-fileprivate enum _PlistSuperKey : String, CodingKey {
- case `super`
+fileprivate struct _PlistKey : CodingKey {
+ public var stringValue: String
+ public var intValue: Int?
+
+ public init?(stringValue: String) {
+ self.stringValue = stringValue
+ self.intValue = nil
+ }
+
+ public init?(intValue: Int) {
+ self.stringValue = "\(intValue)"
+ self.intValue = intValue
+ }
+
+ fileprivate init(index: Int) {
+ self.stringValue = "Index \(index)"
+ self.intValue = index
+ }
+
+ fileprivate static let `super` = _PlistKey(stringValue: "super")!
}
diff --git a/stdlib/public/core/Codable.swift b/stdlib/public/core/Codable.swift
index 1cd4209..74f7c13 100644
--- a/stdlib/public/core/Codable.swift
+++ b/stdlib/public/core/Codable.swift
@@ -75,7 +75,7 @@
public protocol Encoder {
/// The path of coding keys taken to get to this point in encoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// Any contextual information set by the user for encoding.
var userInfo: [CodingUserInfoKey : Any] { get }
@@ -108,7 +108,7 @@
public protocol Decoder {
/// The path of coding keys taken to get to this point in decoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// Any contextual information set by the user for decoding.
var userInfo: [CodingUserInfoKey : Any] { get }
@@ -147,7 +147,7 @@
/// The path of coding keys taken to get to this point in encoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// Encodes a null value for the given key.
///
@@ -423,7 +423,7 @@
/// The path of coding keys taken to get to this point in encoding.
/// A `nil` value indicates an unkeyed container.
- public var codingPath: [CodingKey?] {
+ public var codingPath: [CodingKey] {
return _box.codingPath
}
@@ -761,7 +761,7 @@
/// The path of coding keys taken to get to this point in decoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// All the keys the `Decoder` has for this container.
///
@@ -1136,7 +1136,7 @@
/// The path of coding keys taken to get to this point in decoding.
/// A `nil` value indicates an unkeyed container.
- public var codingPath: [CodingKey?] {
+ public var codingPath: [CodingKey] {
return _box.codingPath
}
@@ -1578,7 +1578,10 @@
public protocol UnkeyedEncodingContainer {
/// The path of coding keys taken to get to this point in encoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
+
+ /// The number of elements encoded into the container.
+ var count: Int { get }
/// Encodes a null value.
///
@@ -1800,7 +1803,7 @@
public protocol UnkeyedDecodingContainer {
/// The path of coding keys taken to get to this point in decoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// Returns the number of elements (if known) contained within this container.
var count: Int? { get }
@@ -1808,8 +1811,14 @@
/// Returns whether there are no more elements left to be decoded in the container.
var isAtEnd: Bool { get }
+ /// The current decoding index of the container (i.e. the index of the next element to be decoded.)
+ /// Incremented after every successful decode call.
+ var currentIndex: Int { get }
+
/// Decodes a null value.
///
+ /// If the value is not null, does not increment currentIndex.
+ ///
/// - returns: Whether the encountered value was null.
/// - throws: `DecodingError.valueNotFound` if there are no more values to decode.
mutating func decodeNil() throws -> Bool
@@ -2098,7 +2107,7 @@
public protocol SingleValueEncodingContainer {
/// The path of coding keys taken to get to this point in encoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// Encodes a null value.
///
@@ -2216,7 +2225,7 @@
public protocol SingleValueDecodingContainer {
/// The path of coding keys taken to get to this point in encoding.
/// A `nil` value indicates an unkeyed container.
- var codingPath: [CodingKey?] { get }
+ var codingPath: [CodingKey] { get }
/// Decodes a null value.
///
@@ -2385,7 +2394,7 @@
/// The context in which the error occurred.
public struct Context {
/// The path of `CodingKey`s taken to get to the point of the failing encode call.
- public let codingPath: [CodingKey?]
+ public let codingPath: [CodingKey]
/// A description of what went wrong, for debugging purposes.
public let debugDescription: String
@@ -2398,7 +2407,7 @@
/// - parameter codingPath: The path of `CodingKey`s taken to get to the point of the failing encode call.
/// - parameter debugDescription: A description of what went wrong, for debugging purposes.
/// - parameter underlyingError: The underlying error which caused this error, if any.
- public init(codingPath: [CodingKey?], debugDescription: String, underlyingError: Error? = nil) {
+ public init(codingPath: [CodingKey], debugDescription: String, underlyingError: Error? = nil) {
self.codingPath = codingPath
self.debugDescription = debugDescription
self.underlyingError = underlyingError
@@ -2454,7 +2463,7 @@
/// The context in which the error occurred.
public struct Context {
/// The path of `CodingKey`s taken to get to the point of the failing decode call.
- public let codingPath: [CodingKey?]
+ public let codingPath: [CodingKey]
/// A description of what went wrong, for debugging purposes.
public let debugDescription: String
@@ -2467,7 +2476,7 @@
/// - parameter codingPath: The path of `CodingKey`s taken to get to the point of the failing decode call.
/// - parameter debugDescription: A description of what went wrong, for debugging purposes.
/// - parameter underlyingError: The underlying error which caused this error, if any.
- public init(codingPath: [CodingKey?], debugDescription: String, underlyingError: Error? = nil) {
+ public init(codingPath: [CodingKey], debugDescription: String, underlyingError: Error? = nil) {
self.codingPath = codingPath
self.debugDescription = debugDescription
self.underlyingError = underlyingError
@@ -2541,6 +2550,20 @@
// The following extensions allow for easier error construction.
+internal struct _GenericIndexKey : CodingKey {
+ var stringValue: String
+ var intValue: Int?
+
+ init?(stringValue: String) {
+ return nil
+ }
+
+ init?(intValue: Int) {
+ self.stringValue = "Index \(intValue)"
+ self.intValue = intValue
+ }
+}
+
public extension DecodingError {
/// A convenience method which creates a new .dataCorrupted error using a constructed coding path and the given debug description.
///
@@ -2562,7 +2585,7 @@
/// - param container: The container in which the corrupted data was accessed.
/// - param debugDescription: A description of the error to aid in debugging.
static func dataCorruptedError(in container: UnkeyedDecodingContainer, debugDescription: String) -> DecodingError {
- let context = DecodingError.Context(codingPath: container.codingPath + [nil],
+ let context = DecodingError.Context(codingPath: container.codingPath + [_GenericIndexKey(intValue: container.currentIndex)!],
debugDescription: debugDescription)
return .dataCorrupted(context)
}
@@ -2590,7 +2613,7 @@
// These must all be given a concrete implementation in _*Box.
@_inlineable
@_versioned
- internal var codingPath: [CodingKey?] {
+ internal var codingPath: [CodingKey] {
fatalError("_KeyedEncodingContainerBase cannot be used directly.")
}
@@ -2827,7 +2850,7 @@
@_inlineable
@_versioned
- override internal var codingPath: [CodingKey?] {
+ override internal var codingPath: [CodingKey] {
return concrete.codingPath
}
@@ -3053,7 +3076,7 @@
internal class _KeyedDecodingContainerBase<Key : CodingKey> {
@_inlineable
@_versioned
- internal var codingPath: [CodingKey?] {
+ internal var codingPath: [CodingKey] {
fatalError("_KeyedDecodingContainerBase cannot be used directly.")
}
@@ -3296,7 +3319,7 @@
@_inlineable
@_versioned
- override var codingPath: [CodingKey?] {
+ override var codingPath: [CodingKey] {
return concrete.codingPath
}
diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift
index 5781c2c..a0838fc 100644
--- a/test/ClangImporter/objc_parse.swift
+++ b/test/ClangImporter/objc_parse.swift
@@ -44,7 +44,7 @@
}
// Renaming of redundant parameters.
- b.performAdd(1, withValue:2, withValue2:3, withValue:4) // expected-error{{argument 'withValue' must precede argument 'withValue2'}}
+ b.performAdd(1, withValue:2, withValue2:3, withValue:4) // expected-error{{argument 'withValue' must precede argument 'withValue2'}} {{32-32=withValue:4, }} {{44-57=}}
b.performAdd(1, withValue:2, withValue:4, withValue2: 3)
b.performAdd(1, 2, 3, 4) // expected-error{{missing argument labels 'withValue:withValue:withValue2:' in call}} {{19-19=withValue: }} {{22-22=withValue: }} {{25-25=withValue2: }}
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index fd58398..f6c4590 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -816,14 +816,14 @@
r27212391(3, 5) // expected-error {{missing argument label 'x' in call}}
r27212391(3, y: 5) // expected-error {{missing argument label 'x' in call}}
-r27212391(3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #1}}
-r27212391(y: 3, x: 5) // expected-error {{argument 'x' must precede argument 'y'}}
+r27212391(3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #1}} {{11-11=x: 5, }} {{12-18=}}
+r27212391(y: 3, x: 5) // expected-error {{argument 'x' must precede argument 'y'}} {{11-11=x: 5, }} {{15-21=}}
r27212391(y: 3, 5) // expected-error {{incorrect argument label in call (have 'y:_:', expected 'x:_:')}}
r27212391(x: 3, x: 5) // expected-error {{extraneous argument label 'x:' in call}}
r27212391(a: 1, 3, y: 5) // expected-error {{missing argument label 'x' in call}}
r27212391(1, x: 3, y: 5) // expected-error {{missing argument label 'a' in call}}
-r27212391(a: 1, y: 3, x: 5) // expected-error {{argument 'x' must precede argument 'y'}}
-r27212391(a: 1, 3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #2}}
+r27212391(a: 1, y: 3, x: 5) // expected-error {{argument 'x' must precede argument 'y'}} {{17-17=x: 5, }} {{21-27=}}
+r27212391(a: 1, 3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #2}} {{17-17=x: 5, }} {{18-24=}}
// SR-1255
func foo1255_1() {
@@ -1060,3 +1060,28 @@
// expected-error@-1 {{value of type 'Expr_28456467' has no member 'hasStateDef'}}
}
}
+
+// rdar://problem/31849281 - Let's play "bump the argument"
+
+struct rdar31849281 { var foo, a, b, c: Int }
+_ = rdar31849281(a: 101, b: 102, c: 103, foo: 104) // expected-error {{argument 'foo' must precede argument 'a'}} {{18-18=foo: 104, }} {{40-50=}}
+
+_ = rdar31849281(a: 101, c: 103, b: 102, foo: 104) // expected-error {{argument 'foo' must precede argument 'a'}} {{18-18=foo: 104, }} {{40-50=}}
+_ = rdar31849281(foo: 104, a: 101, c: 103, b: 102) // expected-error {{argument 'b' must precede argument 'c'}} {{36-36=b: 102, }} {{42-50=}}
+
+_ = rdar31849281(b: 102, c: 103, a: 101, foo: 104) // expected-error {{argument 'foo' must precede argument 'b'}} {{18-18=foo: 104, }} {{40-50=}}
+_ = rdar31849281(foo: 104, b: 102, c: 103, a: 101) // expected-error {{argument 'a' must precede argument 'b'}} {{28-28=a: 101, }} {{42-50=}}
+
+func var_31849281(_ a: Int, _ b: Int..., c: Int) {}
+var_31849281(1, c: 10, 3, 4, 5, 6, 7, 8, 9) // expected-error {{unnamed argument #3 must precede argument 'c'}} {{17-17=3, 4, 5, 6, 7, 8, 9, }} {{22-43=}}
+
+func fun_31849281(a: (Bool) -> Bool, b: (Int) -> (String), c: [Int?]) {}
+fun_31849281(c: [nil, 42], a: { !$0 }, b: { (num: Int) -> String in return "\(num)" })
+// expected-error @-1 {{argument 'a' must precede argument 'c'}} {{14-14=a: { !$0 }, }} {{26-38=}}
+fun_31849281(a: { !$0 }, c: [nil, 42], b: { (num: Int) -> String in return String(describing: num) })
+// expected-error @-1 {{argument 'b' must precede argument 'c'}} {{26-26=b: { (num: Int) -> String in return String(describing: num) }, }} {{38-101=}}
+fun_31849281(a: { !$0 }, c: [nil, 42], b: { "\($0)" })
+// expected-error @-1 {{argument 'b' must precede argument 'c'}} {{26-26=b: { "\\($0)" }, }} {{38-54=}}
+
+func f_31849281(x: Int, y: Int, z: Int) {}
+f_31849281(42, y: 10, x: 20) // expected-error {{argument 'x' must precede unnamed argument #1}} {{12-12=x: 20, }} {{21-28=}}
diff --git a/test/Constraints/function.swift b/test/Constraints/function.swift
index d6e661c..7610786 100644
--- a/test/Constraints/function.swift
+++ b/test/Constraints/function.swift
@@ -36,7 +36,7 @@
// <rdar://problem/17652759> Default arguments cause crash with tuple permutation
func testArgumentShuffle(_ first: Int = 7, third: Int = 9) {
}
-testArgumentShuffle(third: 1, 2) // expected-error {{unnamed argument #2 must precede argument 'third'}} {{21-29=2}} {{31-32=third: 1}}
+testArgumentShuffle(third: 1, 2) // expected-error {{unnamed argument #2 must precede argument 'third'}} {{21-21=2, }} {{29-32=}}
diff --git a/test/Constraints/keyword_arguments.swift b/test/Constraints/keyword_arguments.swift
index 48a35e4..8cf9760 100644
--- a/test/Constraints/keyword_arguments.swift
+++ b/test/Constraints/keyword_arguments.swift
@@ -82,7 +82,7 @@
// -------------------------------------------
// Out-of-order keywords
// -------------------------------------------
-allkeywords1(y: 1, x: 2) // expected-error{{argument 'x' must precede argument 'y'}} {{14-18=x: 2}} {{20-24=y: 1}}
+allkeywords1(y: 1, x: 2) // expected-error{{argument 'x' must precede argument 'y'}} {{14-14=x: 2, }} {{18-24=}}
// -------------------------------------------
// Default arguments
@@ -102,9 +102,9 @@
defargs1(x: 1, z: 3)
// Using defaults (out-of-order, error by SE-0060)
-defargs1(z: 3, y: 2, x: 1) // expected-error{{argument 'y' must precede argument 'z'}} {{10-14=y: 2}} {{16-20=z: 3}}
-defargs1(x: 1, z: 3, y: 2) // expected-error{{argument 'y' must precede argument 'z'}} {{16-20=y: 2}} {{22-26=z: 3}}
-defargs1(y: 2, x: 1) // expected-error{{argument 'x' must precede argument 'y'}} {{10-14=x: 1}} {{16-20=y: 2}}
+defargs1(z: 3, y: 2, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{10-10=x: 1, }} {{20-26=}}
+defargs1(x: 1, z: 3, y: 2) // expected-error{{argument 'y' must precede argument 'z'}} {{16-16=y: 2, }} {{20-26=}}
+defargs1(y: 2, x: 1) // expected-error{{argument 'x' must precede argument 'y'}} {{10-10=x: 1, }} {{14-20=}}
// Default arguments "boxed in".
func defargs2(first: Int, x: Int = 1, y: Int = 2, z: Int = 3, last: Int) { }
@@ -116,12 +116,12 @@
defargs2(first: 1, last: 4)
// Using defaults in the middle (out-of-order, error by SE-0060)
-defargs2(first: 1, z: 3, x: 1, last: 4) // expected-error{{argument 'x' must precede argument 'z'}} {{20-24=x: 1}} {{26-30=z: 3}}
-defargs2(first: 1, z: 3, y: 2, last: 4) // expected-error{{argument 'y' must precede argument 'z'}} {{20-24=y: 2}} {{26-30=z: 3}}
+defargs2(first: 1, z: 3, x: 1, last: 4) // expected-error{{argument 'x' must precede argument 'z'}} {{20-20=x: 1, }} {{24-30=}}
+defargs2(first: 1, z: 3, y: 2, last: 4) // expected-error{{argument 'y' must precede argument 'z'}} {{20-20=y: 2, }} {{24-30=}}
// Using defaults that have moved past a non-defaulted parameter
-defargs2(x: 1, first: 1, last: 4) // expected-error{{argument 'first' must precede argument 'x'}} {{10-14=first: 1}} {{16-24=x: 1}}
-defargs2(first: 1, last: 4, x: 1) // expected-error{{argument 'x' must precede argument 'last'}} {{20-27=x: 1}} {{29-33=last: 4}}
+defargs2(x: 1, first: 1, last: 4) // expected-error{{argument 'first' must precede argument 'x'}} {{10-10=first: 1, }} {{14-24=}}
+defargs2(first: 1, last: 4, x: 1) // expected-error{{argument 'x' must precede argument 'last'}} {{20-20=x: 1, }} {{27-33=}}
// -------------------------------------------
// Variadics
@@ -135,7 +135,7 @@
variadics1(x: 1, y: 2, 1, 2, 3)
// Using various (out-of-order)
-variadics1(1, 2, 3, 4, 5, x: 6, y: 7) // expected-error{{argument 'x' must precede unnamed argument #1}} {{12-25=x: 6}} {{27-31=1, 2, 3, 4, 5}}
+variadics1(1, 2, 3, 4, 5, x: 6, y: 7) // expected-error{{argument 'x' must precede unnamed argument #1}} {{12-12=x: 6, }} {{25-31=}}
func variadics2(x: Int, y: Int = 2, z: Int...) { } // expected-note {{'variadics2(x:y:z:)' declared here}}
@@ -150,7 +150,7 @@
// Using variadics (out-of-order)
variadics2(z: 1, 2, 3, y: 2) // expected-error{{missing argument for parameter 'x' in call}}
-variadics2(z: 1, 2, 3, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-22=x: 1}} {{24-28=z: 1, 2, 3}}
+variadics2(z: 1, 2, 3, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-12=x: 1, }} {{22-28=}}
func variadics3(_ x: Int..., y: Int = 2, z: Int = 3) { }
@@ -173,8 +173,8 @@
variadics3()
// Using variadics (out-of-order)
-variadics3(y: 0, 1, 2, 3) // expected-error{{unnamed argument #2 must precede argument 'y'}} {{12-16=1, 2, 3}} {{18-25=y: 0}}
-variadics3(z: 1, 1) // expected-error{{unnamed argument #2 must precede argument 'z'}} {{12-16=1}} {{18-19=z: 1}}
+variadics3(y: 0, 1, 2, 3) // expected-error{{unnamed argument #2 must precede argument 'y'}} {{12-12=1, 2, 3, }} {{16-25=}}
+variadics3(z: 1, 1) // expected-error{{unnamed argument #2 must precede argument 'z'}} {{12-12=1, }} {{16-19=}}
func variadics4(x: Int..., y: Int = 2, z: Int = 3) { }
@@ -198,7 +198,7 @@
// Using variadics (in-order, some missing)
variadics4(y: 0, x: 1, 2, 3) // expected-error{{extra argument in call}}
-variadics4(z: 1, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-16=x: 1}} {{18-22=z: 1}}
+variadics4(z: 1, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-12=x: 1, }} {{16-22=}}
func variadics5(_ x: Int, y: Int, _ z: Int...) { } // expected-note {{'variadics5(_:y:_:)' declared here}}
@@ -209,7 +209,7 @@
variadics5(1, y: 2, 1, 2, 3)
// Using various (out-of-order)
-variadics5(1, 2, 3, 4, 5, 6, y: 7) // expected-error{{argument 'y' must precede unnamed argument #2}} {{15-28=y: 7}} {{30-34=2, 3, 4, 5, 6}}
+variadics5(1, 2, 3, 4, 5, 6, y: 7) // expected-error{{argument 'y' must precede unnamed argument #2}} {{15-15=y: 7, }} {{28-34=}}
variadics5(y: 1, 2, 3, 4, 5, 6, 7) // expected-error{{missing argument for parameter #1 in call}}
func variadics6(x: Int..., y: Int = 2, z: Int) { } // expected-note 4 {{'variadics6(x:y:z:)' declared here}}
@@ -233,7 +233,7 @@
variadics6() // expected-error{{missing argument for parameter 'z' in call}}
func outOfOrder(_ a : Int, b: Int) {
- outOfOrder(b: 42, 52) // expected-error {{unnamed argument #2 must precede argument 'b'}} {{14-19=52}} {{21-23=b: 42}}
+ outOfOrder(b: 42, 52) // expected-error {{unnamed argument #2 must precede argument 'b'}} {{14-14=52, }} {{19-23=}}
}
// -------------------------------------------
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.asan-x86_64.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.asan-x86_64.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.asan-x86_64.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.tsan-x86_64.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.tsan-x86_64.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.tsan-x86_64.a
diff --git a/test/Driver/sanitize_coverage.swift b/test/Driver/sanitize_coverage.swift
index efcccc2..71f4a0b 100644
--- a/test/Driver/sanitize_coverage.swift
+++ b/test/Driver/sanitize_coverage.swift
@@ -1,4 +1,3 @@
-// XFAIL: linux
// Different sanitizer coverage types
// RUN: %swiftc_driver -driver-print-jobs -sanitize-coverage=func -sanitize=address %s | %FileCheck -check-prefix=SANCOV_FUNC %s
// RUN: %swiftc_driver -driver-print-jobs -sanitize-coverage=bb -sanitize=address %s | %FileCheck -check-prefix=SANCOV_BB %s
diff --git a/test/Driver/sanitizers.swift b/test/Driver/sanitizers.swift
index 9ca5619..953bfed 100644
--- a/test/Driver/sanitizers.swift
+++ b/test/Driver/sanitizers.swift
@@ -5,7 +5,7 @@
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target arm64-apple-tvos9.0 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_tvOS %s
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target i386-apple-watchos2.0 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_watchOS_SIM %s
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target armv7k-apple-watchos2.0 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_watchOS %s
-// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=ASAN_LINUX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=ASAN_LINUX %s
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=TSAN -check-prefix=TSAN_OSX %s
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86-apple-macosx10.9 %s 2>&1 | %FileCheck -check-prefix=TSAN_OSX_32 %s
@@ -15,12 +15,20 @@
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target arm64-apple-tvos9.0 %s 2>&1 | %FileCheck -check-prefix=TSAN_tvOS %s
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target i386-apple-watchos2.0 %s 2>&1 | %FileCheck -check-prefix=TSAN_watchOS_SIM %s
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target armv7k-apple-watchos2.0 %s 2>&1 | %FileCheck -check-prefix=TSAN_watchOS %s
-// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=TSAN_LINUX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=TSAN_LINUX %s
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address,unknown %s 2>&1 | %FileCheck -check-prefix=BADARG %s
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -sanitize=unknown %s 2>&1 | %FileCheck -check-prefix=BADARG %s
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address,thread %s 2>&1 | %FileCheck -check-prefix=INCOMPATIBLESANITIZERS %s
+/*
+ * Make sure we don't accidentally add the sanitizer library path when building libraries or modules
+ */
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -emit-library -sanitize=address -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck --implicit-check-not=ASAN_LINUX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -emit-module -sanitize=address -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck --implicit-check-not=ASAN_LINUX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -emit-library -sanitize=thread -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck --implicit-check-not=TSAN_LINUX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -emit-module -sanitize=thread -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck --implicit-check-not=TSAN_LINUX %s
+
// ASAN: swift
// ASAN: -sanitize=address
@@ -31,7 +39,7 @@
// ASAN_tvOS: lib/swift/clang/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib
// ASAN_watchOS_SIM: lib/swift/clang/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib
// ASAN_watchOS: lib/swift/clang/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib
-// ASAN_LINUX: unsupported option '-sanitize=address' for target 'x86_64-unknown-linux-gnu'
+// ASAN_LINUX: lib/swift/clang/lib/linux/libclang_rt.asan-x86_64.a
// ASAN: -rpath @executable_path
@@ -46,7 +54,7 @@
// TSAN_tvOS: unsupported option '-sanitize=thread' for target 'arm64-apple-tvos9.0'
// TSAN_watchOS_SIM: unsupported option '-sanitize=thread' for target 'i386-apple-watchos2.0'
// TSAN_watchOS: unsupported option '-sanitize=thread' for target 'armv7k-apple-watchos2.0'
-// TSAN_LINUX: unsupported option '-sanitize=thread' for target 'x86_64-unknown-linux-gnu'
+// TSAN_LINUX: lib/swift/clang/lib/linux/libclang_rt.tsan-x86_64.a
// TSAN: -rpath @executable_path
diff --git a/test/IRGen/asan-attributes.swift b/test/IRGen/asan-attributes.swift
index 5498f76..dc0c680 100644
--- a/test/IRGen/asan-attributes.swift
+++ b/test/IRGen/asan-attributes.swift
@@ -2,8 +2,6 @@
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-ir -sanitize=address %s | %FileCheck %s -check-prefix=ASAN
-// XFAIL: linux
-
func test() {
}
diff --git a/test/SILGen/tsan_instrumentation.swift b/test/SILGen/tsan_instrumentation.swift
index ff9ffb0..06f1fc6 100644
--- a/test/SILGen/tsan_instrumentation.swift
+++ b/test/SILGen/tsan_instrumentation.swift
@@ -1,6 +1,5 @@
// RUN: %target-swift-frontend -sanitize=thread -emit-silgen %s | %FileCheck %s
// REQUIRES: tsan_runtime
-// XFAIL: linux
func takesInout(_ p: inout Int) { }
func takesInout(_ p: inout MyStruct) { }
diff --git a/test/Sanitizers/sanitizer_coverage.swift b/test/Sanitizers/sanitizer_coverage.swift
index eb2ddb3..9bbc6d1 100644
--- a/test/Sanitizers/sanitizer_coverage.swift
+++ b/test/Sanitizers/sanitizer_coverage.swift
@@ -8,7 +8,6 @@
// REQUIRES: asan_runtime
// For now restrict this test to platforms where we know this test will pass
// REQUIRES: CPU=x86_64
-// REQUIRES: OS=macosx
func sayHello() {
print("Hello")
diff --git a/test/stdlib/TestJSONEncoder.swift b/test/stdlib/TestJSONEncoder.swift
index 4882858..e758c33 100644
--- a/test/stdlib/TestJSONEncoder.swift
+++ b/test/stdlib/TestJSONEncoder.swift
@@ -408,27 +408,13 @@
}
// MARK: - Helper Global Functions
-func expectEqualPaths(_ lhs: [CodingKey?], _ rhs: [CodingKey?], _ prefix: String) {
+func expectEqualPaths(_ lhs: [CodingKey], _ rhs: [CodingKey], _ prefix: String) {
if lhs.count != rhs.count {
- expectUnreachable("\(prefix) [CodingKey?].count mismatch: \(lhs.count) != \(rhs.count)")
+ expectUnreachable("\(prefix) [CodingKey].count mismatch: \(lhs.count) != \(rhs.count)")
return
}
- for (k1, k2) in zip(lhs, rhs) {
- switch (k1, k2) {
- case (.none, .none): continue
- case (.some(let _k1), .none):
- expectUnreachable("\(prefix) CodingKey mismatch: \(type(of: _k1)) != nil")
- return
- case (.none, .some(let _k2)):
- expectUnreachable("\(prefix) CodingKey mismatch: nil != \(type(of: _k2))")
- return
- default: break
- }
-
- let key1 = k1!
- let key2 = k2!
-
+ for (key1, key2) in zip(lhs, rhs) {
switch (key1.intValue, key2.intValue) {
case (.none, .none): break
case (.some(let i1), .none):
@@ -788,7 +774,7 @@
}
}
- func _testNestedContainers(in encoder: Encoder, baseCodingPath: [CodingKey?]) {
+ func _testNestedContainers(in encoder: Encoder, baseCodingPath: [CodingKey]) {
expectEqualPaths(encoder.codingPath, baseCodingPath, "New encoder has non-empty codingPath.")
// codingPath should not change upon fetching a non-nested container.
@@ -822,30 +808,52 @@
// Nested Unkeyed Container
do {
// Nested container for key should have a new key pushed on.
- var secondLevelContainer = firstLevelContainer.nestedUnkeyedContainer(forKey: .a)
+ var secondLevelContainer = firstLevelContainer.nestedUnkeyedContainer(forKey: .b)
expectEqualPaths(encoder.codingPath, baseCodingPath, "Top-level Encoder's codingPath changed.")
expectEqualPaths(firstLevelContainer.codingPath, baseCodingPath, "First-level keyed container's codingPath changed.")
- expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.a], "New second-level keyed container had unexpected codingPath.")
+ expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.b], "New second-level keyed container had unexpected codingPath.")
// Appending a keyed container should not change existing coding paths.
let thirdLevelContainerKeyed = secondLevelContainer.nestedContainer(keyedBy: IntermediateCodingKeys.self)
expectEqualPaths(encoder.codingPath, baseCodingPath, "Top-level Encoder's codingPath changed.")
expectEqualPaths(firstLevelContainer.codingPath, baseCodingPath, "First-level keyed container's codingPath changed.")
- expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.a], "Second-level unkeyed container's codingPath changed.")
- expectEqualPaths(thirdLevelContainerKeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.a, nil], "New third-level keyed container had unexpected codingPath.")
+ expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.b], "Second-level unkeyed container's codingPath changed.")
+ expectEqualPaths(thirdLevelContainerKeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.b, _TestKey(index: 0)], "New third-level keyed container had unexpected codingPath.")
// Appending an unkeyed container should not change existing coding paths.
let thirdLevelContainerUnkeyed = secondLevelContainer.nestedUnkeyedContainer()
expectEqualPaths(encoder.codingPath, baseCodingPath, "Top-level Encoder's codingPath changed.")
expectEqualPaths(firstLevelContainer.codingPath, baseCodingPath, "First-level keyed container's codingPath changed.")
- expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.a], "Second-level unkeyed container's codingPath changed.")
- expectEqualPaths(thirdLevelContainerUnkeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.a, nil], "New third-level unkeyed container had unexpected codingPath.")
+ expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.b], "Second-level unkeyed container's codingPath changed.")
+ expectEqualPaths(thirdLevelContainerUnkeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.b, _TestKey(index: 1)], "New third-level unkeyed container had unexpected codingPath.")
}
}
}
// MARK: - Helper Types
+/// A key type which can take on any string or integer value.
+/// This needs to mirror _JSONKey.
+fileprivate struct _TestKey : CodingKey {
+ var stringValue: String
+ var intValue: Int?
+
+ init?(stringValue: String) {
+ self.stringValue = stringValue
+ self.intValue = nil
+ }
+
+ init?(intValue: Int) {
+ self.stringValue = "\(intValue)"
+ self.intValue = intValue
+ }
+
+ init(index: Int) {
+ self.stringValue = "Index \(index)"
+ self.intValue = index
+ }
+}
+
/// Wraps a type T so that it can be encoded at the top level of a payload.
fileprivate struct TopLevelWrapper<T> : Codable, Equatable where T : Codable, T : Equatable {
let value: T
diff --git a/test/stdlib/TestPlistEncoder.swift b/test/stdlib/TestPlistEncoder.swift
index 9f55f38..f20b200 100644
--- a/test/stdlib/TestPlistEncoder.swift
+++ b/test/stdlib/TestPlistEncoder.swift
@@ -192,27 +192,13 @@
}
// MARK: - Helper Global Functions
-func expectEqualPaths(_ lhs: [CodingKey?], _ rhs: [CodingKey?], _ prefix: String) {
+func expectEqualPaths(_ lhs: [CodingKey], _ rhs: [CodingKey], _ prefix: String) {
if lhs.count != rhs.count {
- expectUnreachable("\(prefix) [CodingKey?].count mismatch: \(lhs.count) != \(rhs.count)")
+ expectUnreachable("\(prefix) [CodingKey].count mismatch: \(lhs.count) != \(rhs.count)")
return
}
- for (k1, k2) in zip(lhs, rhs) {
- switch (k1, k2) {
- case (.none, .none): continue
- case (.some(let _k1), .none):
- expectUnreachable("\(prefix) CodingKey mismatch: \(type(of: _k1)) != nil")
- return
- case (.none, .some(let _k2)):
- expectUnreachable("\(prefix) CodingKey mismatch: nil != \(type(of: _k2))")
- return
- default: break
- }
-
- let key1 = k1!
- let key2 = k2!
-
+ for (key1, key2) in zip(lhs, rhs) {
switch (key1.intValue, key2.intValue) {
case (.none, .none): break
case (.some(let i1), .none):
@@ -572,7 +558,7 @@
}
}
- func _testNestedContainers(in encoder: Encoder, baseCodingPath: [CodingKey?]) {
+ func _testNestedContainers(in encoder: Encoder, baseCodingPath: [CodingKey]) {
expectEqualPaths(encoder.codingPath, baseCodingPath, "New encoder has non-empty codingPath.")
// codingPath should not change upon fetching a non-nested container.
@@ -606,30 +592,52 @@
// Nested Unkeyed Container
do {
// Nested container for key should have a new key pushed on.
- var secondLevelContainer = firstLevelContainer.nestedUnkeyedContainer(forKey: .a)
+ var secondLevelContainer = firstLevelContainer.nestedUnkeyedContainer(forKey: .b)
expectEqualPaths(encoder.codingPath, baseCodingPath, "Top-level Encoder's codingPath changed.")
expectEqualPaths(firstLevelContainer.codingPath, baseCodingPath, "First-level keyed container's codingPath changed.")
- expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.a], "New second-level keyed container had unexpected codingPath.")
+ expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.b], "New second-level keyed container had unexpected codingPath.")
// Appending a keyed container should not change existing coding paths.
let thirdLevelContainerKeyed = secondLevelContainer.nestedContainer(keyedBy: IntermediateCodingKeys.self)
expectEqualPaths(encoder.codingPath, baseCodingPath, "Top-level Encoder's codingPath changed.")
expectEqualPaths(firstLevelContainer.codingPath, baseCodingPath, "First-level keyed container's codingPath changed.")
- expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.a], "Second-level unkeyed container's codingPath changed.")
- expectEqualPaths(thirdLevelContainerKeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.a, nil], "New third-level keyed container had unexpected codingPath.")
+ expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.b], "Second-level unkeyed container's codingPath changed.")
+ expectEqualPaths(thirdLevelContainerKeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.b, _TestKey(index: 0)], "New third-level keyed container had unexpected codingPath.")
// Appending an unkeyed container should not change existing coding paths.
let thirdLevelContainerUnkeyed = secondLevelContainer.nestedUnkeyedContainer()
expectEqualPaths(encoder.codingPath, baseCodingPath, "Top-level Encoder's codingPath changed.")
expectEqualPaths(firstLevelContainer.codingPath, baseCodingPath, "First-level keyed container's codingPath changed.")
- expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.a], "Second-level unkeyed container's codingPath changed.")
- expectEqualPaths(thirdLevelContainerUnkeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.a, nil], "New third-level unkeyed container had unexpected codingPath.")
+ expectEqualPaths(secondLevelContainer.codingPath, baseCodingPath + [TopLevelCodingKeys.b], "Second-level unkeyed container's codingPath changed.")
+ expectEqualPaths(thirdLevelContainerUnkeyed.codingPath, baseCodingPath + [TopLevelCodingKeys.b, _TestKey(index: 1)], "New third-level unkeyed container had unexpected codingPath.")
}
}
}
// MARK: - Helper Types
+/// A key type which can take on any string or integer value.
+/// This needs to mirror _PlistKey.
+fileprivate struct _TestKey : CodingKey {
+ var stringValue: String
+ var intValue: Int?
+
+ init?(stringValue: String) {
+ self.stringValue = stringValue
+ self.intValue = nil
+ }
+
+ init?(intValue: Int) {
+ self.stringValue = "\(intValue)"
+ self.intValue = intValue
+ }
+
+ init(index: Int) {
+ self.stringValue = "Index \(index)"
+ self.intValue = index
+ }
+}
+
/// Wraps a type T so that it can be encoded at the top level of a payload.
fileprivate struct TopLevelWrapper<T> : Codable, Equatable where T : Codable, T : Equatable {
let value: T
diff --git a/validation-test/compiler_crashers/28812-getgenericparams.swift b/validation-test/compiler_crashers/28812-getgenericparams.swift
new file mode 100644
index 0000000..c7e3f95
--- /dev/null
+++ b/validation-test/compiler_crashers/28812-getgenericparams.swift
@@ -0,0 +1,13 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 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
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+class a<a{{}
+let d=a
+& a
+P{{{}}}typealias a:A protocol A
diff --git a/validation-test/compiler_crashers/28813-swift-genericsignature-enumeratepairedrequirements-llvm-function-ref-bool-swift-.swift b/validation-test/compiler_crashers/28813-swift-genericsignature-enumeratepairedrequirements-llvm-function-ref-bool-swift-.swift
new file mode 100644
index 0000000..cfa8ae63
--- /dev/null
+++ b/validation-test/compiler_crashers/28813-swift-genericsignature-enumeratepairedrequirements-llvm-function-ref-bool-swift-.swift
@@ -0,0 +1,9 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 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
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A:Collection}extension CountableRange{protocol P{protocol P{struct a:A{}typealias a:A}{}typealias e:P
diff --git a/validation-test/compiler_crashers/28814-basety-hasunboundgenerictype.swift b/validation-test/compiler_crashers/28814-basety-hasunboundgenerictype.swift
new file mode 100644
index 0000000..2c89be7
--- /dev/null
+++ b/validation-test/compiler_crashers/28814-basety-hasunboundgenerictype.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 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
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol P{typealias a=FlattenCollection}{{P.a.a}}protocol P
diff --git a/validation-test/compiler_crashers/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift b/validation-test/compiler_crashers/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
new file mode 100644
index 0000000..1affb55
--- /dev/null
+++ b/validation-test/compiler_crashers/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 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
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+extension CountableRange{{}{}protocol P{typealias a:A{}func 丏
+protocol A:CountableRange
diff --git a/validation-test/compiler_crashers/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift b/validation-test/compiler_crashers/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
new file mode 100644
index 0000000..1c78fe4
--- /dev/null
+++ b/validation-test/compiler_crashers/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 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
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol b{{}{}class a{{}class A}{}typealias a
+init(t:Self.a.a.a
diff --git a/validation-test/compiler_crashers/28817-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers/28817-swift-typebase-getdesugaredtype.swift
new file mode 100644
index 0000000..b8edc95
--- /dev/null
+++ b/validation-test/compiler_crashers/28817-swift-typebase-getdesugaredtype.swift
@@ -0,0 +1,9 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 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
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+class a{class a}func a:P._=a.a{