 }
 
 //===----------------------------------------------------------------------===//
-// Optional Conformance
+// Optional/Collection Type Conformances
 //===----------------------------------------------------------------------===//
+
+fileprivate func assertTypeIsEncodable<T>(_ type: T.Type, in wrappingType: Any.Type) {
+    guard T.self is Encodable.Type else {
+        if T.self == Encodable.self || T.self == Codable.self {
+            preconditionFailure("\(wrappingType) does not conform to Encodable because Encodable does not conform to itself. You must use a concrete type to encode or decode.")
+        } else {
+            preconditionFailure("\(wrappingType) does not conform to Encodable because \(T.self) does not conform to Encodable.")
+        }
+    }
+}
+
+fileprivate func assertTypeIsDecodable<T>(_ type: T.Type, in wrappingType: Any.Type) {
+    guard T.self is Decodable.Type else {
+        if T.self == Decodable.self || T.self == Codable.self {
+            preconditionFailure("\(wrappingType) does not conform to Decodable because Decodable does not conform to itself. You must use a concrete type to encode or decode.")
+        } else {
+            preconditionFailure("\(wrappingType) does not conform to Decodable because \(T.self) does not conform to Decodable.")
+        }
+    }
+}
 
 // FIXME: Uncomment when conditional conformance is available.
 extension Optional : Encodable /* where Wrapped : Encodable */ {
     public func encode(to encoder: Encoder) throws {
-        guard Wrapped.self is Encodable.Type else {
-            preconditionFailure("\(type(of: self)) does not conform to Encodable because \(Wrapped.self) does not conform to Encodable.")
-        }
+        assertTypeIsEncodable(Wrapped.self, in: type(of: self))
 
         var container = encoder.singleValueContainer()
         switch self {


extension Set : Encodable /* where Element : Encodable */ {
    public func encode(to encoder: Encoder) throws {
        guard Element.self is Encodable.Type else {
            preconditionFailure("\(type(of: self)) does not conform to Encodable because \(Element.self) does not conform to Encodable.")
        }

        var container = encoder.unkeyedContainer()
        for element in self {

    }
}

// FIXME: Uncomment when conditional conformance is available.
extension Array : Encodable /* where Element : Encodable */ {
    public func encode(to encoder: Encoder) throws {
        assertTypeIsEncodable(Element.self, in: type(of: self))

        var container = encoder.unkeyedContainer()
        for element in self {
