Merge pull request #17991 from rudkx/remove-binding-optimization-2

[ConstraintSystem] Remove an attempted optimization that we've not
diff --git a/docs/LibraryEvolution.rst b/docs/LibraryEvolution.rst
index 84924db..c3afef6 100644
--- a/docs/LibraryEvolution.rst
+++ b/docs/LibraryEvolution.rst
@@ -89,10 +89,10 @@
 clients (distribution via source, static library, or embedded/sandboxed dynamic
 library, as used by the `Swift Package Manager`_). Because a client always uses
 a particular version of such a library, there is no need to worry about
-backwards- or forwards-compatibility. Just as developers with a single app
-target are not forced to think about access control, anyone writing a bundled
-library should not be required to use any of the annotations described below in
-order to achieve full performance.
+backwards- or forwards-compatibility at the binary level. Just as developers
+with a single app target are not forced to think about access control, anyone
+writing a bundled library should not be required to use any of the annotations
+described below in order to achieve full performance.
 
 .. _Swift Package Manager: https://swift.org/package-manager/
 
@@ -172,7 +172,7 @@
 A library's API is already marked with the ``public`` modifier, but if a
 client wants to work with multiple releases of the library, the API needs
 versioning information as well. A *versioned entity* represents anything with a
-runtime presence that a client may rely on; its version records when the entity
+run-time presence that a client may rely on; its version records when the entity
 was first exposed publicly in its library. Put another way, it is the oldest
 version of the library where the entity may be used.
 
@@ -182,6 +182,8 @@
 - Protocol conformances may be versioned entities, despite not explicitly having
   a declaration in Swift, because a client may depend on them.
   See `New Conformances`_, below.
+- Typealiases are treated as versioned entities for the purpose of verifying
+  availability, even though they have no run-time presence.
 
 In a versioned library, any top-level public entity from the list above may not
 be made ``public`` (or ``open``) without an appropriate version. A public
@@ -220,7 +222,7 @@
     @available(1.2)
     public func summonDemons()
 
-    @available(1.0) @inlineable(1.2)
+    @available(1.0) @inlinable(1.2)
     public func summonElves()
 
 Using the same attribute for both publishing and using versioned APIs helps tie
@@ -239,7 +241,7 @@
     public func summonDemons()
 
     #version(1.0) {}
-    #version(1.2) { @inlineable }
+    #version(1.2) { @inlinable }
     public func summonElves()
 
 Since there are potentially many annotations on a declaration that need
@@ -254,7 +256,7 @@
 
     public(1.2) func summonDemons()
 
-    /* @inlineable ?? */
+    /* @inlinable ?? */
     public(1.0) func summonElves()
 
 Putting the version on the public modifier is the most concise option. However,
@@ -307,8 +309,8 @@
   is safe when a client deploys against older versions of the library.
 
 
-Inlineable Functions
---------------------
+Inlinable Functions
+-------------------
 
 Functions are a very common example of resilience: the function's declaration
 is published as API, but its body may change between library versions as long
@@ -326,62 +328,44 @@
   allows the library author to preserve invariants while still allowing
   efficient access to the struct.
 
-- The function is used to determine which version of the library a client was
-  compiled against.
+- The function is generic and its performance may be greatly increased by
+  specialization in the client.
 
-- The library author does not want to make the function part of their binary
-  interface, allowing for source-compatible changes 
-
-A versioned function marked with the ``@inlineable`` attribute makes its body
-available to clients as part of the module's public interface. ``@inlineable``
+A versioned function marked with the ``@inlinable`` attribute makes its body
+available to clients as part of the module's public interface. ``@inlinable``
 is a `versioned attribute`; clients may not assume that the body of the
-function is suitable when deploying against older versions of the library. If a
-function has been inlineable since it was introduced, it is not considered part
-of the library's binary interface.
+function is suitable when deploying against older versions of the library.
 
-Clients are not required to inline a function marked ``@inlineable``. However,
-if a function has been inlineable since the minimum required version of the
-library, any use of that function must copy its implementation into the client
-module.
+Clients are not required to inline a function marked ``@inlinable``.
 
 .. note::
 
-    It is legal to change the implementation of an inlineable function in the
+    It is legal to change the implementation of an inlinable function in the
     next release of the library. However, any such change must be made with the
     understanding that it will not affect existing clients. This is the
     standard example of a `binary-compatible source-breaking change`.
 
-Any local functions or closures within an inlineable function are themselves
-treated as ``@inlineable``. This is important in case it is necessary to change
-the inlineable function later; existing clients should not be depending on
-internal details of the previous implementation.
+Any local functions or closures within an inlinable function are themselves
+treated as ``@inlinable``, and a client that inlines the containing function
+must emit its own copy of the local functions or closures. This is important in
+case it is necessary to change the inlinable function later; existing clients
+should not be depending on internal details of the previous implementation.
 
-It is a `binary-compatible source-breaking change` to completely remove a
-public entity marked ``@inlineable`` from a library if and only if it has been
-inlineable since it was introduced. If not, it is considered a part of the
-library's binary interface and may not be removed.
-
-(Non-public, non-versioned entities may always be removed from a library; they
-are not part of its API or ABI.)
-
-.. note::
-
-    Removing ``@inlineable`` from a public entity without updating its
-    availability information is not permitted. Instead, add a second,
-    non-inlineable function that provides the implementation of the
-    ``@inlineable`` entity, and call through to that function when a new enough
-    version of the library is available.
+Removing the ``@inlinable`` attribute completely---say, to reference private
+implementation details that should not be `versioned <versioned entity>`---is a
+safe change. However, existing clients will of course not be affected by this
+change, and any future use of the function must take this into account.
 
 Although they are not a supported feature for arbitrary libraries at this time,
-`transparent`_ functions are implicitly marked ``@inlineable``.
+`transparent`_ functions are implicitly marked ``@inlinable``.
 
 .. _transparent: https://github.com/apple/swift/blob/master/docs/TransparentAttr.rst
 
 
-Restrictions on Inlineable Functions
-------------------------------------
+Restrictions on Inlinable Functions
+-----------------------------------
 
-Because the body of an inlineable function (or method, accessor, initializer,
+Because the body of an inlinable function (or method, accessor, initializer,
 or deinitializer) will be inlined into another module, it must not make any
 assumptions that rely on knowledge of the current module. Here is a trivial
 example using methods::
@@ -392,7 +376,7 @@
     }
 
     extension Point2D {
-      @inlineable public func distance(to other: Point2D) -> Double {
+      @inlinable public func distance(to other: Point2D) -> Double {
         let deltaX = self.x - other.x
         let deltaY = self.y - other.y
         return sqrt(deltaX*deltaX + deltaY*deltaY)
@@ -409,40 +393,39 @@
     }
 
 and the ``x`` and ``y`` properties have now disappeared. To avoid this, the
-bodies of inlineable functions have the following restrictions:
+bodies of inlinable functions have the following restrictions:
 
 - They may not define any local types (other than typealiases).
 
-- They must not reference any ``private`` or ``fileprivate`` entities, except
-  for other declarations marked ``@inlineable``.
+- They must not reference any ``private`` or ``fileprivate`` entities.
 
 - They must not reference any ``internal`` entities except for those that have
-  been `versioned`_ and those declared ``@inlineable``. See below for a
-  discussion of versioning internal API.
-
-- In addition, no non-public, non-versioned stored constants or variables may
-  be referenced even if they are declared ``@inlineable``. (This is because
-  their storage is still considered part of the defining library.)
+  been ``versioned <versioned entity>` and those declared ``@inlinable``. See
+  below for a discussion of versioning internal API.
 
 - They must not reference any entities from the current module introduced
-  after the function was made inlineable, except under appropriate availability
+  after the function was made inlinable, except under appropriate availability
   guards.
 
-.. _versioned: #versioning-internal-api
-
 
 Default Argument Expressions
 ----------------------------
 
-Default argument expressions are implemented as ``@inlineable`` functions and
-thus are subject to the same restrictions as inlineable functions. A default
-argument implicitly has the same availability as the function it is attached to.
+Default argument expressions for functions that are public, versioned, or
+inlinable are implemented very similar to inlinable functions and thus are
+subject to similar restrictions:
 
-.. note::
+- They may not define any local types (other than typealiases).
 
-    Swift 4.0's implementation of default arguments puts the evaluation of the
-    default argument expression in the library, rather than in the client like
-    C++ or C#. We plan to change this.
+- They must not reference any non-``public`` entities.
+
+- They must not reference any entities from the current module introduced
+  after the function was made inlinable, except under appropriate availability
+  guards.
+
+A default argument implicitly has the same availability as the function it is
+attached to. Because default argument expressions can be added and removed, a
+client that uses one must always emit its own copy of the implementation.
 
 
 Top-Level Variables and Constants
@@ -491,8 +474,9 @@
 Giving Up Flexibility
 ---------------------
 
-Both top-level constants and variables can be marked ``@inlineable`` to allow
-clients to access them more efficiently. This restricts changes a fair amount:
+Both top-level constants and variables can be marked ``@inlinableAccess`` to
+allow clients to access them more efficiently. This restricts changes a fair
+amount:
 
 - Adding a versioned setter to a computed variable is still permitted.
 - Adding or removing a non-public, non-versioned setter is still permitted.
@@ -513,22 +497,15 @@
 .. admonition:: TODO
 
     It Would Be Nice(tm) to allow marking the *getter* of a top-level variable
-    inlineable while still allowing the setter to change. This would need
+    inlinable while still allowing the setter to change. This would need
     syntax, though.
 
-Any inlineable accessors must follow the rules for `inlineable functions`_, as
+Any inlinable accessors must follow the rules for `inlinable functions`_, as
 described above.
 
-Unlike functions, inlineable stored constants and variables (including those
-with accessors) may not be removed even if they have been inlineable since they
-were first introduced, because the storage for these bindings is still part of
-the library in which they were defined. Removing computed variables that have
-been inlineable since their introduction is a `binary-compatible
-source-breaking change`.
-
 Note that if a constant's initial value expression has any observable side
 effects, including the allocation of class instances, it must not be treated
-as inlineable. A constant must always behave as if it is initialized exactly
+as inlinable. A constant must always behave as if it is initialized exactly
 once.
 
 .. admonition:: TODO
@@ -536,6 +513,13 @@
     Is this a condition we can detect at compile-time? Do we have to be
     restricted to things that can be lowered to compile-time constants?
 
+.. admonition:: TODO
+
+    ``@inlinableAccess`` isn't implemented yet, but for computed properties we
+    already allow putting ``@inlinable`` on the accessors individually. That
+    doesn't support all the use cases, like promising that a stored property
+    will remain stored, but it also provides flexibility in only making *one*
+    accessor inlinable. Is that important?
 
 Structs
 ~~~~~~~
@@ -568,10 +552,11 @@
 
 For the most part struct methods and initializers are treated exactly like
 top-level functions. They permit all of the same modifications and can also be
-marked ``@inlineable``, with the same restrictions. Inlineable initializers
-must always delegate to another initializer, since new properties may be added
-between new releases. For the same reason, initializers declared outside of the
-struct's module must always delegate to another initializer.
+marked ``@inlinable``, with the same restrictions. Inlinable initializers must
+always delegate to another initializer or assign an entire value to ``self``,
+since new properties may be added between new releases. For the same reason,
+initializers declared outside of the struct's module must always delegate to
+another initializer or assign to ``self``.
 
 
 Properties
@@ -581,8 +566,8 @@
 all of the same modifications, and also allow adding or removing an initial
 value entirely.
 
-Struct properties can also be marked ``@inlineable``, with the same
-restrictions as for top-level bindings. An inlineable stored property may not
+Struct properties can also be marked ``@inlinableAccess``, with the same
+restrictions as for top-level bindings. An inlinable stored property may not
 become computed, but the offset of its storage within the struct is not
 necessarily fixed.
 
@@ -607,9 +592,9 @@
 - Changing or removing a default argument is a `binary-compatible
   source-breaking change`.
 
-Like properties, subscripts can be marked ``@inlineable``, which makes changing
-the body of an accessor a `binary-compatible source-breaking change`. Any
-inlineable accessors must follow the rules for `inlineable functions`_, as
+Like properties, subscripts can be marked ``@inlinableAccess``, which makes
+changing the body of an accessor a `binary-compatible source-breaking change`.
+Any inlinable accessors must follow the rules for `inlinable functions`_, as
 described above.
 
 
@@ -660,7 +645,7 @@
 This promises that no stored properties will be added to or removed from the
 struct, even non-public ones. Additionally, all versioned instance stored
 properties in a ``@fixedContents`` struct are implicitly declared
-``@inlineable`` (as described above for top-level variables). In effect:
+``@inlinable`` (as described above for top-level variables). In effect:
 
 - Reordering stored instance properties (public or non-public) is not permitted.
   Reordering all other members is still permitted.
@@ -700,8 +685,8 @@
 - A versioned ``internal`` property may be made ``public`` (without changing
   its version).
 
-An initializer of a fixed-contents struct may be declared ``@inlineable`` even
-if it does not delegate to another initializer, as long as the ``@inlineable``
+An initializer of a fixed-contents struct may be declared ``@inlinable`` even
+if it does not delegate to another initializer, as long as the ``@inlinable``
 attribute, or the initializer itself, is not introduced earlier than the
 ``@fixedContents`` attribute and the struct has no non-versioned stored
 properties.
@@ -714,7 +699,8 @@
 
     We can add a *different* feature to control layout some day, or something
     equivalent, but this feature should not restrict Swift from doing useful
-    things like minimizing member padding.
+    things like minimizing member padding. At the very least, Swift structs
+    don't guarantee the same tail padding that C structs do.
 
 .. note::
 
@@ -781,9 +767,7 @@
 
 For the most part enum initializers are treated exactly like top-level
 functions. They permit all of the same modifications and can also be marked
-``@inlineable``, with the same restrictions. Unlike struct initializers, enum
-initializers do not always need to delegate to another initializer, even if
-they are inlineable or declared in a separate module.
+``@inlinable``, with the same restrictions.
 
 
 Methods and Subscripts
@@ -793,11 +777,11 @@
 members.
 
 
-Closed Enums
+Frozen Enums
 ------------
 
 A library owner may opt out of this flexibility by marking a versioned enum as
-``@closed``. A "closed" enum may not have any cases with less access than the
+``@frozen``. A "frozen" enum may not have any cases with less access than the
 enum itself, and may not add new cases in the future. This guarantees to
 clients that the enum cases are exhaustive. In particular:
 
@@ -813,19 +797,19 @@
 
 .. note::
 
-    Were a public "closed" enum allowed to have non-public cases, clients of
+    Were a public "frozen" enum allowed to have non-public cases, clients of
     the library would still have to treat the enum as opaque and would still
     have to be able to handle unknown cases in their ``switch`` statements.
 
-``@closed`` is a `versioned attribute`. This is so that clients can deploy
+``@frozen`` is a `versioned attribute`. This is so that clients can deploy
 against older versions of the library, which may have non-public cases in the
-enum. (In this case the client must manipulate the enum as if the ``@closed``
+enum. (In this case the client must manipulate the enum as if the ``@frozen``
 attribute were absent.) All cases that are not versioned become implicitly
 versioned with this number.
 
-Even for default "open" enums, adding new cases should not be done lightly. Any
-clients attempting to do an exhaustive switch over all enum cases will likely
-not handle new cases well.
+Even for default "non-frozen" enums, adding new cases should not be done
+lightly. Any clients attempting to do an exhaustive switch over all enum cases
+will likely not handle new cases well.
 
 .. note::
 
@@ -843,10 +827,9 @@
 
 - A new non-type requirement may be added to a protocol, as long as it has an
   unconstrained default implementation.
-- A new associated type may be added to a protocol, as long as it has a default.
-  As with any other declarations, newly-added associated types must be marked
-  with ``@available`` specifying when they were introduced.
 - A default may be added to an associated type.
+- Removing a default from an associated type is a `binary-compatible
+  source-breaking change`.
 - A new optional requirement may be added to an ``@objc`` protocol.
 - All members may be reordered, including associated types.
 - Changing *internal* parameter names of function and subscript requirements
@@ -859,10 +842,12 @@
 
 All other changes to the protocol itself are forbidden, including:
 
+- Adding a new associated type.
+- Removing any existing requirements (type or non-type).
 - Making an existing requirement optional.
 - Making a non-``@objc`` protocol ``@objc`` or vice versa.
-- Adding or removing constraints from an associated type.
-- Removing a default from an associated type.
+- Adding or removing constraints from an associated type, including inherited
+  associated types.
 
 Protocol extensions may be more freely modified; `see below`__.
 
@@ -870,16 +855,14 @@
 
 .. note::
 
-    Allowing the addition of associated types means implementing some form of
-    "generalized existentials", so that existing existential values (values
-    with protocol type) continue to work even if a protocol gets its first
-    associated type. Until we have that feature implemented, it would only be
-    safe to add an associated type to a protocol that already has associated
-    types, or uses ``Self`` in a non-return position (i.e. one that currently
-    cannot be used as the type of a value).
+    A protocol's associated types are used in computing the "generic signature"
+    that uniquely identifies a generic function. Adding an associated type
+    could perturb the generic signature and thus change the identity of a
+    function, breaking binary compatibility.
     
-    As a first pass, it is likely that we will not allow adding new associated
-    types to existing protocols at all.
+    It may be possible to allow adding associated types as long as they have
+    proper availability annotations, but this is not in scope for the initial
+    version of Swift ABI stability.
 
 
 Classes
@@ -926,7 +909,7 @@
   automatically use the superclass implementation.
 - Within an ``open`` class, any public method, subscript, or property may be
   marked ``open`` if it is not already marked ``final``.
-- Any public method, subscript, or property may be marked ``final`` if it is not
+- Any method, subscript, or property may be marked ``final`` if it is not
   already marked ``open``.
 - ``@IBOutlet``, ``@IBAction``, ``@IBInspectable``, and ``@GKInspectable`` may
   be added to a member without providing any extra version information.
@@ -976,9 +959,9 @@
 
 .. admonition:: TODO
 
-    The ``@NSManaged`` attribute as it is in Swift 4 exposes implementation
-    details to clients in a bad way. We need to fix this.
-    rdar://problem/20829214
+    ``@NSManaged`` as it is in Swift 4.2 exposes implementation details to
+    clients in a bad way. If we want to use ``@NSManaged`` in frameworks with
+    binary compatibility concerns, we need to fix this. rdar://problem/20829214
 
 
 Initializers
@@ -993,8 +976,14 @@
 convenience initializer; that initializer may only call existing ``required``
 initializers. An existing initializer may not be marked ``required``.
 
+.. admonition:: TODO
+
+    This implies a different rule for inheriting ``required`` convenience
+    initializers than non-required convenience initializers, which is not
+    currently implemented.
+
 All of the modifications permitted for top-level functions are also permitted
-for class initializers. Convenience initializers may be marked ``@inlineable``,
+for class initializers. Convenience initializers may be marked ``@inlinable``,
 with the same restrictions as top-level functions; designated initializers may
 not.
 
@@ -1016,19 +1005,16 @@
 - The ``@discardableResult`` and ``@warn_unqualified_access`` attributes may
   be added to a method without any additional versioning information.
 
-Class and instance methods may be marked ``@inlineable``, with the same
+Class and instance methods may be marked ``@inlinable``, with the same
 restrictions as struct methods. Additionally, only non-overriding ``final``
-methods may be marked ``@inlineable``.
+methods may be marked ``@inlinable``.
 
 .. note::
 
     A previous draft of this document allowed non-``final`` methods to be
-    marked ``@inlineable``, permitting inlining based on speculative
-    devirtualization. This was removed both because of the added complexity for
-    users and because it would make methods on classes different from
-    struct/enum methods and top-level functions: a method on a class would be
-    part of the library's module interface even if it had been inlineable since
-    its introduction.
+    marked ``@inlinable``, permitting inlining based on speculative
+    devirtualization. This was removed because of the added complexity for
+    users.
 
 
 Properties
@@ -1059,7 +1045,7 @@
 value, as well as adding or removing an initial value entirely.
 
 Non-overriding ``final`` variable and constant properties (on both instances
-and classes) may be marked ``@inlineable``. This behaves as described for
+and classes) may be marked ``@inlinableAccess``. This behaves as described for
 struct properties.
 
 
@@ -1084,8 +1070,8 @@
 `binary-compatible source-breaking change`; any existing overrides will not
 know what to do with the setter and will likely not behave correctly.
 
-Non-overriding ``final`` class subscripts may be marked ``@inlineable``, which
-behaves as described for struct subscripts.
+Non-overriding ``final`` class subscripts may be marked ``@inlinableAccess``,
+which behaves as described for struct subscripts.
 
 
 Possible Restrictions on Classes
@@ -1144,19 +1130,19 @@
     overridable, even when the conforming type is a class.
 
 
-Operators
-~~~~~~~~~
+Operators and Precedence Groups
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Operator declarations are entirely compile-time constructs, so changing them
-does not have any affect on binary compatibility. However, they do affect
-*source* compatibility, so it is recommended that existing operators are not
-changed at all except for the following:
+Operator and precedence group declarations are entirely compile-time
+constructs, so changing them does not have any affect on binary compatibility.
+However, they do affect *source* compatibility, so it is recommended that
+existing operators are not changed at all except for the following:
 
-- Making a non-associative operator left- or right-associative.
+- Making a non-associative precedence group left- or right-associative.
 
 Any other change counts as a `binary-compatible source-breaking change`.
 
-Operator declarations are not versioned.
+Operator and precedence group declarations are not versioned.
 
 
 Typealiases
@@ -1176,14 +1162,15 @@
 It is always permitted to change the *use* of a public typealias to its
 underlying type, and vice versa, at any location in the program.
 
-Neither top-level nor member typealiases are versioned.
+Typealiases are `versioned <versioned entity>` despite being compile-time
+constructs in order to verify the availability of their underlying types.
 
 
 A Unifying Theme
 ~~~~~~~~~~~~~~~~
 
 So far this document has talked about ways to give up flexibility for several
-different kinds of declarations: ``@inlineable`` for functions,
+different kinds of declarations: ``@inlinable`` for functions,
 ``@fixedContents`` for structs, etc. Each of these has a different set of
 constraints it enforces on the library author and promises it makes to clients.
 However, they all follow a common theme of giving up the flexibility of future
@@ -1202,13 +1189,13 @@
 
 The initial discussion on versioning focused on public APIs, making sure
 that a client knows what features they can use when a specific version of a
-library is present. Inlineable functions have much the same constraints, except
-the inlineable function is the client and the entities being used may not be
+library is present. Inlinable functions have much the same constraints, except
+the inlinable function is the client and the entities being used may not be
 public.
 
 Adding a versioning annotation to an ``internal`` entity promises that the
 entity will be available at link time in the containing module's binary. This
-makes it safe to refer to such an entity from an inlineable function. If the
+makes it safe to refer to such an entity from an inlinable function. If the
 entity is ever made ``public`` or ``open``, its availability should not be
 changed; not only is it safe for new clients to rely on it, but *existing*
 clients require its presence as well.
@@ -1219,6 +1206,10 @@
     imply everything that ``public`` does, such as requiring overrides to be
     ``public``.
 
+In libraries without binary compatibility concerns, the equivalent annotation
+is ``@usableFromInline``, since inlinable functions are the only way that a
+non-public entity can be referenced from outside of a module.
+
 Because a versioned class member may eventually be made ``open``, it must be
 assumed that new overrides may eventually appear from outside the module if the
 class is marked ``open`` unless the member is marked ``final``.
@@ -1240,9 +1231,9 @@
     as ``internal`` entities. However, this is a purely additive feature, so to
     keep things simple we'll stick with the basics.
 
-We could do away with the entire feature if we restricted inlineable functions
+We could do away with the entire feature if we restricted inlinable functions
 and fixed-contents structs to only refer to public entities. However, this
-removes one of the primary reasons to make something inlineable: to allow
+removes one of the primary reasons to make something inlinable: to allow
 efficient access to a type while still protecting its invariants.
 
 
@@ -1275,6 +1266,12 @@
     above this may affect how those existing clients use the entities declared
     in the library.
 
+The one exception is ``@inlinable``, which does not change how a function is
+called or otherwise used at the ABI level. If the implementation being provided
+is compatible with a previous version of a library, and the function was
+present and public (or `versioned <versioned entity>`) there, then the library
+author may choose to backdate the ``@inlinable`` annotation.
+
 
 Optimization
 ============
@@ -1315,31 +1312,31 @@
 information (and performance assertions) introduced prior to version 1.5.
 
 
-Inlineable Code
-~~~~~~~~~~~~~~~
+Inlinable Code
+~~~~~~~~~~~~~~
 
 By default, the availability context for a library always includes the latest
 version of the library itself, since that code is always distributed as a unit.
-However, this is not true for functions that have been marked inlineable (see
-`Inlineable Functions`_ above). Inlineable code must be treated as if it is
+However, this is not true for functions that have been marked inlinable (see
+`Inlinable Functions`_ above). Inlinable code must be treated as if it is
 outside the current module, since once it's inlined it will be.
 
-For inlineable code, the availability context is exactly the same as the
-equivalent non-inlineable code except that the assumed version of the
-containing library is the version attached to the ``@inlineable`` attribute, or
+For inlinable code, the availability context is exactly the same as the
+equivalent non-inlinable code except that the assumed version of the
+containing library is the version attached to the ``@inlinable`` attribute, or
 the version of the library in which the entity was introduced, and any `library
 version dependencies <#declaring-library-version-dependencies>`_ or minimum
 deployment target must be specified explicitly using ``@available``. Code
 within this context must be treated as if the containing library were just a
 normal dependency.
 
-A versioned inlineable function still has an exported symbol in the library
+A versioned inlinable function still has an exported symbol in the library
 binary, which may be used when the function is referenced from a client rather
 than called. This version of the function is not subject to the same
 restrictions as the version that may be inlined, and so it may be desirable to
 compile a function twice: once for inlining, once for maximum performance.
 
-If the body of an inlineable function is used in any way by a client module
+If the body of an inlinable function is used in any way by a client module
 (say, to determine that it does not read any global variables), that module
 must take care to emit and use its own copy of the function. This is because
 analysis of the function body may not apply to the version of the function
@@ -1391,7 +1388,8 @@
     ``maximumFootprint``, and the latter is more flexible.
 
 .. note:: None of these names / spellings are final. The name "trivial" comes
-    from C++, though Swift's trivial is closer to C++'s "`trivially copyable`__".
+    from C++, though Swift's trivial is closer to C++'s "`trivially
+    copyable`__".
 
 All of these features need to be versioned, just like the more semantic
 fragility attributes above. The exact spelling is not proposed by this document.
@@ -1406,7 +1404,7 @@
 in this document do not apply to libraries distributed in a bundle with their
 clients. In this case, a client can rely on all the current implementation
 details of its libraries when compiling, since the same version of the library
-is guaranteed to be present at runtime. This allows more optimization than
+is guaranteed to be present at run time. This allows more optimization than
 would otherwise be possible.
 
 In some cases, a collection of libraries may be built and delivered together,
@@ -1423,7 +1421,7 @@
 and indeed they are an additive feature. One possibility is that a library's
 resilience domain defaults to the name of the module, but can be overridden. If
 a client has the same resilience domain name as a library it is using, it may
-assume that version of the library will be present at runtime.
+assume that version of the library will be present at run time.
 
 
 Deployments
@@ -1630,20 +1628,17 @@
 
 - (draft) `Overridable methods in extensions`_
 - (planned) Restricting retroactive modeling (protocol conformances for types you don't own)
-- (planned) Default implementations in protocols
 - (planned) `Generalized existentials (values of protocol type) <Generics>`_
-- (planned) Open and closed enums
+- (planned) Frozen enums (building on `SE-0192 <SE0192>`_)
 - (planned) Removing the "constant" guarantee for 'let' across module boundaries
-- (planned) Syntax for declaring "versioned" entities and their features
-- (planned) Syntax for declaring inlineable code
 - (planned) Syntax for declaring fixed-contents structs
-- (?) Non-inherited protocol conformances
 - (future) Performance annotations for types
 - (future) Attributes for stored property accessors
 - (future) Stored properties in extensions
 
 .. _Overridable methods in extensions: https://github.com/jrose-apple/swift-evolution/blob/overridable-members-in-extensions/proposals/nnnn-overridable-members-in-extensions.md
 .. _Generics: https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generalized-existentials
+.. _SE0192: https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
 
 This does not mean all of these proposals need to be accepted, only that their
 acceptance or rejection will affect this document.
@@ -1655,7 +1650,7 @@
 .. glossary::
 
   ABI
-    The runtime contract for using a particular API (or for an entire library),
+    The run-time contract for using a particular API (or for an entire library),
     including things like symbol names, calling conventions, and type layout
     information. Stands for "Application Binary Interface".
 
@@ -1702,7 +1697,7 @@
 
   entity
     A type, function, member, or global in a Swift program. Occasionally the
-    term "entities" also includes conformances, since these have a runtime
+    term "entities" also includes conformances, since these have a run-time
     presence and are depended on by clients.
 
   forwards-compatible
diff --git a/include/swift/AST/ProtocolConformance.h b/include/swift/AST/ProtocolConformance.h
index f61662d..14e0827 100644
--- a/include/swift/AST/ProtocolConformance.h
+++ b/include/swift/AST/ProtocolConformance.h
@@ -316,6 +316,11 @@
   /// Substitute the conforming type and produce a ProtocolConformance that
   /// applies to the substituted type.
   ProtocolConformance *subst(Type substType,
+                             SubstitutionMap subMap) const;
+
+  /// Substitute the conforming type and produce a ProtocolConformance that
+  /// applies to the substituted type.
+  ProtocolConformance *subst(Type substType,
                              TypeSubstitutionFn subs,
                              LookupConformanceFn conformances) const;
 
diff --git a/include/swift/AST/ProtocolConformanceRef.h b/include/swift/AST/ProtocolConformanceRef.h
index 6237f6d5..716ce48 100644
--- a/include/swift/AST/ProtocolConformanceRef.h
+++ b/include/swift/AST/ProtocolConformanceRef.h
@@ -47,9 +47,8 @@
   using UnionType = llvm::PointerUnion<ProtocolDecl*, ProtocolConformance*>;
   UnionType Union;
 
-  explicit ProtocolConformanceRef(UnionType value) : Union(value) {
-    assert(value && "cannot construct ProtocolConformanceRef with null");
-  }
+  explicit ProtocolConformanceRef(UnionType value) : Union(value) {}
+
 public:
   /// Create an abstract protocol conformance reference.
   explicit ProtocolConformanceRef(ProtocolDecl *proto) : Union(proto) {
@@ -63,17 +62,30 @@
            "cannot construct ProtocolConformanceRef with null");
   }
 
+  static ProtocolConformanceRef forInvalid() {
+    return ProtocolConformanceRef(UnionType((ProtocolDecl *)nullptr));
+  }
+
+  bool isInvalid() const {
+    return !Union;
+  }
+
   /// Create either a concrete or an abstract protocol conformance reference,
   /// depending on whether ProtocolConformance is null.
   explicit ProtocolConformanceRef(ProtocolDecl *protocol,
                                   ProtocolConformance *conf);
 
-  bool isConcrete() const { return Union.is<ProtocolConformance*>(); }
+  bool isConcrete() const {
+    return !isInvalid() && Union.is<ProtocolConformance*>();
+  }
   ProtocolConformance *getConcrete() const {
     return Union.get<ProtocolConformance*>();
   }
 
-  bool isAbstract() const { return Union.is<ProtocolDecl*>(); }
+  bool isAbstract() const {
+    return !isInvalid() && Union.is<ProtocolDecl*>();
+  }
+
   ProtocolDecl *getAbstract() const {
     return Union.get<ProtocolDecl*>();
   }
@@ -89,6 +101,10 @@
   
   /// Apply a substitution to the conforming type.
   ProtocolConformanceRef subst(Type origType,
+                               SubstitutionMap subMap) const;
+
+  /// Apply a substitution to the conforming type.
+  ProtocolConformanceRef subst(Type origType,
                                TypeSubstitutionFn subs,
                                LookupConformanceFn conformances) const;
 
diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h
index dca4f8e..fe46e4e 100644
--- a/include/swift/SIL/TypeSubstCloner.h
+++ b/include/swift/SIL/TypeSubstCloner.h
@@ -172,9 +172,7 @@
 
   ProtocolConformanceRef remapConformance(Type type,
                                           ProtocolConformanceRef conf) {
-    return conf.subst(type,
-                      QuerySubstitutionMap{SubsMap},
-                      LookUpConformanceInSubstitutionMap(SubsMap));
+    return conf.subst(type, SubsMap);
   }
 
   SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
diff --git a/include/swift/SILOptimizer/PassManager/PassManager.h b/include/swift/SILOptimizer/PassManager/PassManager.h
index 1833612..efd6c57 100644
--- a/include/swift/SILOptimizer/PassManager/PassManager.h
+++ b/include/swift/SILOptimizer/PassManager/PassManager.h
@@ -48,7 +48,7 @@
   llvm::SmallVector<SILTransform *, 16> Transformations;
 
   /// A list of registered analysis.
-  llvm::SmallVector<SILAnalysis *, 16> Analysis;
+  llvm::SmallVector<SILAnalysis *, 16> Analyses;
 
   /// An entry in the FunctionWorkList.
   struct WorklistEntry {
@@ -122,7 +122,7 @@
   /// analysis. If the analysis is not found, the program terminates.
   template<typename T>
   T *getAnalysis() {
-    for (SILAnalysis *A : Analysis)
+    for (SILAnalysis *A : Analyses)
       if (auto *R = llvm::dyn_cast<T>(A))
         return R;
 
@@ -145,7 +145,7 @@
   /// \brief Iterate over all analysis and invalidate them.
   void invalidateAllAnalysis() {
     // Invalidate the analysis (unless they are locked)
-    for (auto AP : Analysis)
+    for (auto AP : Analyses)
       if (!AP->isLocked())
         AP->invalidate();
 
@@ -170,7 +170,7 @@
   /// is the job of the analysis to make sure no extra work is done if the
   /// particular analysis has been done on the function.
   void notifyAnalysisOfFunction(SILFunction *F) {
-    for (auto AP : Analysis) {
+    for (auto AP : Analyses) {
       AP->notifyAddedOrModifiedFunction(F);
     }
   }
@@ -179,7 +179,7 @@
   void invalidateAnalysis(SILFunction *F,
                           SILAnalysis::InvalidationKind K) {
     // Invalidate the analysis (unless they are locked)
-    for (auto AP : Analysis)
+    for (auto AP : Analyses)
       if (!AP->isLocked())
         AP->invalidate(F, K);
     
@@ -192,7 +192,7 @@
   /// or vtables.
   void invalidateFunctionTables() {
     // Invalidate the analysis (unless they are locked)
-    for (auto AP : Analysis)
+    for (auto AP : Analyses)
       if (!AP->isLocked())
         AP->invalidateFunctionTables();
 
@@ -205,7 +205,7 @@
   /// \brief Iterate over all analysis and notify them of a deleted function.
   void notifyDeleteFunction(SILFunction *F) {
     // Invalidate the analysis (unless they are locked)
-    for (auto AP : Analysis)
+    for (auto AP : Analyses)
       if (!AP->isLocked())
         AP->notifyWillDeleteFunction(F);
 
@@ -233,7 +233,7 @@
 
   /// Verify all analyses.
   void verifyAnalyses() const {
-    for (auto *A : Analysis) {
+    for (auto *A : Analyses) {
       A->verify();
     }
   }
@@ -245,7 +245,7 @@
   /// this. If no override is provided the SILAnalysis should just call the
   /// normal verify method.
   void verifyAnalyses(SILFunction *F) const {
-    for (auto *A : Analysis) {
+    for (auto *A : Analyses) {
       A->verify(F);
     }
   }
diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def
index efe47c4..05a2782 100644
--- a/include/swift/Serialization/DeclTypeRecordNodes.def
+++ b/include/swift/Serialization/DeclTypeRecordNodes.def
@@ -87,7 +87,6 @@
 TRAILING_INFO(TUPLE_TYPE_ELT)
 TYPE(FUNCTION)
 TYPE(METATYPE)
-TYPE(LVALUE_unused)
 TYPE(INOUT)
 TYPE(ARCHETYPE)
 TYPE(PROTOCOL_COMPOSITION)
@@ -144,42 +143,44 @@
 PATTERN(TYPED)
 PATTERN(VAR)
 
-OTHER(PARAMETERLIST, 226)
-OTHER(PARAMETERLIST_ELT, 227)
-OTHER(FOREIGN_ERROR_CONVENTION, 228)
-OTHER(DECL_CONTEXT, 229)
-OTHER(XREF_TYPE_PATH_PIECE, 230)
-OTHER(XREF_VALUE_PATH_PIECE, 231)
-OTHER(XREF_EXTENSION_PATH_PIECE, 232)
-OTHER(XREF_OPERATOR_OR_ACCESSOR_PATH_PIECE, 233)
-OTHER(XREF_GENERIC_PARAM_PATH_PIECE, 234)
-OTHER(XREF_INITIALIZER_PATH_PIECE, 235)
+OTHER(PARAMETERLIST, 210)
+OTHER(PARAMETERLIST_ELT, 211)
+OTHER(FOREIGN_ERROR_CONVENTION, 212)
+OTHER(DECL_CONTEXT, 213)
+OTHER(XREF_TYPE_PATH_PIECE, 214)
+OTHER(XREF_VALUE_PATH_PIECE, 215)
+OTHER(XREF_EXTENSION_PATH_PIECE, 216)
+OTHER(XREF_OPERATOR_OR_ACCESSOR_PATH_PIECE, 217)
+OTHER(XREF_GENERIC_PARAM_PATH_PIECE, 218)
+OTHER(XREF_INITIALIZER_PATH_PIECE, 219)
 
-OTHER(ABSTRACT_CLOSURE_EXPR_CONTEXT, 236)
-OTHER(PATTERN_BINDING_INITIALIZER_CONTEXT, 237)
-OTHER(DEFAULT_ARGUMENT_INITIALIZER_CONTEXT, 238)
-OTHER(TOP_LEVEL_CODE_DECL_CONTEXT, 239)
+OTHER(ABSTRACT_CLOSURE_EXPR_CONTEXT, 220)
+OTHER(PATTERN_BINDING_INITIALIZER_CONTEXT, 221)
+OTHER(DEFAULT_ARGUMENT_INITIALIZER_CONTEXT, 222)
+OTHER(TOP_LEVEL_CODE_DECL_CONTEXT, 223)
 
-OTHER(GENERIC_PARAM_LIST, 240)
+OTHER(GENERIC_PARAM_LIST, 230)
 TRAILING_INFO(GENERIC_PARAM)
 TRAILING_INFO(GENERIC_REQUIREMENT)
 TRAILING_INFO(LAYOUT_REQUIREMENT)
-OTHER(GENERIC_SIGNATURE, 244)
-OTHER(SIL_GENERIC_ENVIRONMENT, 245)
-OTHER(SUBSTITUTION_MAP, 246)
+OTHER(GENERIC_SIGNATURE, 234)
+OTHER(SIL_GENERIC_ENVIRONMENT, 235)
+OTHER(SUBSTITUTION_MAP, 236)
 
-OTHER(LOCAL_DISCRIMINATOR, 248)
-OTHER(PRIVATE_DISCRIMINATOR, 249)
+OTHER(LOCAL_DISCRIMINATOR, 237)
+OTHER(PRIVATE_DISCRIMINATOR, 238)
 
-OTHER(ABSTRACT_PROTOCOL_CONFORMANCE, 250)
-OTHER(NORMAL_PROTOCOL_CONFORMANCE, 251)
-OTHER(SPECIALIZED_PROTOCOL_CONFORMANCE, 252)
-OTHER(INHERITED_PROTOCOL_CONFORMANCE, 253)
-OTHER(SIL_LAYOUT, 197) // FIXME: Note out-of-order
-OTHER(NORMAL_PROTOCOL_CONFORMANCE_ID, 198) // FIXME: Note out-of-order
-OTHER(PROTOCOL_CONFORMANCE_XREF, 199) // FIXME: Note out-of-order
-OTHER(MEMBERS, 254)
-OTHER(XREF, 255)
+OTHER(ABSTRACT_PROTOCOL_CONFORMANCE, 240)
+OTHER(NORMAL_PROTOCOL_CONFORMANCE, 241)
+OTHER(SPECIALIZED_PROTOCOL_CONFORMANCE, 242)
+OTHER(INHERITED_PROTOCOL_CONFORMANCE, 243)
+OTHER(INVALID_PROTOCOL_CONFORMANCE, 244)
+
+OTHER(SIL_LAYOUT, 245)
+OTHER(NORMAL_PROTOCOL_CONFORMANCE_ID, 246)
+OTHER(PROTOCOL_CONFORMANCE_XREF, 247)
+OTHER(MEMBERS, 248)
+OTHER(XREF, 249)
 
 #undef RECORD
 #undef DECLTYPERECORDNODES_HAS_RECORD_VAL
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 4b29be7..42534cb 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -55,7 +55,7 @@
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
 /// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t VERSION_MINOR = 426; // SIL key path external components with local attempts
+const uint16_t VERSION_MINOR = 427; // Invalid conformances
 
 using DeclIDField = BCFixed<31>;
 
@@ -1287,6 +1287,11 @@
     DeclIDField // the protocol
   >;
 
+  /// A placeholder for an invalid conformance.
+  using InvalidProtocolConformanceLayout = BCRecordLayout<
+    INVALID_PROTOCOL_CONFORMANCE
+  >;
+
   using NormalProtocolConformanceLayout = BCRecordLayout<
     NORMAL_PROTOCOL_CONFORMANCE,
     DeclIDField, // the protocol
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 9237bf2..7be6b66 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -2852,7 +2852,9 @@
     const ProtocolConformanceRef conformance, llvm::raw_ostream &out,
     unsigned indent,
     llvm::SmallPtrSetImpl<const ProtocolConformance *> &visited) {
-  if (conformance.isConcrete()) {
+  if (conformance.isInvalid()) {
+    out.indent(indent) << "(invalid_conformance)";
+  } else if (conformance.isConcrete()) {
     dumpProtocolConformanceRec(conformance.getConcrete(), out, indent, visited);
   } else {
     out.indent(indent) << "(abstract_conformance protocol="
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index 7e5d364..0d7e18c 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -74,6 +74,8 @@
 }
 
 ProtocolDecl *ProtocolConformanceRef::getRequirement() const {
+  assert(!isInvalid());
+
   if (isConcrete()) {
     return getConcrete()->getProtocol();
   } else {
@@ -83,8 +85,19 @@
 
 ProtocolConformanceRef
 ProtocolConformanceRef::subst(Type origType,
+                              SubstitutionMap subMap) const {
+  return subst(origType,
+               QuerySubstitutionMap{subMap},
+               LookUpConformanceInSubstitutionMap(subMap));
+}
+
+ProtocolConformanceRef
+ProtocolConformanceRef::subst(Type origType,
                               TypeSubstitutionFn subs,
                               LookupConformanceFn conformances) const {
+  if (isInvalid())
+    return *this;
+
   auto substType = origType.subst(subs, conformances,
                                   SubstFlags::UseErrorType);
 
@@ -96,8 +109,7 @@
       // If this is a class, we need to traffic in the actual type that
       // implements the protocol, not 'Self' and not any subclasses (with their
       // inherited conformances).
-      substType =
-          substType->eraseDynamicSelfType()->getSuperclassForDecl(classDecl);
+      substType = substType->getSuperclassForDecl(classDecl);
     }
     return ProtocolConformanceRef(
       getConcrete()->subst(substType, subs, conformances));
@@ -130,6 +142,8 @@
                                              ProtocolConformanceRef conformance,
                                              Identifier name,
                                              LazyResolver *resolver) {
+  assert(!conformance.isInvalid());
+
   // Find the named requirement.
   AssociatedTypeDecl *assocType = nullptr;
   auto members = conformance.getRequirement()->lookupDirect(name);
@@ -739,9 +753,7 @@
     SubstitutionMap::getProtocolSubstitutions(getRequirement(),
                                               conformingType, *this);
   auto abstractConf = ProtocolConformanceRef(protocol);
-  return abstractConf.subst(assocType,
-                            QuerySubstitutionMap{subMap},
-                            LookUpConformanceInSubstitutionMap(subMap));
+  return abstractConf.subst(assocType, subMap);
 }
 
 ProtocolConformanceRef
@@ -942,9 +954,7 @@
        ? conformance.getConcrete()->getType()
        : GenericConformance->getAssociatedType(assocType, resolver));
 
-  return conformance.subst(origType,
-                           QuerySubstitutionMap{subMap},
-                           LookUpConformanceInSubstitutionMap(subMap));
+  return conformance.subst(origType, subMap);
 }
 
 ConcreteDeclRef
@@ -1029,6 +1039,14 @@
 
 ProtocolConformance *
 ProtocolConformance::subst(Type substType,
+                           SubstitutionMap subMap) const {
+  return subst(substType,
+               QuerySubstitutionMap{subMap},
+               LookUpConformanceInSubstitutionMap(subMap));
+}
+
+ProtocolConformance *
+ProtocolConformance::subst(Type substType,
                            TypeSubstitutionFn subs,
                            LookupConformanceFn conformances) const {
   // ModuleDecl::lookupConformance() strips off dynamic Self, so
@@ -1351,14 +1369,14 @@
 
 /// Check of all types used by the conformance are canonical.
 bool ProtocolConformanceRef::isCanonical() const {
-  if (isAbstract())
+  if (isAbstract() || isInvalid())
     return true;
   return getConcrete()->isCanonical();
 }
 
 ProtocolConformanceRef
 ProtocolConformanceRef::getCanonicalConformanceRef() const {
-  if (isAbstract())
+  if (isAbstract() || isInvalid())
     return *this;
   return ProtocolConformanceRef(getConcrete()->getCanonicalConformance());
 }
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index 213d8d9..4d406a5 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -224,7 +224,7 @@
     auto protoType = req.getSecondType()->castTo<ProtocolType>();
     auto proto = protoType->getDecl();
     auto conformance = lookupConformance(depTy, replacement, proto)
-                         .getValueOr(ProtocolConformanceRef(proto));
+                         .getValueOr(ProtocolConformanceRef::forInvalid());
     conformances.push_back(conformance);
   }
 
@@ -369,6 +369,9 @@
       continue;
     }
 
+    if (conformance->isInvalid())
+      return conformance;
+
     // If we've hit an abstract conformance, everything from here on out is
     // abstract.
     // FIXME: This may not always be true, but it holds for now.
@@ -444,7 +447,7 @@
         ProtocolDecl *proto) ->Optional<ProtocolConformanceRef> {
       auto conformance =
         lookupConformance(dependentType, proto)
-          .getValueOr(ProtocolConformanceRef(proto));
+          .getValueOr(ProtocolConformanceRef::forInvalid());
       auto substType = dependentType.subst(*this, SubstFlags::UseErrorType);
       return conformance.subst(substType, subs, conformances);
     });
@@ -610,6 +613,9 @@
 
     auto conformance = getConformances()[conformanceIndex];
 
+    if (conformance.isInvalid())
+      continue;
+
     // An existential type can have an abstract conformance to
     // AnyObject or an @objc protocol.
     if (conformance.isAbstract() &&
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 813108b..9f40989 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// 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
@@ -1996,15 +1996,6 @@
                    nullptr };
     };
 
-    // HACK: In Swift 3 mode, we accepted (Void) -> Void for () -> Void
-    if (dc->getASTContext().isSwiftVersion3()
-        && functionType->getParams().size() == 1
-        && functionType->getParams()[0].getLabel().empty()
-        && functionType->getParams()[0].getType()->isVoid()
-        && functionType->getResult()->isVoid()) {
-      return success(anyStaticBridged, anyBridged, isBlock);
-    }
-
     // Look at the result type.
     Type resultType = functionType->getResult();
     if (!resultType->isVoid() && recurse(resultType))
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index f2fe10a..6281e7f 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -1962,7 +1962,7 @@
     return module->getTopLevelModuleName() == "Foundation";
   };
 
-  if (langOpts.isSwiftVersion3() || isFromFoundationModule(decl)) {
+  if (isFromFoundationModule(decl)) {
     // In Swift 3 we used a hardcoded list of declarations, and made all of
     // their subclasses drop their generic parameters when imported.
     while (decl) {
@@ -7558,41 +7558,6 @@
                                           PlatformAgnostic, /*Implicit=*/false);
 
       MappedDecl->getAttrs().add(AvAttr);
-
-      // For enum cases introduced in the 2017 SDKs, add
-      // @_downgrade_exhaustivity_check in Swift 3.
-      if (C.LangOpts.isSwiftVersion3() && isa<EnumElementDecl>(MappedDecl)) {
-        bool downgradeExhaustivity = false;
-        switch (*platformK) {
-        case PlatformKind::OSX:
-        case PlatformKind::OSXApplicationExtension:
-          downgradeExhaustivity = (introduced.getMajor() == 10 &&
-                                   introduced.getMinor() &&
-                                   *introduced.getMinor() == 13);
-          break;
-
-        case PlatformKind::iOS:
-        case PlatformKind::iOSApplicationExtension:
-        case PlatformKind::tvOS:
-        case PlatformKind::tvOSApplicationExtension:
-          downgradeExhaustivity = (introduced.getMajor() == 11);
-          break;
-
-        case PlatformKind::watchOS:
-        case PlatformKind::watchOSApplicationExtension:
-          downgradeExhaustivity = (introduced.getMajor() == 4);
-          break;
-
-        case PlatformKind::none:
-          break;
-        }
-
-        if (downgradeExhaustivity) {
-          auto attr =
-            new (C) DowngradeExhaustivityCheckAttr(/*isImplicit=*/true);
-          MappedDecl->getAttrs().add(attr);
-        }
-      }
     }
   }
 
@@ -7723,8 +7688,7 @@
       }
     }
     if (auto method = dyn_cast<clang::ObjCMethodDecl>(ClangDecl)) {
-      if (!SwiftContext.LangOpts.isSwiftVersion3() &&
-          method->isDesignatedInitializerForTheInterface()) {
+      if (method->isDesignatedInitializerForTheInterface()) {
         const clang::ObjCInterfaceDecl *theClass = method->getClassInterface();
         assert(theClass && "cannot be a protocol method here");
         // Only allow this to affect declarations in the same top-level module
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index 9ea9ae6..9674640 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -884,10 +884,7 @@
               }
               importedTypeArg = subresult.AbstractType;
             } else if (typeParam->getSuperclass() &&
-                       (Impl.SwiftContext.isSwiftVersion3() ||
-                        typeParam->getConformingProtocols().empty())) {
-              // In Swift 3 mode, discard the protocol bounds if there is
-              // a superclass bound.
+                       typeParam->getConformingProtocols().empty()) {
               importedTypeArg = typeParam->getSuperclass();
             } else {
               SmallVector<Type, 4> memberTypes;
@@ -1039,10 +1036,7 @@
         }
       }
 
-      // Swift 3 compatibility -- don't import subclass existentials
-      if (!type->qual_empty() &&
-          (importedType->isAnyObject() ||
-           !Impl.SwiftContext.isSwiftVersion3())) {
+      if (!type->qual_empty()) {
         SmallVector<Type, 4> members;
         if (!importedType->isAnyObject())
           members.push_back(importedType);
@@ -1555,23 +1549,7 @@
     bool allowNSUIntegerAsInt) {
 
   // Hardcode handling of certain result types for builtins.
-  auto builtinID = clangDecl->getBuiltinID();
-  switch (builtinID) {
-  case clang::Builtin::NotBuiltin:
-    break;
-  case clang::Builtin::BIstrxfrm:
-  case clang::Builtin::BIstrcspn:
-  case clang::Builtin::BIstrspn:
-  case clang::Builtin::BIstrlen:
-  case clang::Builtin::BIstrlcpy:
-  case clang::Builtin::BIstrlcat:
-    // This is a list of all built-ins with a result type of 'size_t' that
-    // existed in Swift 3. We didn't have special handling for builtins at
-    // that time, and so these had a result type of UInt.
-    if (SwiftContext.isSwiftVersion3())
-      break;
-    LLVM_FALLTHROUGH;
-  default:
+  if (auto builtinID = clangDecl->getBuiltinID()) {
     switch (getClangASTContext().BuiltinInfo.getTypeString(builtinID)[0]) {
     case 'z': // size_t
     case 'Y': // ptrdiff_t
diff --git a/lib/SIL/MemAccessUtils.cpp b/lib/SIL/MemAccessUtils.cpp
index be62eb8..0825dc3 100644
--- a/lib/SIL/MemAccessUtils.cpp
+++ b/lib/SIL/MemAccessUtils.cpp
@@ -181,6 +181,16 @@
   return funcRef->isGlobalInit() && funcRef->isExternalDeclaration();
 }
 
+// Return true if the given StructExtractInst extracts the RawPointer from
+// Unsafe[Mutable]Pointer.
+static bool isUnsafePointerExtraction(StructExtractInst *SEI) {
+  assert(isa<BuiltinRawPointerType>(SEI->getType().getASTType()));
+  auto &C = SEI->getModule().getASTContext();
+  auto *decl = SEI->getStructDecl();
+  return decl == C.getUnsafeMutablePointerDecl()
+    || decl == C.getUnsafePointerDecl();
+}
+
 // Given an address base is a block argument, verify that it is actually a box
 // projected from a switch_enum. This is a valid pattern at any SIL stage
 // resulting in a block-type phi. In later SIL stages, the optimizer may form
@@ -231,6 +241,12 @@
     if (kind != AccessedStorage::Unidentified)
       return AccessedStorage(address, kind);
 
+    // If the address producer cannot immediately be classified, follow the
+    // use-def chain of address, box, or RawPointer producers.
+    assert(address->getType().isAddress()
+           || isa<SILBoxType>(address->getType().getASTType())
+           || isa<BuiltinRawPointerType>(address->getType().getASTType()));
+
     // Handle other unidentified address sources.
     switch (address->getKind()) {
     default:
@@ -248,6 +264,14 @@
       // Don't currently allow any other calls to return an accessed address.
       return AccessedStorage();
 
+    case ValueKind::StructExtractInst:
+      // Handle nested access to a KeyPath projection. The projection itself
+      // uses a Builtin. However, the returned UnsafeMutablePointer may be
+      // converted to an address and accessed via an inout argument.
+      if (isUnsafePointerExtraction(cast<StructExtractInst>(address)))
+        return AccessedStorage(address, AccessedStorage::Unidentified);
+      return AccessedStorage();
+
     // A block argument may be a box value projected out of
     // switch_enum. Address-type block arguments are not allowed.
     case ValueKind::SILPHIArgument:
@@ -276,6 +300,12 @@
       return AccessedStorage();
     }
 
+    // ref_tail_addr project an address from a reference.
+    // This is a valid address producer for nested @inout argument
+    // access, but it is never used for formal access of identified objects.
+    case ValueKind::RefTailAddrInst:
+      return AccessedStorage(address, AccessedStorage::Unidentified);
+
     // Inductive cases:
     // Look through address casts to find the source address.
     case ValueKind::MarkUninitializedInst:
@@ -297,8 +327,8 @@
       continue;
 
     // Access to a Builtin.RawPointer. Treat this like the inductive cases
-    // above because some RawPointer's originate from identified locations. See
-    // the special case for global addressors, which return RawPointer above.
+    // above because some RawPointers originate from identified locations. See
+    // the special case for global addressors, which return RawPointer, above.
     //
     // If the inductive search does not find a valid addressor, it will
     // eventually reach the default case that returns in invalid location. This
@@ -320,11 +350,10 @@
       address = cast<SingleValueInstruction>(address)->getOperand(0);
       continue;
 
-    // Subobject projections.
+    // Address-to-address subobject projections.
     case ValueKind::StructElementAddrInst:
     case ValueKind::TupleElementAddrInst:
     case ValueKind::UncheckedTakeEnumDataAddrInst:
-    case ValueKind::RefTailAddrInst:
     case ValueKind::TailAddrInst:
     case ValueKind::IndexAddrInst:
       address = cast<SingleValueInstruction>(address)->getOperand(0);
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index 19762d7..3ac3d87 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -70,6 +70,9 @@
       if (!decl)
         return false;
 
+      if (isa<ProtocolDecl>(decl))
+        return false;
+
       auto *genericSig = decl->getGenericSignature();
       if (!genericSig)
         return false;
diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp
index a765859..b5f2abf 100644
--- a/lib/SILOptimizer/PassManager/PassManager.cpp
+++ b/lib/SILOptimizer/PassManager/PassManager.cpp
@@ -236,10 +236,10 @@
   Mod(M), StageName(Stage), isMandatoryPipeline(isMandatoryPipeline) {
   
 #define ANALYSIS(NAME) \
-  Analysis.push_back(create##NAME##Analysis(Mod));
+  Analyses.push_back(create##NAME##Analysis(Mod));
 #include "swift/SILOptimizer/Analysis/Analysis.def"
 
-  for (SILAnalysis *A : Analysis) {
+  for (SILAnalysis *A : Analyses) {
     A->initialize(this);
     M->registerDeleteNotificationHandler(A);
   }
@@ -258,7 +258,7 @@
 }
 
 bool SILPassManager::analysesUnlocked() {
-  for (auto *A : Analysis)
+  for (auto *A : Analyses)
     if (A->isLocked())
       return false;
 
@@ -544,7 +544,7 @@
     delete T;
 
   // delete the analysis.
-  for (auto *A : Analysis) {
+  for (auto *A : Analyses) {
     Mod->removeDeleteNotificationHandler(A);
     assert(!A->isLocked() &&
            "Deleting a locked analysis. Did we forget to unlock ?");
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 921da13..2ba558a 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -8088,11 +8088,13 @@
 Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr,
                                       Type convertType,
                                       bool discardedExpr,
-                                      bool suppressDiagnostics,
                                       bool skipClosures) {
   // If any fixes needed to be applied to arrive at this solution, resolve
   // them to specific expressions.
   if (!solution.Fixes.empty()) {
+    if (shouldSuppressDiagnostics())
+      return nullptr;
+
     // If we can diagnose the problem with the fixits that we've pre-assumed,
     // do so now.
     if (applySolutionFixes(expr, solution))
@@ -8108,7 +8110,7 @@
   for (auto &e : solution.Conformances)
     TC.markConformanceUsed(e.second, DC);
 
-  ExprRewriter rewriter(*this, solution, suppressDiagnostics);
+  ExprRewriter rewriter(*this, solution, shouldSuppressDiagnostics());
   ExprWalker walker(rewriter);
 
   // Apply the solution to the expression.
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 5e47e71..34e3a28 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1167,6 +1167,7 @@
       if (!E->isActivated())
         return Type();
 
+      CS.Options |= ConstraintSystemFlags::SuppressDiagnostics;
       return CS.createTypeVariable(CS.getConstraintLocator(E),
                                    TVO_CanBindToLValue);
     }
@@ -3562,6 +3563,8 @@
   }
 
   Type visitCodeCompletionExpr(CodeCompletionExpr *Expr) override {
+    auto &cs = getConstraintSystem();
+    cs.Options |= ConstraintSystemFlags::SuppressDiagnostics;
     return createFreeTypeVariableType(Expr);
   }
 
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 58cb681..4f0a191 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1320,12 +1320,63 @@
   }
 }
 
+bool ConstraintSystem::solve(Expr *&expr,
+                             Type convertType,
+                             ExprTypeCheckListener *listener,
+                             SmallVectorImpl<Solution> &solutions,
+                             FreeTypeVariableBinding allowFreeTypeVariables) {
+  // Attempt to solve the constraint system.
+  auto solution = solveImpl(expr,
+                            convertType,
+                            listener,
+                            solutions,
+                            allowFreeTypeVariables);
+
+  // The constraint system has failed
+  if (solution == SolutionKind::Error)
+    return true;
+
+  // If the system is unsolved or there are multiple solutions present but
+  // type checker options do not allow unresolved types, let's try to salvage
+  if (solution == SolutionKind::Unsolved ||
+      (solutions.size() != 1 &&
+       !Options.contains(
+           ConstraintSystemFlags::AllowUnresolvedTypeVariables))) {
+    if (shouldSuppressDiagnostics())
+      return true;
+
+    // Try to provide a decent diagnostic.
+    if (salvage(solutions, expr)) {
+      // If salvage produced an error message, then it failed to salvage the
+      // expression, just bail out having reported the error.
+      return true;
+    }
+
+    // The system was salvaged; continue on as if nothing happened.
+  }
+
+  if (TC.getLangOpts().DebugConstraintSolver) {
+    auto &log = getASTContext().TypeCheckerDebug->getStream();
+    if (solutions.size() == 1) {
+      log << "---Solution---\n";
+      solutions[0].dump(log);
+    } else {
+      for (unsigned i = 0, e = solutions.size(); i != e; ++i) {
+        log << "--- Solution #" << i << " ---\n";
+        solutions[i].dump(log);
+      }
+    }
+  }
+
+  return false;
+}
+
 ConstraintSystem::SolutionKind
-ConstraintSystem::solve(Expr *&expr,
-                        Type convertType,
-                        ExprTypeCheckListener *listener,
-                        SmallVectorImpl<Solution> &solutions,
-                        FreeTypeVariableBinding allowFreeTypeVariables) {
+ConstraintSystem::solveImpl(Expr *&expr,
+                            Type convertType,
+                            ExprTypeCheckListener *listener,
+                            SmallVectorImpl<Solution> &solutions,
+                            FreeTypeVariableBinding allowFreeTypeVariables) {
   if (TC.getLangOpts().DebugConstraintSolver) {
     auto &log = getASTContext().TypeCheckerDebug->getStream();
     log << "---Constraint solving for the expression at ";
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index c4d76ea..b85fc0a 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -1998,9 +1998,14 @@
       Type lookupBaseType = newBase->getWithoutSpecifierType();
 
       if (lookupBaseType->mayHaveMembers()) {
-        auto subs = lookupBaseType->getContextSubstitutionMap(
-          cs.DC->getParentModule(),
-            assocType->getDeclContext());
+        auto *proto = assocType->getProtocol();
+        auto conformance = cs.DC->getParentModule()->lookupConformance(
+          lookupBaseType, proto);
+        if (!conformance)
+          return DependentMemberType::get(lookupBaseType, assocType);
+
+        auto subs = SubstitutionMap::getProtocolSubstitutions(
+          proto, lookupBaseType, *conformance);
         auto result = assocType->getDeclaredInterfaceType().subst(subs);
 
         if (result && !result->hasError())
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index a963d7d..f277363 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -790,6 +790,16 @@
   /// If set, this is going to prevent constraint system from erasing all
   /// discovered solutions except the best one.
   ReturnAllDiscoveredSolutions = 0x04,
+
+  /// Set if the client wants diagnostics suppressed.
+  SuppressDiagnostics = 0x08,
+
+  /// If set, the client wants a best-effort solution to the constraint system,
+  /// but can tolerate a solution where all of the constraints are solved, but
+  /// not all type variables have been determined.  In this case, the constraint
+  /// system is not applied to the expression AST, but the ConstraintSystem is
+  /// left in-tact.
+  AllowUnresolvedTypeVariables = 0x10,
 };
 
 /// Options that affect the constraint system as a whole.
@@ -1716,6 +1726,10 @@
     return !solverState || solverState->recordFixes;
   }
 
+  bool shouldSuppressDiagnostics() {
+    return Options.contains(ConstraintSystemFlags::SuppressDiagnostics);
+  }
+
   /// \brief Log and record the application of the fix. Return true iff any
   /// subsequent solution would be worse than the best known solution.
   bool recordFix(Fix fix, ConstraintLocatorBuilder locator);
@@ -2965,7 +2979,6 @@
                                      bool *foundConsistent);
   bool areBindPairConsistent(Constraint *first, Constraint *second);
 
-public:
   /// \brief Solve the system of constraints generated from provided expression.
   ///
   /// \param expr The expression to generate constraints from.
@@ -2977,12 +2990,34 @@
   ///
   /// \returns Error is an error occurred, Solved is system is consistent
   /// and solutions were found, Unsolved otherwise.
-  SolutionKind solve(Expr *&expr,
-                     Type convertType,
-                     ExprTypeCheckListener *listener,
-                     SmallVectorImpl<Solution> &solutions,
-                     FreeTypeVariableBinding allowFreeTypeVariables
-                       = FreeTypeVariableBinding::Disallow);
+  SolutionKind solveImpl(Expr *&expr,
+                         Type convertType,
+                         ExprTypeCheckListener *listener,
+                         SmallVectorImpl<Solution> &solutions,
+                         FreeTypeVariableBinding allowFreeTypeVariables
+                          = FreeTypeVariableBinding::Disallow);
+
+public:
+  /// \brief Solve the system of constraints generated from provided expression.
+  ///
+  /// The expression should have already been pre-checked with
+  /// preCheckExpression().
+  ///
+  /// \param expr The expression to generate constraints from.
+  /// \param convertType The expected type of the expression.
+  /// \param listener The callback to check solving progress.
+  /// \param solutions The set of solutions to the system of constraints.
+  /// \param allowFreeTypeVariables How to bind free type variables in
+  /// the solution.
+  ///
+  /// \returns true is an error occurred, false is system is consistent
+  /// and solutions were found.
+  bool solve(Expr *&expr,
+             Type convertType,
+             ExprTypeCheckListener *listener,
+             SmallVectorImpl<Solution> &solutions,
+             FreeTypeVariableBinding allowFreeTypeVariables
+             = FreeTypeVariableBinding::Disallow);
 
   /// \brief Solve the system of constraints.
   ///
@@ -3070,7 +3105,6 @@
   /// non-single expression closures.
   Expr *applySolution(Solution &solution, Expr *expr,
                       Type convertType, bool discardedExpr,
-                      bool suppressDiagnostics,
                       bool skipClosures);
 
   /// \brief Apply a given solution to the expression to the top-level
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index e37e28f..619ea2c 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -1909,57 +1909,6 @@
   return false;
 }
 
-bool TypeChecker::
-solveForExpression(Expr *&expr, DeclContext *dc, Type convertType,
-                   FreeTypeVariableBinding allowFreeTypeVariables,
-                   ExprTypeCheckListener *listener, ConstraintSystem &cs,
-                   SmallVectorImpl<Solution> &viable,
-                   TypeCheckExprOptions options) {
-  // Attempt to solve the constraint system.
-  auto solution = cs.solve(expr,
-                           convertType,
-                           listener,
-                           viable,
-                           allowFreeTypeVariables);
-
-  // The constraint system has failed
-  if (solution == ConstraintSystem::SolutionKind::Error)
-    return true;
-
-  // If the system is unsolved or there are multiple solutions present but
-  // type checker options do not allow unresolved types, let's try to salvage
-  if (solution == ConstraintSystem::SolutionKind::Unsolved
-      || (viable.size() != 1 &&
-          !options.contains(TypeCheckExprFlags::AllowUnresolvedTypeVariables))) {
-    if (options.contains(TypeCheckExprFlags::SuppressDiagnostics))
-      return true;
-
-    // Try to provide a decent diagnostic.
-    if (cs.salvage(viable, expr)) {
-      // If salvage produced an error message, then it failed to salvage the
-      // expression, just bail out having reported the error.
-      return true;
-    }
-
-    // The system was salvaged; continue on as if nothing happened.
-  }
-
-  if (getLangOpts().DebugConstraintSolver) {
-    auto &log = Context.TypeCheckerDebug->getStream();
-    if (viable.size() == 1) {
-      log << "---Solution---\n";
-      viable[0].dump(log);
-    } else {
-      for (unsigned i = 0, e = viable.size(); i != e; ++i) {
-        log << "--- Solution #" << i << " ---\n";
-        viable[i].dump(log);
-      }
-    }
-  }
-
-  return false;
-}
-
 #pragma mark High-level entry points
 Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
                                       TypeLoc convertType,
@@ -1976,6 +1925,13 @@
 
   // Construct a constraint system from this expression.
   ConstraintSystemOptions csOptions = ConstraintSystemFlags::AllowFixes;
+
+  if (options.contains(TypeCheckExprFlags::SuppressDiagnostics))
+    csOptions |= ConstraintSystemFlags::SuppressDiagnostics;
+
+  if (options.contains(TypeCheckExprFlags::AllowUnresolvedTypeVariables))
+    csOptions |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;
+
   ConstraintSystem cs(*this, dc, csOptions);
   cs.baseCS = baseCS;
   CleanupIllFormedExpressionRAII cleanup(expr);
@@ -2007,9 +1963,6 @@
   // that we don't later treat it as an actual conversion constraint.
   if (options.contains(TypeCheckExprFlags::ConvertTypeIsOnlyAHint))
     convertType = TypeLoc();
-  
-  bool suppressDiagnostics =
-    options.contains(TypeCheckExprFlags::SuppressDiagnostics);
 
   // If the client can handle unresolved type variables, leave them in the
   // system.
@@ -2019,8 +1972,8 @@
 
   // Attempt to solve the constraint system.
   SmallVector<Solution, 4> viable;
-  if (solveForExpression(expr, dc, convertType.getType(),
-                         allowFreeTypeVariables, listener, cs, viable, options))
+  if (cs.solve(expr, convertType.getType(), listener, viable,
+               allowFreeTypeVariables))
     return Type();
 
   // If the client allows the solution to have unresolved type expressions,
@@ -2046,11 +1999,10 @@
   }
 
   // Apply the solution to the expression.
-  bool isDiscarded = options.contains(TypeCheckExprFlags::IsDiscarded);
-  bool skipClosures = options.contains(TypeCheckExprFlags::SkipMultiStmtClosures);
-  result = cs.applySolution(solution, result, convertType.getType(),
-                            isDiscarded, suppressDiagnostics,
-                            skipClosures);
+  result = cs.applySolution(
+      solution, result, convertType.getType(),
+      options.contains(TypeCheckExprFlags::IsDiscarded),
+      options.contains(TypeCheckExprFlags::SkipMultiStmtClosures));
   if (!result) {
     // Failure already diagnosed, above, as part of applying the solution.
     return Type();
@@ -2072,7 +2024,7 @@
 
   // Unless the client has disabled them, perform syntactic checks on the
   // expression now.
-  if (!suppressDiagnostics &&
+  if (!cs.shouldSuppressDiagnostics() &&
       !options.contains(TypeCheckExprFlags::DisableStructuralChecks)) {
     bool isExprStmt = options.contains(TypeCheckExprFlags::IsExprStmt);
     performSyntacticExprDiagnostics(*this, result, dc, isExprStmt);
@@ -2092,7 +2044,7 @@
   referencedDecl = nullptr;
 
   // Construct a constraint system from this expression.
-  ConstraintSystem cs(*this, dc, ConstraintSystemFlags::AllowFixes);
+  ConstraintSystem cs(*this, dc, ConstraintSystemFlags::SuppressDiagnostics);
   CleanupIllFormedExpressionRAII cleanup(expr);
 
   // Attempt to solve the constraint system.
@@ -2108,9 +2060,8 @@
   // re-check.
   if (needClearType)
     expr->setType(Type());
-  if (solveForExpression(expr, dc, /*convertType*/Type(),
-                         allowFreeTypeVariables, listener, cs, viable,
-                         TypeCheckExprFlags::SuppressDiagnostics)) {
+  if (cs.solve(expr, /*convertType*/Type(), listener, viable,
+               allowFreeTypeVariables)) {
     recoverOriginalType();
     return Type();
   }
@@ -2177,8 +2128,8 @@
 
   // Construct a constraint system from this expression.
   ConstraintSystemOptions options;
-  options |= ConstraintSystemFlags::AllowFixes;
   options |= ConstraintSystemFlags::ReturnAllDiscoveredSolutions;
+  options |= ConstraintSystemFlags::SuppressDiagnostics;
 
   ConstraintSystem cs(*this, dc, options);
 
@@ -2194,9 +2145,8 @@
     if (originalType && originalType->hasError())
       expr->setType(Type());
 
-    solveForExpression(expr, dc, /*convertType*/ Type(), allowFreeTypeVariables,
-                       listener, cs, viable,
-                       TypeCheckExprFlags::SuppressDiagnostics);
+    cs.solve(expr, /*convertType*/ Type(), listener, viable,
+             allowFreeTypeVariables);
   }
 
   for (auto &solution : viable) {
@@ -2210,7 +2160,7 @@
   PrettyStackTraceExpr stackTrace(Context, "type-checking", expr);
 
   // Construct a constraint system from this expression.
-  ConstraintSystem CS(*this, DC, ConstraintSystemFlags::AllowFixes);
+  ConstraintSystem CS(*this, DC, ConstraintSystemFlags::SuppressDiagnostics);
   CleanupIllFormedExpressionRAII cleanup(expr);
 
   auto *SE = cast<SequenceExpr>(expr);
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index cf70750..0befdcb 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -900,13 +900,17 @@
   auto &ctx = DC->getASTContext();
   if (ctx.getLazyResolver()) {
     TypeChecker *TC = static_cast<TypeChecker *>(ctx.getLazyResolver());
-    auto resultTy = TC->typeCheckExpression(parsedExpr, DC);
+    auto resultTy = TC->typeCheckExpression(parsedExpr, DC, TypeLoc(),
+                                      ContextualTypePurpose::CTP_Unused,
+                                      TypeCheckExprFlags::SuppressDiagnostics);
     return !resultTy;
   } else {
     // Set up a diagnostics engine that swallows diagnostics.
     DiagnosticEngine diags(ctx.SourceMgr);
     TypeChecker TC(ctx, diags);
-    auto resultTy = TC.typeCheckExpression(parsedExpr, DC);
+    auto resultTy = TC.typeCheckExpression(parsedExpr, DC, TypeLoc(),
+                                      ContextualTypePurpose::CTP_Unused,
+                                      TypeCheckExprFlags::SuppressDiagnostics);
     return !resultTy;
   }
 }
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 917e213..c321754 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1487,22 +1487,6 @@
   /// expression and folding sequence expressions.
   bool preCheckExpression(Expr *&expr, DeclContext *dc);
 
-  /// Sets up and solves the constraint system \p cs to type check the given
-  /// expression.
-  ///
-  /// The expression should have already been pre-checked with
-  /// preCheckExpression().
-  ///
-  /// \returns true if an error occurred, false otherwise.
-  ///
-  /// \see typeCheckExpression
-  bool solveForExpression(Expr *&expr, DeclContext *dc, Type convertType,
-                          FreeTypeVariableBinding allowFreeTypeVariables,
-                          ExprTypeCheckListener *listener,
-                          constraints::ConstraintSystem &cs,
-                          SmallVectorImpl<constraints::Solution> &viable,
-                          TypeCheckExprOptions options);
-
   /// \name Name lookup
   ///
   /// Routines that perform name lookup.
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 48d0a80..32409f0 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -469,6 +469,10 @@
 
   unsigned kind = Cursor.readRecord(next.ID, scratch);
   switch (kind) {
+  case INVALID_PROTOCOL_CONFORMANCE: {
+    return ProtocolConformanceRef::forInvalid();
+  }
+
   case ABSTRACT_PROTOCOL_CONFORMANCE: {
     DeclID protoID;
     AbstractProtocolConformanceLayout::readRecord(scratch, protoID);
diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h
index 537c242..3eb5401 100644
--- a/lib/Serialization/SILFormat.h
+++ b/lib/Serialization/SILFormat.h
@@ -179,6 +179,7 @@
       = decls_block::SPECIALIZED_PROTOCOL_CONFORMANCE,
     INHERITED_PROTOCOL_CONFORMANCE
       = decls_block::INHERITED_PROTOCOL_CONFORMANCE,
+    INVALID_PROTOCOL_CONFORMANCE = decls_block::INVALID_PROTOCOL_CONFORMANCE,
     GENERIC_PARAM = decls_block::GENERIC_PARAM,
     GENERIC_REQUIREMENT = decls_block::GENERIC_REQUIREMENT,
     LAYOUT_REQUIREMENT = decls_block::LAYOUT_REQUIREMENT,
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index a82e034..5d6ad35 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -857,6 +857,8 @@
   // These layouts can exist in both decl blocks and sil blocks.
 #define BLOCK_RECORD_WITH_NAMESPACE(K, X) emitRecordID(Out, X, #X, nameBuffer)
   BLOCK_RECORD_WITH_NAMESPACE(sil_block,
+                              decls_block::INVALID_PROTOCOL_CONFORMANCE);
+  BLOCK_RECORD_WITH_NAMESPACE(sil_block,
                               decls_block::ABSTRACT_PROTOCOL_CONFORMANCE);
   BLOCK_RECORD_WITH_NAMESPACE(sil_block,
                               decls_block::NORMAL_PROTOCOL_CONFORMANCE);
@@ -1634,6 +1636,12 @@
                              GenericEnvironment *genericEnv) {
   using namespace decls_block;
 
+  if (conformanceRef.isInvalid()) {
+    unsigned abbrCode = abbrCodes[InvalidProtocolConformanceLayout::Code];
+    InvalidProtocolConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode);
+    return;
+  }
+
   if (conformanceRef.isAbstract()) {
     unsigned abbrCode = abbrCodes[AbstractProtocolConformanceLayout::Code];
     AbstractProtocolConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode,
@@ -4067,6 +4075,7 @@
   registerDeclTypeAbbr<NormalProtocolConformanceLayout>();
   registerDeclTypeAbbr<SpecializedProtocolConformanceLayout>();
   registerDeclTypeAbbr<InheritedProtocolConformanceLayout>();
+  registerDeclTypeAbbr<InvalidProtocolConformanceLayout>();
   registerDeclTypeAbbr<NormalProtocolConformanceIdLayout>();
   registerDeclTypeAbbr<ProtocolConformanceXrefLayout>();
 
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 42b9931..696bf72 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -121,7 +121,7 @@
   SmallString.swift
   Sort.swift
   StaticString.swift
-  Stride.swift.gyb
+  Stride.swift
   StringHashable.swift  # ORDER DEPENDENCY: Must precede String.swift
   String.swift
   StringBridge.swift
diff --git a/stdlib/public/core/MigrationSupport.swift b/stdlib/public/core/MigrationSupport.swift
index 8f76639..f742838 100644
--- a/stdlib/public/core/MigrationSupport.swift
+++ b/stdlib/public/core/MigrationSupport.swift
@@ -869,6 +869,52 @@
   }
 }
 
+extension Strideable {
+  @available(swift, deprecated: 3, obsoleted: 4, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")
+  public static func + (lhs: Self, rhs: Self.Stride) -> Self {
+    return lhs.advanced(by: rhs)
+  }
+
+  @available(swift, deprecated: 3, obsoleted: 4, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")
+  public static func + (lhs: Self.Stride, rhs: Self) -> Self {
+    return rhs.advanced(by: lhs)
+  }
+
+  @available(swift, deprecated: 3, obsoleted: 4, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")
+  public static func - (lhs: Self, rhs: Self.Stride) -> Self {
+    return lhs.advanced(by: -rhs)
+  }
+
+  @available(swift, deprecated: 3, obsoleted: 4, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")
+  public static func - (lhs: Self, rhs: Self) -> Self.Stride {
+    return rhs.distance(to: lhs)
+  }
+
+  @available(swift, deprecated: 3, obsoleted: 4, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")
+  public static func += (lhs: inout Self, rhs: Self.Stride) {
+    lhs = lhs.advanced(by: rhs)
+  }
+
+  @available(swift, deprecated: 3, obsoleted: 4, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")
+  public static func -= (lhs: inout Self, rhs: Self.Stride) {
+    lhs = lhs.advanced(by: -rhs)
+  }
+}
+
+extension UnsafeMutableRawPointer {
+  @available(*, unavailable, renamed: "init(mutating:)")
+  public init(_ from : UnsafeRawPointer) { Builtin.unreachable() }
+
+  @available(*, unavailable, renamed: "init(mutating:)")
+  public init?(_ from : UnsafeRawPointer?) { Builtin.unreachable() }
+
+  @available(*, unavailable, renamed: "init(mutating:)")
+  public init<T>(_ from : UnsafePointer<T>) { Builtin.unreachable() }
+
+  @available(*, unavailable, renamed: "init(mutating:)")
+  public init?<T>(_ from : UnsafePointer<T>?) { Builtin.unreachable() }
+}
+
 extension UnsafeRawPointer : _CustomPlaygroundQuickLookable {
   internal var summary: String {
     let ptrValue = UInt64(
diff --git a/stdlib/public/core/Pointer.swift b/stdlib/public/core/Pointer.swift
index 11f6ddf..d52bfdb 100644
--- a/stdlib/public/core/Pointer.swift
+++ b/stdlib/public/core/Pointer.swift
@@ -292,6 +292,39 @@
   }
 }
 
+// Pointer arithmetic operators (formerly via Strideable)
+extension Strideable where Self : _Pointer {
+  @_transparent
+  public static func + (lhs: Self, rhs: Self.Stride) -> Self {
+    return lhs.advanced(by: rhs)
+  }
+
+  @_transparent
+  public static func + (lhs: Self.Stride, rhs: Self) -> Self {
+    return rhs.advanced(by: lhs)
+  }
+
+  @_transparent
+  public static func - (lhs: Self, rhs: Self.Stride) -> Self {
+    return lhs.advanced(by: -rhs)
+  }
+
+  @_transparent
+  public static func - (lhs: Self, rhs: Self) -> Self.Stride {
+    return rhs.distance(to: lhs)
+  }
+
+  @_transparent
+  public static func += (lhs: inout Self, rhs: Self.Stride) {
+    lhs = lhs.advanced(by: rhs)
+  }
+
+  @_transparent
+  public static func -= (lhs: inout Self, rhs: Self.Stride) {
+    lhs = lhs.advanced(by: -rhs)
+  }
+}
+
 /// Derive a pointer argument from a convertible pointer type.
 @_transparent
 public // COMPILER_INTRINSIC
diff --git a/stdlib/public/core/Stride.swift.gyb b/stdlib/public/core/Stride.swift
similarity index 91%
rename from stdlib/public/core/Stride.swift.gyb
rename to stdlib/public/core/Stride.swift
index 9b3f8b3..9de124a 100644
--- a/stdlib/public/core/Stride.swift.gyb
+++ b/stdlib/public/core/Stride.swift
@@ -1,4 +1,4 @@
-//===--- Stride.swift.gyb - Components for stride(...) iteration ----------===//
+//===--- Stride.swift - Components for stride(...) iteration --------------===//
 //
 // This source file is part of the Swift.org open source project
 //
@@ -163,68 +163,6 @@
   }
 }
 
-//===----------------------------------------------------------------------===//
-
-%{
-  # Strideable used to provide + and - unconditionally. With the updated
-  # collection indexing model of Swift 3 this became unnecessary for integer
-  # types, and was deprecated, as it was a way to write mixed-type arithmetic
-  # expressions, that are otherwise are not allowed.
-}%
-% for Base, VersionInfo in [
-%   ('Strideable where Self : _Pointer', None),
-%   ('Strideable', 'deprecated: 3, obsoleted: 4'),
-%   ]:
-%   Availability = '@available(swift, %s, message: "Please use explicit type conversions or Strideable methods for mixed-type arithmetics.")' % (VersionInfo) if VersionInfo else ''
-
-extension ${Base} {
-  @inlinable // FIXME(sil-serialize-all)
-  @_transparent
-  ${Availability}
-  public static func + (lhs: Self, rhs: Self.Stride) -> Self {
-    return lhs.advanced(by: rhs)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @_transparent
-  ${Availability}
-  public static func + (lhs: Self.Stride, rhs: Self) -> Self {
-    return rhs.advanced(by: lhs)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @_transparent
-  ${Availability}
-  public static func - (lhs: Self, rhs: Self.Stride) -> Self {
-    return lhs.advanced(by: -rhs)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @_transparent
-  ${Availability}
-  public static func - (lhs: Self, rhs: Self) -> Self.Stride {
-    return rhs.distance(to: lhs)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @_transparent
-  ${Availability}
-  public static func += (lhs: inout Self, rhs: Self.Stride) {
-    lhs = lhs.advanced(by: rhs)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @_transparent
-  ${Availability}
-  public static func -= (lhs: inout Self, rhs: Self.Stride) {
-    lhs = lhs.advanced(by: -rhs)
-  }
-}
-
-% end
-
-//===----------------------------------------------------------------------===//
-
 extension Strideable {
   @inlinable // protocol-only
   public static func _step(
@@ -718,7 +656,3 @@
 ) -> StrideThrough<T> {
   return StrideThrough(_start: start, end: end, stride: stride)
 }
-
-// ${'Local Variables'}:
-// eval: (read-only-mode 1)
-// End:
diff --git a/stdlib/public/core/UnsafeRawPointer.swift b/stdlib/public/core/UnsafeRawPointer.swift
index 488d99b..821f54f 100644
--- a/stdlib/public/core/UnsafeRawPointer.swift
+++ b/stdlib/public/core/UnsafeRawPointer.swift
@@ -967,18 +967,3 @@
     self._rawValue = unwrapped._rawValue
   }
 }
-
-
-extension UnsafeMutableRawPointer {
-  @available(*, unavailable, renamed: "init(mutating:)")
-  public init(_ from : UnsafeRawPointer) { Builtin.unreachable() }
-
-  @available(*, unavailable, renamed: "init(mutating:)")
-  public init?(_ from : UnsafeRawPointer?) { Builtin.unreachable(); return nil }
-
-  @available(*, unavailable, renamed: "init(mutating:)")
-  public init<T>(_ from : UnsafePointer<T>) { Builtin.unreachable() }
-
-  @available(*, unavailable, renamed: "init(mutating:)")
-  public init?<T>(_ from : UnsafePointer<T>?) { Builtin.unreachable(); return nil }
-}
diff --git a/test/ClangImporter/availability_open_enums.swift b/test/ClangImporter/availability_open_enums.swift
index 68156fe..686e8a9 100644
--- a/test/ClangImporter/availability_open_enums.swift
+++ b/test/ClangImporter/availability_open_enums.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs/custom-modules -swift-version 4 -enable-nonfrozen-enum-exhaustivity-diagnostics %s
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs/custom-modules -enable-nonfrozen-enum-exhaustivity-diagnostics %s
 
 // REQUIRES: objc_interop
 
diff --git a/test/ClangImporter/clang_builtins.swift b/test/ClangImporter/clang_builtins.swift
index cb9fb1c..0e0eac2 100644
--- a/test/ClangImporter/clang_builtins.swift
+++ b/test/ClangImporter/clang_builtins.swift
@@ -1,4 +1,4 @@
-// RUN: not %target-swift-frontend -swift-version 4 -typecheck %s 2>&1 | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-%target-runtime %s
+// RUN: not %target-swift-frontend -typecheck %s 2>&1 | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-%target-runtime %s
 
 #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
   import Darwin
diff --git a/test/ClangImporter/subclass_existentials.swift b/test/ClangImporter/subclass_existentials.swift
index 15a085f..8a93d77 100644
--- a/test/ClangImporter/subclass_existentials.swift
+++ b/test/ClangImporter/subclass_existentials.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -o - -primary-file %s -swift-version 4 -I %S/Inputs/custom-modules/
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -o - -primary-file %s -I %S/Inputs/custom-modules/
 
 // REQUIRES: objc_interop
 
diff --git a/test/IDE/complete_operators.swift b/test/IDE/complete_operators.swift
index a4c2159..917abdc 100644
--- a/test/IDE/complete_operators.swift
+++ b/test/IDE/complete_operators.swift
@@ -210,8 +210,6 @@
   x#^INFIX_7^#
 }
 // S2_INFIX_OPTIONAL: Begin completions
-// FIXME: rdar://problem/22996887 - shouldn't complete with optional LHS
-// S2_INFIX_OPTIONAL-DAG: Decl[InfixOperatorFunction]/CurrModule:   ** {#Int#}[#S2#]
 // S2_INFIX_OPTIONAL-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]:  != {#{{.*}}#}[#Bool#]
 // S2_INFIX_OPTIONAL-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]:  == {#{{.*}}#}[#Bool#]
 // S2_INFIX_OPTIONAL-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]:  ?? {#S2#}[#S2#]; name=?? S2
diff --git a/test/Interpreter/enforce_exclusive_access.swift b/test/Interpreter/enforce_exclusive_access.swift
index 7453be5..816b49b 100644
--- a/test/Interpreter/enforce_exclusive_access.swift
+++ b/test/Interpreter/enforce_exclusive_access.swift
@@ -3,7 +3,6 @@
 //
 // RUN: %target-run %t/a.out
 // REQUIRES: executable_test
-// REQUIRES: rdar41660554
 
 // Tests for traps at run time when enforcing exclusive access.
 
@@ -306,7 +305,7 @@
 
   c[keyPath: getF] = 7
   c[keyPath: getF] = 8 // no-trap
-  c[keyPath: getF] += c[keyPath: getF] + 1 // no-trap
+  c[keyPath: getF] += c[keyPath: getF] // no-trap
 }
 
 ExclusiveAccessTestSuite.test("KeyPathInoutKeyPathWriteClassStoredProp")
diff --git a/test/SILOptimizer/exclusivity_static_diagnostics.sil b/test/SILOptimizer/exclusivity_static_diagnostics.sil
index 1b4b9bc..cad893d 100644
--- a/test/SILOptimizer/exclusivity_static_diagnostics.sil
+++ b/test/SILOptimizer/exclusivity_static_diagnostics.sil
@@ -1106,3 +1106,31 @@
   %v = tuple ()
   return %v : $()
 }
+
+// <rdar://problem/41660554> Swift CI (macOS release master, OSS): SIL verification failed: Unknown formal access pattern: storage
+// Test access marker verification of a KeyPath projection with nested @inout access after inlining.
+sil @takeInoutInt : $@convention(thin) (@inout Int) -> ()
+
+// The compiler intrinsic _projectXXXKeyPath returns a tuple of
+// UnsafePointer and Optional AnyObject. After inlining, the unsafe
+// pointer may appear to originate from anywhere, including a phi.
+// There's currently no way to tell that the UnsafePointer originated
+// from a KeyPath projection. This pattern could occur with any
+// addressor. In either case, the nested access is valid but
+// unidentified. Addressors that require enforcement must start a
+// dynamic access within the addressor itself, before returning an
+// UnsafePointer.
+sil @testNestedKeypathAccess : $@convention(thin) (@guaranteed (UnsafeMutablePointer<Int>, Optional<AnyObject>)) -> () {
+bb0(%0 : $(UnsafeMutablePointer<Int>, Optional<AnyObject>)):
+  %up = tuple_extract %0 : $(UnsafeMutablePointer<Int>, Optional<AnyObject>), 0
+  %o = tuple_extract %0 : $(UnsafeMutablePointer<Int>, Optional<AnyObject>), 1
+  %p = struct_extract %up : $UnsafeMutablePointer<Int>, #UnsafeMutablePointer._rawValue
+  %adr = pointer_to_address %p : $Builtin.RawPointer to [strict] $*Int
+  %dep = mark_dependence %adr : $*Int on %o : $Optional<AnyObject>
+  %access = begin_access [modify] [static] %dep : $*Int
+  %f = function_ref @takeInoutInt : $@convention(thin) (@inout Int) -> ()
+  %call = apply %f(%access) : $@convention(thin) (@inout Int) -> ()
+  end_access %access : $*Int
+  %v = tuple ()
+  return %v : $()
+}