Merge pull request #14777 from cwakamo/introducing-CustomPlaygroundDisplayConvertible-4.1

[4.1] [SE-0198] Introduced CustomPlaygroundDisplayConvertible and deprecated PlaygroundQuickLook/CustomPlaygroundQuickLookable
diff --git a/stdlib/public/SDK/AppKit/AppKit.swift b/stdlib/public/SDK/AppKit/AppKit.swift
index 9ee047b..ffb9f7d 100644
--- a/stdlib/public/SDK/AppKit/AppKit.swift
+++ b/stdlib/public/SDK/AppKit/AppKit.swift
@@ -14,6 +14,7 @@
 @_exported import AppKit
 
 extension NSCursor : _DefaultCustomPlaygroundQuickLookable {
+  @available(*, deprecated, message: "NSCursor._defaultCustomPlaygroundQuickLook will be removed in a future Swift version")
   public var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook {
     return .image(image)
   }
@@ -24,6 +25,7 @@
 }
 
 extension NSView : _DefaultCustomPlaygroundQuickLookable {
+  @available(*, deprecated, message: "NSView._defaultCustomPlaygroundQuickLook will be removed in a future Swift version")
   public var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook {
     // if you set NSView.needsDisplay, you can get yourself in a recursive scenario where the same view
     // could need to draw itself in order to get a QLObject for itself, which in turn if your code was
diff --git a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
index 7ed88df..6703ab8 100644
--- a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
+++ b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
@@ -232,6 +232,7 @@
     return Mirror(self, children: ["x": x, "y": y], displayStyle: .`struct`)
   }
 
+  @available(*, deprecated, message: "CGPoint.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .point(Double(x), Double(y))
   }
@@ -299,6 +300,7 @@
       displayStyle: .`struct`)
   }
 
+  @available(*, deprecated, message: "CGSize.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .size(Double(width), Double(height))
   }
@@ -436,6 +438,7 @@
       displayStyle: .`struct`)
   }
 
+  @available(*, deprecated, message: "CGRect.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .rectangle(
       Double(origin.x), Double(origin.y),
diff --git a/stdlib/public/SDK/Foundation/Date.swift b/stdlib/public/SDK/Foundation/Date.swift
index c179f30..d11270f 100644
--- a/stdlib/public/SDK/Foundation/Date.swift
+++ b/stdlib/public/SDK/Foundation/Date.swift
@@ -280,6 +280,7 @@
         return df.string(from: self)
     }
     
+    @available(*, deprecated, message: "Date.customPlaygroundQuickLook will be removed in a future Swift version")
     public var customPlaygroundQuickLook: PlaygroundQuickLook {
         return .text(summary)
     }
diff --git a/stdlib/public/SDK/Foundation/NSDate.swift b/stdlib/public/SDK/Foundation/NSDate.swift
index a69ef73..4896e9d 100644
--- a/stdlib/public/SDK/Foundation/NSDate.swift
+++ b/stdlib/public/SDK/Foundation/NSDate.swift
@@ -21,6 +21,7 @@
     return df.string(from: self as Date)
   }
 
+  @available(*, deprecated, message: "NSDate.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(summary)
   }
diff --git a/stdlib/public/SDK/Foundation/NSRange.swift b/stdlib/public/SDK/Foundation/NSRange.swift
index e05673e..85228fc 100644
--- a/stdlib/public/SDK/Foundation/NSRange.swift
+++ b/stdlib/public/SDK/Foundation/NSRange.swift
@@ -198,6 +198,7 @@
 }
 
 extension NSRange : CustomPlaygroundQuickLookable {
+    @available(*, deprecated, message: "NSRange.customPlaygroundQuickLook will be removed in a future Swift version")
     public var customPlaygroundQuickLook: PlaygroundQuickLook {
         return .range(Int64(location), Int64(length))
     }
diff --git a/stdlib/public/SDK/Foundation/NSString.swift b/stdlib/public/SDK/Foundation/NSString.swift
index fbbe27e..904185f 100644
--- a/stdlib/public/SDK/Foundation/NSString.swift
+++ b/stdlib/public/SDK/Foundation/NSString.swift
@@ -113,6 +113,7 @@
 }
 
 extension NSString : CustomPlaygroundQuickLookable {
+  @available(*, deprecated, message: "NSString.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(self as String)
   }
diff --git a/stdlib/public/SDK/Foundation/NSURL.swift b/stdlib/public/SDK/Foundation/NSURL.swift
index b62c374..6cf6522 100644
--- a/stdlib/public/SDK/Foundation/NSURL.swift
+++ b/stdlib/public/SDK/Foundation/NSURL.swift
@@ -13,6 +13,7 @@
 @_exported import Foundation // Clang module
 
 extension NSURL : CustomPlaygroundQuickLookable {
+  @available(*, deprecated, message: "NSURL.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     guard let str = absoluteString else { return .text("Unknown URL") }
     return .url(str)
diff --git a/stdlib/public/SDK/Foundation/URL.swift b/stdlib/public/SDK/Foundation/URL.swift
index cf2dad3..47c2e0a 100644
--- a/stdlib/public/SDK/Foundation/URL.swift
+++ b/stdlib/public/SDK/Foundation/URL.swift
@@ -1202,6 +1202,7 @@
 }
 
 extension URL : CustomPlaygroundQuickLookable {
+    @available(*, deprecated, message: "URL.customPlaygroundQuickLook will be removed in a future Swift version")
     public var customPlaygroundQuickLook: PlaygroundQuickLook {
         return .url(absoluteString)
     }
diff --git a/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb b/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
index 746a0f1..aae60bb 100644
--- a/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
+++ b/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
@@ -15,6 +15,7 @@
 % for Self in ['SKShapeNode', 'SKSpriteNode', 'SKTextureAtlas', 'SKTexture']:
 
 extension ${Self} : CustomPlaygroundQuickLookable {
+  @available(*, deprecated, message: "${Self}.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     let data = (self as AnyObject)._copyImageData?() as Data?
 
diff --git a/stdlib/public/SDK/UIKit/UIKit.swift b/stdlib/public/SDK/UIKit/UIKit.swift
index 9be02a5..abf0015 100644
--- a/stdlib/public/SDK/UIKit/UIKit.swift
+++ b/stdlib/public/SDK/UIKit/UIKit.swift
@@ -231,6 +231,7 @@
 }
 
 extension UIView : _DefaultCustomPlaygroundQuickLookable {
+  @available(*, deprecated, message: "UIView._defaultCustomPlaygroundQuickLook will be removed in a future Swift version")
   public var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook {
     if _UIViewQuickLookState.views.contains(self) {
       return .view(UIImage())
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 0d1ef30..95401ff 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -167,6 +167,7 @@
   CollectionOfOne.swift
   ExistentialCollection.swift.gyb
   Mirror.swift
+  PlaygroundDisplay.swift
   CommandLine.swift
   SliceBuffer.swift
   Tuple.swift.gyb
diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json
index e94dd6c..bd9eeca 100644
--- a/stdlib/public/core/GroupInfo.json
+++ b/stdlib/public/core/GroupInfo.json
@@ -148,6 +148,9 @@
     "CompilerProtocols.swift",
     "ShadowProtocols.swift"
   ],
+  "Playground": [
+    "PlaygroundDisplay.swift"
+  ],
   "Misc": [
     "AnyHashable.swift",
     "Interval.swift",
diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift
index c3fca5b..20f282d 100644
--- a/stdlib/public/core/Mirror.swift
+++ b/stdlib/public/core/Mirror.swift
@@ -659,7 +659,19 @@
 //===--- QuickLooks -------------------------------------------------------===//
 
 /// The sum of types that can be used as a Quick Look representation.
+///
+/// - note: `PlaygroundQuickLook` is deprecated, and will be removed from the
+/// standard library in a future Swift release. Customizing display for in a
+/// playground is now done using the `CustomPlaygroundDisplayConvertible`
+/// protocol, which does not use the `PlaygroundQuickLook` enum. Please remove
+/// your uses of `PlaygroundQuickLook`, or conditionalize your use such that it
+/// is only present when compiling with Swift 4.0 or Swift 3.2 or earlier:
+///
+///     #if !(swift(>=4.1) || swift(>=3.3) && !swift(>=4.0))
+///       /* OK to use PlaygroundQuickLook */
+///     #endif
 @_fixed_layout // FIXME(sil-serialize-all)
+@available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
 public enum PlaygroundQuickLook {
   /// Plain text.
   case text(String)
@@ -746,6 +758,7 @@
   /// - Parameter subject: The instance to represent with the resulting Quick
   ///   Look.
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version.")
   public init(reflecting subject: Any) {
     if let customized = subject as? CustomPlaygroundQuickLookable {
       self = customized.customPlaygroundQuickLook
@@ -771,6 +784,23 @@
 /// with the representation supplied for your type by default, you can make it
 /// conform to the `CustomPlaygroundQuickLookable` protocol and provide a
 /// custom `PlaygroundQuickLook` instance.
+///
+/// - note: `CustomPlaygroundQuickLookable` is deprecated, and will be removed
+/// from the standard library in a future Swift release. Please migrate to the
+/// `CustomPlaygroundDisplayConvertible` protocol instead, or conditionalize
+/// your conformance such that it is only present when compiling with Swift 4.0
+/// or Swift 3.2 or earlier:
+///
+///     #if swift(>=4.1) || swift(>=3.3) && !swift(>=4.0)
+///       // With Swift 4.1 and later (including Swift 3.3 and later), implement
+///       // CustomPlaygroundDisplayConvertible.
+///       extension MyType: CustomPlaygroundDisplayConvertible { /*...*/ }
+///     #else
+///       // Otherwise, on Swift 4.0 and Swift 3.2 and earlier,
+///       // implement CustomPlaygroundQuickLookable.
+///       extension MyType: CustomPlaygroundQuickLookable { /*...*/ }
+///     #endif
+@available(*, deprecated, message: "CustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
 public protocol CustomPlaygroundQuickLookable {
   /// A custom playground Quick Look for this instance.
   ///
@@ -782,6 +812,7 @@
 
 // A workaround for <rdar://problem/26182650>
 // FIXME(ABI)#50 (Dynamic Dispatch for Class Extensions) though not if it moves out of stdlib.
+@available(*, deprecated, message: "_DefaultCustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
 public protocol _DefaultCustomPlaygroundQuickLookable {
   var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook { get }
 }
diff --git a/stdlib/public/core/Mirrors.swift.gyb b/stdlib/public/core/Mirrors.swift.gyb
index a5724c5..3df3a67 100644
--- a/stdlib/public/core/Mirrors.swift.gyb
+++ b/stdlib/public/core/Mirrors.swift.gyb
@@ -48,6 +48,7 @@
 extension ${Type[0]} : CustomPlaygroundQuickLookable {
   /// A custom playground Quick Look for the `${Type[0]}` instance.
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "${Type[0]}.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return ${Type[1]}(${Type[2]})
   }
diff --git a/stdlib/public/core/PlaygroundDisplay.swift b/stdlib/public/core/PlaygroundDisplay.swift
new file mode 100644
index 0000000..ef5dd66
--- /dev/null
+++ b/stdlib/public/core/PlaygroundDisplay.swift
@@ -0,0 +1,63 @@
+//===--- PlaygroundDisplay.swift ------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 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
+//
+//===----------------------------------------------------------------------===//
+
+/// A type that supplies a custom description for playground logging.
+///
+/// All types have a default description for playgrounds. This protocol
+/// allows types to provide custom descriptions which are then logged in
+/// place of the original instance.
+///
+/// Playground logging can generate, at a minimum, a structured description
+/// of any type. Playground logging is also capable of generating a richer,
+/// more specialized description of core types -- for instance, the contents
+/// of a `String` are logged, as are the components of an `NSColor` or
+/// `UIColor`.
+///
+/// The current playground logging implementation logs specialized
+/// descriptions of at least the following types:
+///
+/// - `String` and `NSString`
+/// - `Int` and `UInt` (including the sized variants)
+/// - `Float` and `Double`
+/// - `Bool`
+/// - `Date` and `NSDate`
+/// - `NSAttributedString`
+/// - `NSNumber`
+/// - `NSRange`
+/// - `URL` and `NSURL`
+/// - `CGPoint`, `CGSize`, and `CGRect`
+/// - `NSColor`, `UIColor`, `CGColor`, and `CIColor`
+/// - `NSImage`, `UIImage`, `CGImage`, and `CIImage`
+/// - `NSBezierPath` and `UIBezierPath`
+/// - `NSView` and `UIView`
+///
+/// Playground logging may also be able to support specialized descriptions
+/// of other types.
+///
+/// Implementors of `CustomPlaygroundDisplayConvertible` may return a value of
+/// one of the above types to also receive a specialized log description.
+/// Implementors may also return any other type, and playground logging will
+/// generated structured logging for the returned value.
+///
+/// - note: `CustomPlaygroundDisplayConvertible` conformances chain -- that is,
+///   if `playgroundDescription` returns an instance which itself conforms to
+///   `CustomPlaygroundDisplayConvertible`, then playground logging will ask for
+///   that instance's `playgroundDescription` and so on. It is permissible for
+///   playground logging implementations to place a reasonable limit on this
+///   kind of chaining to prevent infinite loops.
+public protocol CustomPlaygroundDisplayConvertible {
+  /// Returns the custom playground description for this instance.
+  ///
+  /// If this type has value semantics, the instance returned should be
+  /// unaffected by subsequent mutations if possible.
+  var playgroundDescription: Any { get }
+}
\ No newline at end of file
diff --git a/stdlib/public/core/StringUTF16.swift b/stdlib/public/core/StringUTF16.swift
index 44a0c30..7d89874 100644
--- a/stdlib/public/core/StringUTF16.swift
+++ b/stdlib/public/core/StringUTF16.swift
@@ -440,6 +440,7 @@
 
 extension String.UTF16View : CustomPlaygroundQuickLookable {
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "UTF16View.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(description)
   }
diff --git a/stdlib/public/core/StringUTF8.swift b/stdlib/public/core/StringUTF8.swift
index 5a84ca9..1a10529 100644
--- a/stdlib/public/core/StringUTF8.swift
+++ b/stdlib/public/core/StringUTF8.swift
@@ -659,6 +659,7 @@
 
 extension String.UTF8View : CustomPlaygroundQuickLookable {
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "UTF8View.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(description)
   }
diff --git a/stdlib/public/core/StringUnicodeScalarView.swift b/stdlib/public/core/StringUnicodeScalarView.swift
index 8280515..4d853b7 100644
--- a/stdlib/public/core/StringUnicodeScalarView.swift
+++ b/stdlib/public/core/StringUnicodeScalarView.swift
@@ -509,6 +509,7 @@
 
 extension String.UnicodeScalarView : CustomPlaygroundQuickLookable {
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "UnicodeScalarView.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(description)
   }
diff --git a/stdlib/public/core/Substring.swift.gyb b/stdlib/public/core/Substring.swift.gyb
index 9092187..632ecdd 100644
--- a/stdlib/public/core/Substring.swift.gyb
+++ b/stdlib/public/core/Substring.swift.gyb
@@ -365,6 +365,7 @@
 
 extension Substring : CustomPlaygroundQuickLookable {
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "Substring.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return String(self).customPlaygroundQuickLook
   }
diff --git a/stdlib/public/core/UnsafePointer.swift.gyb b/stdlib/public/core/UnsafePointer.swift.gyb
index 146548c..5b5ec76 100644
--- a/stdlib/public/core/UnsafePointer.swift.gyb
+++ b/stdlib/public/core/UnsafePointer.swift.gyb
@@ -1000,6 +1000,7 @@
   }
 
   @_inlineable // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "${Self}.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(summary)
   }
diff --git a/stdlib/public/core/UnsafeRawPointer.swift.gyb b/stdlib/public/core/UnsafeRawPointer.swift.gyb
index 4a3e4aa..5d0259c 100644
--- a/stdlib/public/core/UnsafeRawPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeRawPointer.swift.gyb
@@ -996,6 +996,7 @@
 extension Unsafe${Mutable}RawPointer : CustomPlaygroundQuickLookable {
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
+  @available(*, deprecated, message: "Unsafe${Mutable}RawPointer.customPlaygroundQuickLook will be removed in a future Swift version")
   internal var summary: String {
     let selfType = "${Self}"
     let ptrValue = UInt64(