Merge pull request #15040 from ikesyo/gardening-not-empty

[gardening] Use `!empty()` over `size() > 0`
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 96c7f80..99a927d 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -396,7 +396,7 @@
   type-list ::= empty-list
 
                                                   // FIXME: Consider replacing 'h' with a two-char code
-  list-type ::= type identifier? 'z'? 'h'? 'd'?   // type with optional label, inout convention, shared convention, and variadic specifier
+  list-type ::= type identifier? 'z'? 'h'? 'n'? 'd'?   // type with optional label, inout convention, shared convention, owned convention, and variadic specifier
 
   METATYPE-REPR ::= 't'                      // Thin metatype representation
   METATYPE-REPR ::= 'T'                      // Thick metatype representation
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index eb400b9..3226c5e 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -644,11 +644,7 @@
 
 template <typename int_type>
 class TargetParameterTypeFlags {
-  enum : int_type {
-    InOutMask    = 1 << 0,
-    SharedMask   = 1 << 1,
-    VariadicMask = 1 << 2,
-  };
+  enum : int_type { ValueOwnershipMask = 0x7F, VariadicMask = 0x80 };
   int_type Data;
 
   constexpr TargetParameterTypeFlags(int_type Data) : Data(Data) {}
@@ -656,14 +652,10 @@
 public:
   constexpr TargetParameterTypeFlags() : Data(0) {}
 
-  constexpr TargetParameterTypeFlags<int_type> withInOut(bool isInOut) const {
-    return TargetParameterTypeFlags<int_type>((Data & ~InOutMask) |
-                                              (isInOut ? InOutMask : 0));
-  }
-
-  constexpr TargetParameterTypeFlags<int_type> withShared(bool isShared) const {
-    return TargetParameterTypeFlags<int_type>((Data & ~SharedMask) |
-                                              (isShared ? SharedMask : 0));
+  constexpr TargetParameterTypeFlags<int_type>
+  withValueOwnership(ValueOwnership ownership) const {
+    return TargetParameterTypeFlags<int_type>((Data & ~ValueOwnershipMask) |
+                                              (int_type)ownership);
   }
 
   constexpr TargetParameterTypeFlags<int_type>
@@ -673,10 +665,12 @@
   }
 
   bool isNone() const { return Data == 0; }
-  bool isInOut() const { return Data & InOutMask; }
-  bool isShared() const { return Data & SharedMask; }
   bool isVariadic() const { return Data & VariadicMask; }
 
+  ValueOwnership getValueOwnership() const {
+    return (ValueOwnership)(Data & ValueOwnershipMask);
+  }
+
   int_type getIntValue() const { return Data; }
 
   static TargetParameterTypeFlags<int_type> fromIntValue(int_type Data) {
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index c974d92..938f651 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -316,14 +316,14 @@
     StorageKind : 4
   );
 
-  SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+2+1+1+1,
+  SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+4+1+1+1,
     /// \brief Whether this property is a type property (currently unfortunately
     /// called 'static').
     IsStatic : 1,
 
     /// \brief The specifier associated with this variable or parameter.  This
     /// determines the storage semantics of the value e.g. mutability.
-    Specifier : 2,
+    Specifier : 4,
 
     /// \brief Whether this declaration was an element of a capture list.
     IsCaptureList : 1,
@@ -4445,17 +4445,18 @@
 public:
   enum class Specifier : uint8_t {
     // For Var Decls
-    
-    Let  = 0,
-    Var  = 1,
-    
+
+    Let = 0,
+    Var = 1,
+
     // For Param Decls
-    
-    Owned  = Let,
+
+    Default = Let,
     InOut = 2,
     Shared = 3,
+    Owned = 4,
   };
-  
+
 protected:
   llvm::PointerUnion<PatternBindingDecl*, Stmt*> ParentPattern;
 
@@ -4602,10 +4603,23 @@
   /// \returns the way 'static'/'class' should be spelled for this declaration.
   StaticSpellingKind getCorrectStaticSpelling() const;
 
+  bool isImmutable() const {
+    switch (getSpecifier()) {
+    case Specifier::Let:
+    case Specifier::Shared:
+    case Specifier::Owned:
+      return true;
+    case Specifier::Var:
+    case Specifier::InOut:
+      return false;
+    }
+  }
   /// Is this an immutable 'let' property?
   bool isLet() const { return getSpecifier() == Specifier::Let; }
   /// Is this an immutable 'shared' property?
   bool isShared() const { return getSpecifier() == Specifier::Shared; }
+  /// Is this an immutable 'owned' property?
+  bool isOwned() const { return getSpecifier() == Specifier::Owned; }
 
   ValueOwnership getValueOwnership() const {
     switch (getSpecifier()) {
@@ -4617,6 +4631,8 @@
       return ValueOwnership::InOut;
     case Specifier::Shared:
       return ValueOwnership::Shared;
+    case Specifier::Owned:
+      return ValueOwnership::Owned;
     }
   }
 
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index c176e11..52d3320 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -855,8 +855,8 @@
       "only a single variadic parameter '...' is permitted", ())
 ERROR(parameter_vararg_default,none,
       "variadic parameter cannot have a default value", ())
-ERROR(inout_as_attr_disallowed,none,
-      "%0 before a parameter name is not allowed, place it before the parameter type instead",
+ERROR(parameter_specifier_as_attr_disallowed,none,
+      "'%0' before a parameter name is not allowed, place it before the parameter type instead",
       (StringRef))
 ERROR(parameter_specifier_repeated,none,
       "parameter must not have multiple '__owned', 'inout', '__shared',"
diff --git a/include/swift/AST/Ownership.h b/include/swift/AST/Ownership.h
index 2d8f3de..a3dbfe5 100644
--- a/include/swift/AST/Ownership.h
+++ b/include/swift/AST/Ownership.h
@@ -42,12 +42,15 @@
 
 /// Different kinds of value ownership supported by Swift.
 enum class ValueOwnership : uint8_t {
-  /// \brief the default ownership (owned)
+  /// \brief the context-dependent default ownership (sometimes shared,
+  /// sometimes owned)
   Default,
   /// \brief an 'inout' mutating pointer-like value
   InOut,
   /// \brief a '__shared' non-mutating pointer-like value
-  Shared
+  Shared,
+  /// \brief an '__owned' value
+  Owned
 };
 
 } // end namespace swift
diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h
index 0d6c6b0..b731336 100644
--- a/include/swift/AST/TypeRepr.h
+++ b/include/swift/AST/TypeRepr.h
@@ -901,8 +901,9 @@
   SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
   
   static bool classof(const TypeRepr *T) {
-    return T->getKind() == TypeReprKind::InOut
-        || T->getKind() == TypeReprKind::Shared;
+    return T->getKind() == TypeReprKind::InOut ||
+           T->getKind() == TypeReprKind::Shared ||
+           T->getKind() == TypeReprKind::Owned;
   }
   static bool classof(const SpecifierTypeRepr *T) { return true; }
   
@@ -943,6 +944,20 @@
   static bool classof(const SharedTypeRepr *T) { return true; }
 };
 
+/// \brief A 'owned' type.
+/// \code
+///   x : owned Int
+/// \endcode
+class OwnedTypeRepr : public SpecifierTypeRepr {
+public:
+  OwnedTypeRepr(TypeRepr *Base, SourceLoc OwnedLoc)
+      : SpecifierTypeRepr(TypeReprKind::Owned, Base, OwnedLoc) {}
+
+  static bool classof(const TypeRepr *T) {
+    return T->getKind() == TypeReprKind::Owned;
+  }
+  static bool classof(const OwnedTypeRepr *T) { return true; }
+};
 
 /// \brief A TypeRepr for a known, fixed type.
 ///
@@ -1080,6 +1095,7 @@
   case TypeReprKind::Array:
   case TypeReprKind::SILBox:
   case TypeReprKind::Shared:
+  case TypeReprKind::Owned:
     return true;
   }
   llvm_unreachable("bad TypeRepr kind");
diff --git a/include/swift/AST/TypeReprNodes.def b/include/swift/AST/TypeReprNodes.def
index a664e4c..f5ebe09 100644
--- a/include/swift/AST/TypeReprNodes.def
+++ b/include/swift/AST/TypeReprNodes.def
@@ -56,6 +56,7 @@
 ABSTRACT_TYPEREPR(Specifier, TypeRepr)
   TYPEREPR(InOut, SpecifierTypeRepr)
   TYPEREPR(Shared, SpecifierTypeRepr)
+  TYPEREPR(Owned, SpecifierTypeRepr)
 TYPEREPR(Fixed, TypeRepr)
 TYPEREPR(SILBox, TypeRepr)
 LAST_TYPEREPR(SILBox)
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 4b5324b..b57ee74 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -1580,8 +1580,9 @@
     Escaping    = 1 << 2,
     InOut       = 1 << 3,
     Shared      = 1 << 4,
+    Owned       = 1 << 5,
 
-    NumBits = 5
+    NumBits = 6
   };
   OptionSet<ParameterFlags> value;
   static_assert(NumBits < 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
@@ -1599,7 +1600,8 @@
       : value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
               (escaping ? Escaping : 0) |
               (ownership == ValueOwnership::InOut ? InOut : 0) |
-              (ownership == ValueOwnership::Shared ? Shared : 0)) {}
+              (ownership == ValueOwnership::Shared ? Shared : 0) |
+              (ownership == ValueOwnership::Owned ? Owned : 0)) {}
 
   /// Create one from what's present in the parameter type
   inline static ParameterTypeFlags
@@ -1611,12 +1613,15 @@
   bool isEscaping() const { return value.contains(Escaping); }
   bool isInOut() const { return value.contains(InOut); }
   bool isShared() const { return value.contains(Shared); }
+  bool isOwned() const { return value.contains(Owned); }
 
   ValueOwnership getValueOwnership() const {
     if (isInOut())
       return ValueOwnership::InOut;
     else if (isShared())
       return ValueOwnership::Shared;
+    else if (isOwned())
+      return ValueOwnership::Owned;
 
     return ValueOwnership::Default;
   }
@@ -1641,6 +1646,11 @@
                                        : value - ParameterTypeFlags::Shared);
   }
 
+  ParameterTypeFlags withOwned(bool isOwned) const {
+    return ParameterTypeFlags(isOwned ? value | ParameterTypeFlags::Owned
+                                      : value - ParameterTypeFlags::Owned);
+  }
+
   bool operator ==(const ParameterTypeFlags &other) const {
     return value.toRaw() == other.value.toRaw();
   }
@@ -2530,6 +2540,9 @@
     
     /// Whether the parameter is marked 'shared'
     bool isShared() const { return Flags.isShared(); }
+
+    /// Whether the parameter is marked 'owned'
+    bool isOwned() const { return Flags.isOwned(); }
   };
 
   class CanParam : public Param {
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index 845b16d..d209d38 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -150,6 +150,7 @@
 NODE(RetroactiveConformance)
 NODE(ReturnType)
 NODE(Shared)
+NODE(Owned)
 NODE(SILBoxType)
 NODE(SILBoxTypeWithLayout)
 NODE(SILBoxLayout)
diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h
index d2bd7dd..a98fab4 100644
--- a/include/swift/Demangling/TypeDecoder.h
+++ b/include/swift/Demangling/TypeDecoder.h
@@ -56,8 +56,9 @@
   void setType(BuiltType type) { Type = type; }
 
   void setVariadic() { Flags = Flags.withVariadic(true); }
-  void setShared() { Flags = Flags.withShared(true); }
-  void setInOut() { Flags = Flags.withInOut(true); }
+  void setValueOwnership(ValueOwnership ownership) {
+    Flags = Flags.withValueOwnership(ownership);
+  }
   void setFlags(ParameterFlags flags) { Flags = flags; };
 
   FunctionParam withLabel(StringRef label) const {
@@ -531,17 +532,23 @@
         [&](const Demangle::NodePointer &typeNode,
             FunctionParam<BuiltType> &param) -> bool {
       Demangle::NodePointer node = typeNode;
-      switch (node->getKind()) {
-      case NodeKind::InOut:
-        param.setInOut();
+
+      auto setOwnership = [&](ValueOwnership ownership) {
+        param.setValueOwnership(ownership);
         node = node->getFirstChild();
         hasParamFlags = true;
+      };
+      switch (node->getKind()) {
+      case NodeKind::InOut:
+        setOwnership(ValueOwnership::InOut);
         break;
 
       case NodeKind::Shared:
-        param.setShared();
-        hasParamFlags = true;
-        node = node->getFirstChild();
+        setOwnership(ValueOwnership::Shared);
+        break;
+
+      case NodeKind::Owned:
+        setOwnership(ValueOwnership::Owned);
         break;
 
       default:
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index 3a9550f..90b544c 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -64,8 +64,8 @@
 class Lexer {
   const LangOptions &LangOpts;
   const SourceManager &SourceMgr;
-  DiagnosticEngine *Diags;
   const unsigned BufferID;
+  DiagnosticEngine *Diags;
 
   using State = LexerState;
 
@@ -137,20 +137,18 @@
   Lexer(const Lexer&) = delete;
   void operator=(const Lexer&) = delete;
 
+  struct PrincipalTag {};
+
   /// The principal constructor used by public constructors below.
   /// Don't use this constructor for other purposes, it does not initialize
   /// everything.
-  Lexer(const LangOptions &Options,
-        const SourceManager &SourceMgr, DiagnosticEngine *Diags,
-        unsigned BufferID, bool InSILMode,
+  Lexer(const PrincipalTag &, const LangOptions &LangOpts,
+        const SourceManager &SourceMgr, unsigned BufferID,
+        DiagnosticEngine *Diags, bool InSILMode,
         CommentRetentionMode RetainComments,
         TriviaRetentionMode TriviaRetention);
 
-  /// @{
-  /// Helper routines used in \c Lexer constructors.
-  void primeLexer();
-  void initSubLexer(Lexer &Parent, State BeginState, State EndState);
-  /// @}
+  void initialize(unsigned Offset, unsigned EndOffset);
 
 public:
   /// \brief Create a normal lexer that scans the whole source buffer.
@@ -166,31 +164,18 @@
   ///   means that APIs like getLocForEndOfToken really ought to take
   ///   this flag; it's just that we don't care that much about fidelity
   ///   when parsing SIL files.
-  Lexer(const LangOptions &Options,
-        const SourceManager &SourceMgr, unsigned BufferID,
-        DiagnosticEngine *Diags, bool InSILMode,
-        CommentRetentionMode RetainComments = CommentRetentionMode::None,
-        TriviaRetentionMode TriviaRetention = TriviaRetentionMode::WithoutTrivia)
-      : Lexer(Options, SourceMgr, Diags, BufferID, InSILMode, RetainComments,
-              TriviaRetention) {
-    primeLexer();
-  }
+  Lexer(
+      const LangOptions &Options, const SourceManager &SourceMgr,
+      unsigned BufferID, DiagnosticEngine *Diags, bool InSILMode,
+      CommentRetentionMode RetainComments = CommentRetentionMode::None,
+      TriviaRetentionMode TriviaRetention = TriviaRetentionMode::WithoutTrivia);
 
   /// \brief Create a lexer that scans a subrange of the source buffer.
-  Lexer(const LangOptions &Options,
-        const SourceManager &SourceMgr, unsigned BufferID,
-        DiagnosticEngine *Diags, bool InSILMode,
+  Lexer(const LangOptions &Options, const SourceManager &SourceMgr,
+        unsigned BufferID, DiagnosticEngine *Diags, bool InSILMode,
         CommentRetentionMode RetainComments,
-        TriviaRetentionMode TriviaRetention,
-        unsigned Offset, unsigned EndOffset)
-      : Lexer(Options, SourceMgr, Diags, BufferID, InSILMode, RetainComments,
-              TriviaRetention) {
-    assert(Offset <= EndOffset && "invalid range");
-    initSubLexer(
-        *this,
-        State(getLocForStartOfBuffer().getAdvancedLoc(Offset)),
-        State(getLocForStartOfBuffer().getAdvancedLoc(EndOffset)));
-  }
+        TriviaRetentionMode TriviaRetention, unsigned Offset,
+        unsigned EndOffset);
 
   /// \brief Create a sub-lexer that lexes from the same buffer, but scans
   /// a subrange of the buffer.
@@ -198,12 +183,7 @@
   /// \param Parent the parent lexer that scans the whole buffer
   /// \param BeginState start of the subrange
   /// \param EndState end of the subrange
-  Lexer(Lexer &Parent, State BeginState, State EndState)
-      : Lexer(Parent.LangOpts, Parent.SourceMgr, Parent.Diags, Parent.BufferID,
-              Parent.InSILMode, Parent.RetainComments,
-              Parent.TriviaRetention) {
-    initSubLexer(Parent, BeginState, EndState);
-  }
+  Lexer(Lexer &Parent, State BeginState, State EndState);
 
   /// \brief Returns true if this lexer will produce a code completion token.
   bool isCodeCompletion() const {
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 599aec4..9759253 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -1005,7 +1005,7 @@
     SourceLoc SpecifierLoc;
     
     /// The parsed specifier kind, if present.
-    VarDecl::Specifier SpecifierKind = VarDecl::Specifier::Owned;
+    VarDecl::Specifier SpecifierKind = VarDecl::Specifier::Default;
 
     /// The location of the first name.
     ///
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 914a7f6..3c85170 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -2353,9 +2353,6 @@
       Indices(indices),
       IndexEquality{indicesEqual, indicesHash},
       ComponentType(ComponentType) {
-    assert(indices.empty() == !indicesEqual
-           && indices.empty() == !indicesHash
-           && "must have equals/hash functions iff there are indices");
   }
   
   KeyPathPatternComponent(AbstractStorageDecl *externalStorage,
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 7cd3c72..aada1b9 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -210,9 +210,10 @@
   Var,
   InOut,
   Shared,
+  Owned,
 };
-using VarDeclSpecifierField = BCFixed<2>;
-  
+using VarDeclSpecifierField = BCFixed<3>;
+
 // These IDs must \em not be renumbered or reordered without incrementing
 // VERSION_MAJOR.
 enum class ParameterConvention : uint8_t {
@@ -325,6 +326,7 @@
   Default = 0,
   InOut,
   Shared,
+  Owned
 };
 using ValueOwnershipField = BCFixed<2>;
 
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 88d4d15..f493842 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -950,12 +950,23 @@
         PrintWithColorRAII(OS, InterfaceTypeColor) << "'";
       }
 
-      if (P->getSpecifier() == VarDecl::Specifier::Var)
+      switch (P->getSpecifier()) {
+      case VarDecl::Specifier::Let:
+        /* nothing */
+        break;
+      case VarDecl::Specifier::Var:
         OS << " mutable";
-      if (P->getSpecifier() == VarDecl::Specifier::InOut)
+        break;
+      case VarDecl::Specifier::InOut:
         OS << " inout";
-      if (P->isShared())
+        break;
+      case VarDecl::Specifier::Shared:
         OS << " shared";
+        break;
+      case VarDecl::Specifier::Owned:
+        OS << " owned";
+        break;
+      }
 
       if (P->isVariadic())
         OS << " variadic";
@@ -2750,6 +2761,12 @@
     printRec(T->getBase());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
+
+  void visitOwnedTypeRepr(OwnedTypeRepr *T) {
+    printCommon("type_owned") << '\n';
+    printRec(T->getBase());
+    PrintWithColorRAII(OS, ParenthesisColor) << ')';
+  }
 };
 
 } // end anonymous namespace
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 1c00e72..ddc5cc7 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -1724,10 +1724,20 @@
 void ASTMangler::appendTypeListElement(Identifier name, Type elementType,
                                        ParameterTypeFlags flags) {
   appendType(elementType->getInOutObjectType());
-  if (flags.isInOut())
+  switch (flags.getValueOwnership()) {
+  case ValueOwnership::Default:
+    /* nothing */
+    break;
+  case ValueOwnership::InOut:
     appendOperator("z");
-  if (flags.isShared())
+    break;
+  case ValueOwnership::Shared:
     appendOperator("h");
+    break;
+  case ValueOwnership::Owned:
+    appendOperator("n");
+    break;
+  }
   if (!name.empty())
     appendIdentifier(name.str());
   if (flags.isVariadic())
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 1035c66..569745e 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -2132,8 +2132,21 @@
     printer << "@autoclosure ";
   if (!options.excludeAttrKind(TAK_escaping) && flags.isEscaping())
     printer << "@escaping ";
-  if (flags.isShared())
+
+  switch (flags.getValueOwnership()) {
+  case ValueOwnership::Default:
+    /* nothing */
+    break;
+  case ValueOwnership::InOut:
+    /* handled as part of an InOutType */
+    break;
+  case ValueOwnership::Shared:
     printer << "__shared ";
+    break;
+  case ValueOwnership::Owned:
+    printer << "__owned ";
+    break;
+  }
 }
 
 void PrintAST::visitVarDecl(VarDecl *decl) {
@@ -2154,14 +2167,15 @@
       // Map all non-let specifiers to 'var'.  This is not correct, but
       // SourceKit relies on this for info about parameter decls.
       switch (decl->getSpecifier()) {
-        case VarDecl::Specifier::Owned:
-          Printer << tok::kw_let;
-          break;
-        case VarDecl::Specifier::Var:
-        case VarDecl::Specifier::InOut:
-        case VarDecl::Specifier::Shared:
-          Printer << tok::kw_var;
-          break;
+      case VarDecl::Specifier::Let:
+        Printer << tok::kw_let;
+        break;
+      case VarDecl::Specifier::Var:
+      case VarDecl::Specifier::InOut:
+      case VarDecl::Specifier::Shared:
+      case VarDecl::Specifier::Owned:
+        Printer << tok::kw_var;
+        break;
       }
       Printer << " ";
     }
diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp
index e2ff5ae..49ac696 100644
--- a/lib/AST/ASTWalker.cpp
+++ b/lib/AST/ASTWalker.cpp
@@ -1697,6 +1697,10 @@
   return doIt(T->getBase());
 }
 
+bool Traversal::visitOwnedTypeRepr(OwnedTypeRepr *T) {
+  return doIt(T->getBase());
+}
+
 bool Traversal::visitFixedTypeRepr(FixedTypeRepr *T) {
   return false;
 }
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 875a932..6d2a220 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -160,10 +160,9 @@
 
   SmallVector<ParamDecl*, 4> params;
   for (Type argType : argTypes) {
-    auto PD = new (Context) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
-                                      Identifier(), SourceLoc(),
-                                      Identifier(), argType,
-                                      DC);
+    auto PD = new (Context)
+        ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                  Identifier(), SourceLoc(), Identifier(), argType, DC);
     PD->setInterfaceType(argType);
     PD->setValidationStarted();
     PD->setImplicit();
@@ -221,8 +220,8 @@
     auto paramType = ArgBodyTypes[i];
     auto paramIfaceType = ArgParamTypes[i].getType();
     auto specifier = (ArgParamTypes[i].getParameterFlags().isInOut())
-                   ? VarDecl::Specifier::InOut
-                   : VarDecl::Specifier::Owned;
+                         ? VarDecl::Specifier::InOut
+                         : VarDecl::Specifier::Default;
     auto PD = new (Context) ParamDecl(specifier,
                                       SourceLoc(), SourceLoc(),
                                       Identifier(), SourceLoc(),
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1c59fda..69cebce 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -4047,7 +4047,7 @@
                          const DeclRefExpr *base) const {
   // If this is a 'var' decl, then we're settable if we have storage or a
   // setter.
-  if (!isLet() && !isShared())
+  if (!isImmutable())
     return ::isSettable(this);
 
   // If the decl has a value bound to it but has no PBD, then it is
@@ -4377,8 +4377,9 @@
 /// generic parameters.
 ParamDecl *ParamDecl::createUnboundSelf(SourceLoc loc, DeclContext *DC) {
   ASTContext &C = DC->getASTContext();
-  auto *selfDecl = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
-                                     Identifier(), loc, C.Id_self, Type(), DC);
+  auto *selfDecl =
+      new (C) ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                        Identifier(), loc, C.Id_self, Type(), DC);
   selfDecl->setImplicit();
   return selfDecl;
 }
@@ -4396,7 +4397,7 @@
                                  bool isStaticMethod, bool isInOut) {
   ASTContext &C = DC->getASTContext();
   auto selfInterfaceType = DC->getSelfInterfaceType();
-  auto specifier = VarDecl::Specifier::Owned;
+  auto specifier = VarDecl::Specifier::Default;
   assert(selfInterfaceType);
 
   if (isStaticMethod) {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 5e5c65e..d9cb741 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1020,8 +1020,11 @@
     return inputType;
 
   auto flags = ParameterTypeFlags().withInOut(inputType->is<InOutType>());
-  if (auto *parenTy = dyn_cast<ParenType>(origInputType.getPointer()))
-    flags = flags.withShared(parenTy->getParameterFlags().isShared());
+  if (auto *parenTy = dyn_cast<ParenType>(origInputType.getPointer())) {
+    auto parenFlags = parenTy->getParameterFlags();
+    flags =
+        flags.withShared(parenFlags.isShared()).withOwned(parenFlags.isOwned());
+  }
 
   inputType = ParenType::get(inputType->getASTContext(),
                              inputType->getInOutObjectType(), flags);
diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp
index 7ff0d50..f848364 100644
--- a/lib/AST/TypeRepr.cpp
+++ b/lib/AST/TypeRepr.cpp
@@ -224,6 +224,10 @@
   return new (Ctx) SharedTypeRepr(visit(T->getBase()), T->getSpecifierLoc());
 }
 
+TypeRepr *CloneVisitor::visitOwnedTypeRepr(OwnedTypeRepr *T) {
+  return new (Ctx) OwnedTypeRepr(visit(T->getBase()), T->getSpecifierLoc());
+}
+
 TypeRepr *CloneVisitor::visitFixedTypeRepr(FixedTypeRepr *T) {
   return new (Ctx) FixedTypeRepr(T->getType(), T->getLoc());
 }
@@ -557,11 +561,19 @@
 
 void SpecifierTypeRepr::printImpl(ASTPrinter &Printer,
                                   const PrintOptions &Opts) const {
-  if (getKind() == TypeReprKind::InOut) {
+  switch (getKind()) {
+  case TypeReprKind::InOut:
     Printer.printKeyword("inout");
-  } else {
-    assert((getKind() == TypeReprKind::Shared) && "Unknown kind");
+    break;
+  case TypeReprKind::Shared:
     Printer.printKeyword("shared");
+    break;
+  case TypeReprKind::Owned:
+    Printer.printKeyword("owned");
+    break;
+  default:
+    llvm_unreachable("unknown specifier type repr");
+    break;
   }
   Printer << " ";
   printTypeRepr(Base, Printer, Opts);
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index 53d526a..146bee5 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -172,25 +172,25 @@
   // Set the "os" platform condition.
   if (Target.isMacOSX())
     addPlatformConditionValue(PlatformConditionKind::OS, "OSX");
-  else if (triple.isTvOS())
+  else if (Target.isTvOS())
     addPlatformConditionValue(PlatformConditionKind::OS, "tvOS");
-  else if (triple.isWatchOS())
+  else if (Target.isWatchOS())
     addPlatformConditionValue(PlatformConditionKind::OS, "watchOS");
-  else if (triple.isiOS())
+  else if (Target.isiOS())
     addPlatformConditionValue(PlatformConditionKind::OS, "iOS");
-  else if (triple.isAndroid())
+  else if (Target.isAndroid())
     addPlatformConditionValue(PlatformConditionKind::OS, "Android");
-  else if (triple.isOSLinux())
+  else if (Target.isOSLinux())
     addPlatformConditionValue(PlatformConditionKind::OS, "Linux");
-  else if (triple.isOSFreeBSD())
+  else if (Target.isOSFreeBSD())
     addPlatformConditionValue(PlatformConditionKind::OS, "FreeBSD");
-  else if (triple.isOSWindows())
+  else if (Target.isOSWindows())
     addPlatformConditionValue(PlatformConditionKind::OS, "Windows");
-  else if (triple.isWindowsCygwinEnvironment())
+  else if (Target.isWindowsCygwinEnvironment())
     addPlatformConditionValue(PlatformConditionKind::OS, "Cygwin");
-  else if (triple.isPS4())
+  else if (Target.isPS4())
     addPlatformConditionValue(PlatformConditionKind::OS, "PS4");
-  else if (triple.isOSHaiku())
+  else if (Target.isOSHaiku())
     addPlatformConditionValue(PlatformConditionKind::OS, "Haiku");
   else
     UnsupportedOS = true;
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index d02ea72..9f022db 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -434,7 +434,7 @@
   auto selfDecl = ParamDecl::createSelf(SourceLoc(), enumDecl,
                                         /*static*/false, /*inout*/true);
 
-  auto param = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
+  auto param = new (C) ParamDecl(VarDecl::Specifier::Default, SourceLoc(),
                                  SourceLoc(), C.Id_rawValue,
                                  SourceLoc(), C.Id_rawValue,
                                  rawTy,
@@ -708,7 +708,7 @@
   auto &C = Impl.SwiftContext;
   auto selfDecl = ParamDecl::createSelf(SourceLoc(), importedDecl,
                                         /*isStatic*/false, /*isInOut*/true);
-  auto newValueDecl = new (C) ParamDecl(VarDecl::Specifier::Owned,
+  auto newValueDecl = new (C) ParamDecl(VarDecl::Specifier::Default,
                                         SourceLoc(), SourceLoc(),
                                         Identifier(), SourceLoc(), C.Id_value,
                                         importedFieldDecl->getType(),
@@ -1267,7 +1267,7 @@
 
     Identifier argName = generateParamName ? var->getName() : Identifier();
     auto param = new (context)
-        ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(), argName,
+        ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), argName,
                   SourceLoc(), var->getName(), var->getType(), structDecl);
     param->setInterfaceType(var->getInterfaceType());
     param->setValidationStarted();
@@ -1689,7 +1689,7 @@
   auto elementTy = dc->mapTypeIntoContext(elementInterfaceTy);
 
   auto paramVarDecl =
-      new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
+      new (C) ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
                         Identifier(), loc, valueIndex->get(0)->getName(),
                         elementTy, dc);
   paramVarDecl->setInterfaceType(elementInterfaceTy);
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index 2b53fc0..c1b09ad 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -1660,7 +1660,7 @@
     // imported header unit.
     auto paramInfo = createDeclWithClangNode<ParamDecl>(
         param, AccessLevel::Private,
-        VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(), name,
+        VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), name,
         importSourceLoc(param->getLocation()), bodyName,
         dc->mapTypeIntoContext(swiftParamTy),
         ImportedHeaderUnit);
@@ -1678,7 +1678,7 @@
         BoundGenericType::get(SwiftContext.getArrayDecl(), Type(),
                               {SwiftContext.TheAnyType});
     auto name = SwiftContext.getIdentifier("varargs");
-    auto param = new (SwiftContext) ParamDecl(VarDecl::Specifier::Owned,
+    auto param = new (SwiftContext) ParamDecl(VarDecl::Specifier::Default,
                                               SourceLoc(), SourceLoc(),
                                               Identifier(), SourceLoc(),
                                               name, paramTy,
@@ -1979,7 +1979,7 @@
     // It doesn't actually matter which DeclContext we use, so just
     // use the imported header unit.
     auto type = TupleType::getEmpty(SwiftContext);
-    auto var = new (SwiftContext) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
+    auto var = new (SwiftContext) ParamDecl(VarDecl::Specifier::Default, SourceLoc(),
                                             SourceLoc(), argName,
                                             SourceLoc(), argName, type,
                                             ImportedHeaderUnit);
@@ -2105,7 +2105,7 @@
     // Set up the parameter info.
     auto paramInfo
       = createDeclWithClangNode<ParamDecl>(param, AccessLevel::Private,
-                                           VarDecl::Specifier::Owned,
+                                           VarDecl::Specifier::Default,
                                            SourceLoc(), SourceLoc(), name,
                                            importSourceLoc(param->getLocation()),
                                            bodyName,
@@ -2225,7 +2225,7 @@
     Identifier argLabel = functionName.getDeclName().getArgumentNames().front();
     auto paramInfo
       = createDeclWithClangNode<ParamDecl>(param, AccessLevel::Private,
-                                           VarDecl::Specifier::Owned,
+                                           VarDecl::Specifier::Default,
                                            /*let loc*/SourceLoc(),
                                            /*label loc*/SourceLoc(),
                                            argLabel, nameLoc, bodyName,
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index ea4ec7a..ae82735 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -596,6 +596,9 @@
     case 'l': return demangleGenericSignature(/*hasParamCounts*/ false);
     case 'm': return createType(createWithChild(Node::Kind::Metatype,
                                                 popNode(Node::Kind::Type)));
+    case 'n':
+      return createType(
+          createWithChild(Node::Kind::Owned, popTypeAndGetChild()));
     case 'o': return demangleOperatorIdentifier();
     case 'p': return demangleProtocolListType();
     case 'q': return createType(demangleGenericParamIndex());
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index ed38fc1..f1620f7 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -386,6 +386,7 @@
     case Node::Kind::Number:
     case Node::Kind::ObjCAttribute:
     case Node::Kind::ObjCBlock:
+    case Node::Kind::Owned:
     case Node::Kind::OwningAddressor:
     case Node::Kind::OwningMutableAddressor:
     case Node::Kind::PartialApplyForwarder:
@@ -1128,6 +1129,10 @@
     Printer << "__shared ";
     print(Node->getChild(0));
     return nullptr;
+  case Node::Kind::Owned:
+    Printer << "__owned ";
+    print(Node->getChild(0));
+    return nullptr;
   case Node::Kind::NonObjCAttribute:
     Printer << "@nonobjc ";
     return nullptr;
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index 95c0f61..a5c3cfb 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -1470,6 +1470,11 @@
   mangleSingleChildNode(node); // type
 }
 
+void Remangler::mangleOwned(Node *node) {
+  Out << 'n';
+  mangleSingleChildNode(node); // type
+}
+
 void Remangler::mangleInOut(Node *node) {
   Out << 'R';
   mangleSingleChildNode(node); // type
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index 991cb29..0090b6b 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -1307,6 +1307,11 @@
   Buffer << 'h';
 }
 
+void Remangler::mangleOwned(Node *node) {
+  mangleSingleChildNode(node);
+  Buffer << 'n';
+}
+
 void Remangler::mangleInfixOperator(Node *node) {
   mangleIdentifierImpl(node, /*isOperator*/ true);
   Buffer << "oi";
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index b83b771..041886c 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -512,22 +512,22 @@
                                  const SILModule& Module) {
   auto &C = Stats.getFrontendCounters();
   // FIXME: calculate these in constant time, via the dense maps.
-  C.NumSILGenFunctions = Module.getFunctionList().size();
-  C.NumSILGenVtables = Module.getVTableList().size();
-  C.NumSILGenWitnessTables = Module.getWitnessTableList().size();
-  C.NumSILGenDefaultWitnessTables = Module.getDefaultWitnessTableList().size();
-  C.NumSILGenGlobalVariables = Module.getSILGlobalList().size();
+  C.NumSILGenFunctions += Module.getFunctionList().size();
+  C.NumSILGenVtables += Module.getVTableList().size();
+  C.NumSILGenWitnessTables += Module.getWitnessTableList().size();
+  C.NumSILGenDefaultWitnessTables += Module.getDefaultWitnessTableList().size();
+  C.NumSILGenGlobalVariables += Module.getSILGlobalList().size();
 }
 
 static void countStatsPostSILOpt(UnifiedStatsReporter &Stats,
                                  const SILModule& Module) {
   auto &C = Stats.getFrontendCounters();
   // FIXME: calculate these in constant time, via the dense maps.
-  C.NumSILOptFunctions = Module.getFunctionList().size();
-  C.NumSILOptVtables = Module.getVTableList().size();
-  C.NumSILOptWitnessTables = Module.getWitnessTableList().size();
-  C.NumSILOptDefaultWitnessTables = Module.getDefaultWitnessTableList().size();
-  C.NumSILOptGlobalVariables = Module.getSILGlobalList().size();
+  C.NumSILOptFunctions += Module.getFunctionList().size();
+  C.NumSILOptVtables += Module.getVTableList().size();
+  C.NumSILOptWitnessTables += Module.getWitnessTableList().size();
+  C.NumSILOptDefaultWitnessTables += Module.getDefaultWitnessTableList().size();
+  C.NumSILOptGlobalVariables += Module.getSILGlobalList().size();
 }
 
 static std::unique_ptr<llvm::raw_fd_ostream>
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 34c67cc..3ed7bce 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -838,10 +838,10 @@
               auto param = params[index];
               auto flags = param.getParameterFlags();
 
-              auto parameterFlags = ParameterFlags()
-                                        .withInOut(flags.isInOut())
-                                        .withShared(flags.isShared())
-                                        .withVariadic(flags.isVariadic());
+              auto parameterFlags =
+                  ParameterFlags()
+                      .withValueOwnership(flags.getValueOwnership())
+                      .withVariadic(flags.isVariadic());
 
               processor(index, getFunctionParameterRef(param), parameterFlags);
             }
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index 79f4b6d..e886b90 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -160,6 +160,10 @@
     return visit(T->getBase());
   }
 
+  FoundResult visitOwnedTypeRepr(OwnedTypeRepr *T) {
+    return visit(T->getBase());
+  }
+
   FoundResult visitArrayTypeRepr(ArrayTypeRepr *T) {
     return handleParent(T, T->getBase());
   }
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index d18855b..66829cd 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -168,38 +168,44 @@
 // Setup and Helper Methods
 //===----------------------------------------------------------------------===//
 
-Lexer::Lexer(const LangOptions &Options,
-             const SourceManager &SM, DiagnosticEngine *Diags,
-             unsigned BufferID, bool InSILMode,
+Lexer::Lexer(const PrincipalTag &, const LangOptions &LangOpts,
+             const SourceManager &SourceMgr, unsigned BufferID,
+             DiagnosticEngine *Diags, bool InSILMode,
              CommentRetentionMode RetainComments,
              TriviaRetentionMode TriviaRetention)
-    : LangOpts(Options), SourceMgr(SM), Diags(Diags), BufferID(BufferID),
-      InSILMode(InSILMode), RetainComments(RetainComments),
-      TriviaRetention(TriviaRetention) {
+    : LangOpts(LangOpts), SourceMgr(SourceMgr), BufferID(BufferID),
+      Diags(Diags), InSILMode(InSILMode), RetainComments(RetainComments),
+      TriviaRetention(TriviaRetention) {}
+
+void Lexer::initialize(unsigned Offset, unsigned EndOffset) {
+  assert(Offset <= EndOffset);
+
   // Initialize buffer pointers.
-  StringRef contents = SM.extractText(SM.getRangeForBuffer(BufferID));
+  StringRef contents =
+      SourceMgr.extractText(SourceMgr.getRangeForBuffer(BufferID));
   BufferStart = contents.data();
   BufferEnd = contents.data() + contents.size();
+  assert(*BufferEnd == 0);
+  assert(BufferStart + Offset <= BufferEnd);
+  assert(BufferStart + EndOffset <= BufferEnd);
 
   // Check for Unicode BOM at start of file (Only UTF-8 BOM supported now).
-  size_t BOMLength = llvm::StringSwitch<size_t>(contents)
-    .StartsWith("\xEF\xBB\xBF", 3)
-    .Default(0);
+  size_t BOMLength = contents.startswith("\xEF\xBB\xBF") ? 3 : 0;
 
   // Keep information about existance of UTF-8 BOM for transparency source code
   // editing with libSyntax.
-  CurPtr = BufferStart;
   ContentStart = BufferStart + BOMLength;
 
   // Initialize code completion.
-  if (BufferID == SM.getCodeCompletionBufferID()) {
-    const char *Ptr = BufferStart + SM.getCodeCompletionOffset();
+  if (BufferID == SourceMgr.getCodeCompletionBufferID()) {
+    const char *Ptr = BufferStart + SourceMgr.getCodeCompletionOffset();
     if (Ptr >= BufferStart && Ptr <= BufferEnd)
       CodeCompletionPtr = Ptr;
   }
-}
 
-void Lexer::primeLexer() {
+  ArtificialEOF = BufferStart + EndOffset;
+  CurPtr = BufferStart + Offset;
+
   assert(NextToken.is(tok::NUM_TOKENS));
   lexImpl();
   assert((NextToken.isAtStartOfLine() || CurPtr != BufferStart) &&
@@ -207,25 +213,38 @@
          "or we should be lexing from the middle of the buffer");
 }
 
-void Lexer::initSubLexer(Lexer &Parent, State BeginState, State EndState) {
+Lexer::Lexer(const LangOptions &Options, const SourceManager &SourceMgr,
+             unsigned BufferID, DiagnosticEngine *Diags, bool InSILMode,
+             CommentRetentionMode RetainComments,
+             TriviaRetentionMode TriviaRetention)
+    : Lexer(PrincipalTag(), Options, SourceMgr, BufferID, Diags, InSILMode,
+            RetainComments, TriviaRetention) {
+  unsigned EndOffset = SourceMgr.getRangeForBuffer(BufferID).getByteLength();
+  initialize(/*Offset=*/0, EndOffset);
+}
+
+Lexer::Lexer(const LangOptions &Options, const SourceManager &SourceMgr,
+             unsigned BufferID, DiagnosticEngine *Diags, bool InSILMode,
+             CommentRetentionMode RetainComments,
+             TriviaRetentionMode TriviaRetention, unsigned Offset,
+             unsigned EndOffset)
+    : Lexer(PrincipalTag(), Options, SourceMgr, BufferID, Diags, InSILMode,
+            RetainComments, TriviaRetention) {
+  initialize(Offset, EndOffset);
+}
+
+Lexer::Lexer(Lexer &Parent, State BeginState, State EndState)
+    : Lexer(PrincipalTag(), Parent.LangOpts, Parent.SourceMgr, Parent.BufferID,
+            Parent.Diags, Parent.InSILMode, Parent.RetainComments,
+            Parent.TriviaRetention) {
   assert(BufferID == SourceMgr.findBufferContainingLoc(BeginState.Loc) &&
          "state for the wrong buffer");
   assert(BufferID == SourceMgr.findBufferContainingLoc(EndState.Loc) &&
          "state for the wrong buffer");
 
-  // If the parent lexer should stop prematurely, and the ArtificialEOF
-  // position is in this subrange, then we should stop at that point, too.
-  const char *BeginStatePtr = getBufferPtrForSourceLoc(BeginState.Loc);
-  const char *EndStatePtr = getBufferPtrForSourceLoc(EndState.Loc);
-  if (Parent.ArtificialEOF &&
-      Parent.ArtificialEOF >= BeginStatePtr &&
-      Parent.ArtificialEOF <= EndStatePtr) {
-    ArtificialEOF = Parent.ArtificialEOF;
-  } else
-    ArtificialEOF = EndStatePtr;
-
-  primeLexer();
-  restoreState(BeginState);
+  unsigned Offset = SourceMgr.getLocOffsetInBuffer(BeginState.Loc, BufferID);
+  unsigned EndOffset = SourceMgr.getLocOffsetInBuffer(EndState.Loc, BufferID);
+  initialize(Offset, EndOffset);
 }
 
 InFlightDiagnostic Lexer::diagnose(const char *Loc, Diagnostic Diag) {
@@ -255,7 +274,7 @@
   // When we are lexing a subrange from the middle of a file buffer, we will
   // run past the end of the range, but will stay within the file.  Check if
   // we are past the imaginary EOF, and synthesize a tok::eof in this case.
-  if (Kind != tok::eof && ArtificialEOF && TokStart >= ArtificialEOF) {
+  if (Kind != tok::eof && TokStart >= ArtificialEOF) {
     Kind = tok::eof;
   }
   unsigned CommentLength = 0;
@@ -2365,7 +2384,7 @@
 Restart:
   const char *TriviaStart = CurPtr;
 
-  switch (*CurPtr++) {
+  switch ((signed char)*CurPtr++) {
   case '\n':
     if (IsForTrailingTrivia)
       break;
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 84b15c3..e134a65 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1895,7 +1895,7 @@
 bool Parser::parseTypeAttributeListPresent(VarDecl::Specifier &Specifier,
                                            SourceLoc &SpecifierLoc,
                                            TypeAttributes &Attributes) {
-  Specifier = VarDecl::Specifier::Owned;
+  Specifier = VarDecl::Specifier::Default;
   while (Tok.is(tok::kw_inout) ||
          (Tok.is(tok::identifier) &&
           (Tok.getRawText().equals("__shared") ||
@@ -3676,10 +3676,9 @@
     name = P.Context.getIdentifier(implName);
   }
 
-  auto result = new (P.Context) ParamDecl(VarDecl::Specifier::Owned,
-                                          SourceLoc(),SourceLoc(),
-                                          Identifier(), nameLoc, name,
-                                          Type(), P.CurDeclContext);
+  auto result = new (P.Context)
+      ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                Identifier(), nameLoc, name, Type(), P.CurDeclContext);
   if (isNameImplicit)
     result->setImplicit();
 
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 68b673c..cbc527d 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2628,9 +2628,9 @@
 
         Identifier name = Tok.is(tok::identifier) ?
             Context.getIdentifier(Tok.getText()) : Identifier();
-        auto var = new (Context) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
-                                           SourceLoc(), Identifier(),
-                                           Tok.getLoc(), name, Type(), nullptr);
+        auto var = new (Context)
+            ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                      Identifier(), Tok.getLoc(), name, Type(), nullptr);
         elements.push_back(var);
         consumeToken();
 
@@ -2929,9 +2929,9 @@
     StringRef varName = ("$" + Twine(nextIdx)).toStringRef(StrBuf);
     Identifier ident = Context.getIdentifier(varName);
     SourceLoc varLoc = leftBraceLoc;
-    auto *var = new (Context) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),SourceLoc(),
-                                        Identifier(), varLoc, ident, Type(),
-                                        closure);
+    auto *var = new (Context)
+        ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                  Identifier(), varLoc, ident, Type(), closure);
     var->setImplicit();
     decls.push_back(var);
   }
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 70b89d3..3a30a39 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -212,6 +212,12 @@
           // better fixits.
           param.SpecifierKind = VarDecl::Specifier::Shared;
           param.SpecifierLoc = consumeToken();
+        } else if (Tok.is(tok::identifier) &&
+                   Tok.getRawText().equals("__owned")) {
+          // This case is handled later when mapping to ParamDecls for
+          // better fixits.
+          param.SpecifierKind = VarDecl::Specifier::Owned;
+          param.SpecifierLoc = consumeToken();
         } else {
           diagnose(Tok, diag::parameter_let_var_as_attr, Tok.getText())
             .fixItRemove(Tok.getLoc());
@@ -352,6 +358,28 @@
     return status;
   });
 }
+template <typename T>
+static TypeRepr *
+validateParameterWithSpecifier(Parser &parser,
+                               Parser::ParsedParameter &paramInfo,
+                               StringRef specifierName) {
+  auto type = paramInfo.Type;
+  auto loc = paramInfo.SpecifierLoc;
+  if (isa<SpecifierTypeRepr>(type)) {
+    parser.diagnose(loc, diag::parameter_specifier_repeated).fixItRemove(loc);
+  } else {
+    llvm::SmallString<128> replacement(specifierName);
+    replacement += " ";
+    parser
+        .diagnose(loc, diag::parameter_specifier_as_attr_disallowed,
+                  specifierName)
+        .fixItRemove(loc)
+        .fixItInsert(type->getStartLoc(), replacement);
+    type = new (parser.Context) T(type, loc);
+  }
+
+  return type;
+}
 
 /// Map parsed parameters to a ParameterList.
 static ParameterList *
@@ -384,28 +412,14 @@
     if (auto type = paramInfo.Type) {
       // If 'inout' was specified, turn the type into an in-out type.
       if (paramInfo.SpecifierKind == VarDecl::Specifier::InOut) {
-        auto InOutLoc = paramInfo.SpecifierLoc;
-        if (isa<InOutTypeRepr>(type)) {
-          parser.diagnose(InOutLoc, diag::parameter_specifier_repeated)
-            .fixItRemove(InOutLoc);
-        } else {
-          parser.diagnose(InOutLoc, diag::inout_as_attr_disallowed, "'inout'")
-            .fixItRemove(InOutLoc)
-            .fixItInsert(type->getStartLoc(), "inout ");
-          type = new (ctx) InOutTypeRepr(type, InOutLoc);
-        }
+        type = validateParameterWithSpecifier<InOutTypeRepr>(parser, paramInfo,
+                                                             "inout");
       } else if (paramInfo.SpecifierKind == VarDecl::Specifier::Shared) {
-        auto SpecifierLoc = paramInfo.SpecifierLoc;
-        if (isa<SharedTypeRepr>(type)) {
-          parser.diagnose(SpecifierLoc, diag::parameter_specifier_repeated)
-            .fixItRemove(SpecifierLoc);
-        } else {
-          parser.diagnose(SpecifierLoc, diag::inout_as_attr_disallowed,
-                          "'__shared'")
-            .fixItRemove(SpecifierLoc)
-            .fixItInsert(type->getStartLoc(), "__shared ");
-          type = new (ctx) SharedTypeRepr(type, SpecifierLoc);
-        }
+        type = validateParameterWithSpecifier<SharedTypeRepr>(parser, paramInfo,
+                                                              "__shared");
+      } else if (paramInfo.SpecifierKind == VarDecl::Specifier::Owned) {
+        type = validateParameterWithSpecifier<OwnedTypeRepr>(parser, paramInfo,
+                                                             "__owned");
       }
       param->getTypeLoc() = TypeLoc(type);
     } else if (paramContext != Parser::ParameterContextKind::Closure) {
@@ -424,14 +438,18 @@
       case VarDecl::Specifier::Shared:
         specifier = "'shared'";
         break;
+      case VarDecl::Specifier::Owned:
+        specifier = "'owned'";
+        break;
       case VarDecl::Specifier::Let:
       case VarDecl::Specifier::Var:
         llvm_unreachable("can't have let or var here");
+        break;
       }
       parser.diagnose(paramInfo.SpecifierLoc, diag::specifier_must_have_type,
                       specifier);
       paramInfo.SpecifierLoc = SourceLoc();
-      paramInfo.SpecifierKind = VarDecl::Specifier::Owned;
+      paramInfo.SpecifierKind = VarDecl::Specifier::Default;
     }
     return param;
   };
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index ca557a6..350b17d 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -42,7 +42,7 @@
   if (!attrs.empty())
     ty = new (Context) AttributedTypeRepr(attrs, ty);
 
-  // Apply 'inout' or '__shared'
+  // Apply 'inout' or '__shared' or '__owned'
   if (specifierLoc.isValid()) {
     if (auto *fnTR = dyn_cast<FunctionTypeRepr>(ty)) {
       // If the input to the function isn't parenthesized, apply the inout
@@ -64,6 +64,7 @@
     }
     switch (specifier) {
     case VarDecl::Specifier::Owned:
+      ty = new (Context) OwnedTypeRepr(ty, specifierLoc);
       break;
     case VarDecl::Specifier::InOut:
       ty = new (Context) InOutTypeRepr(ty, specifierLoc);
@@ -71,6 +72,8 @@
     case VarDecl::Specifier::Shared:
       ty = new (Context) SharedTypeRepr(ty, specifierLoc);
       break;
+    case VarDecl::Specifier::Default:
+      break;
     case VarDecl::Specifier::Var:
       llvm_unreachable("cannot have var as specifier");
       break;
@@ -904,15 +907,15 @@
       return makeParserError();
     element.Type = type.get();
 
-    // Complain obsoleted 'inout' position; (inout name: Ty)
+    // Complain obsoleted 'inout' etc. position; (inout name: Ty)
     if (ObsoletedInOutLoc.isValid()) {
-      if (isa<InOutTypeRepr>(element.Type) ||
-          isa<SharedTypeRepr>(element.Type)) {
+      if (isa<SpecifierTypeRepr>(element.Type)) {
         // If the parsed type is already a inout type et al, just remove it.
         diagnose(Tok, diag::parameter_specifier_repeated)
             .fixItRemove(ObsoletedInOutLoc);
       } else {
-        diagnose(ObsoletedInOutLoc, diag::inout_as_attr_disallowed, "'inout'")
+        diagnose(ObsoletedInOutLoc,
+                 diag::parameter_specifier_as_attr_disallowed, "inout")
             .fixItRemove(ObsoletedInOutLoc)
             .fixItInsert(element.Type->getStartLoc(), "inout ");
         // Build inout type. Note that we bury the inout locator within the
diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp
index 1d3fdd1..8b7452a 100644
--- a/lib/RemoteAST/RemoteAST.cpp
+++ b/lib/RemoteAST/RemoteAST.cpp
@@ -350,9 +350,11 @@
 
       auto label = Ctx.getIdentifier(param.getLabel());
       auto flags = param.getFlags();
+      auto ownership = flags.getValueOwnership();
       auto parameterFlags = ParameterTypeFlags()
-                                .withInOut(flags.isInOut())
-                                .withShared(flags.isShared())
+                                .withInOut(ownership == ValueOwnership::InOut)
+                                .withShared(ownership == ValueOwnership::Shared)
+                                .withOwned(ownership == ValueOwnership::Owned)
                                 .withVariadic(flags.isVariadic());
 
       funcParams.push_back(AnyFunctionType::Param(type, label, parameterFlags));
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index da75cf4..76694cc 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -268,6 +268,42 @@
   getIndirectSelfParameter(const AbstractionPattern &type) const = 0;
   virtual ParameterConvention
   getDirectSelfParameter(const AbstractionPattern &type) const = 0;
+
+  // Helpers that branch based on a value ownership.
+  ParameterConvention getIndirect(ValueOwnership ownership, bool forSelf,
+                                  unsigned index,
+                                  const AbstractionPattern &type,
+                                  const TypeLowering &substTL) const {
+    switch (ownership) {
+    case ValueOwnership::Default:
+      if (forSelf)
+        return getIndirectSelfParameter(type);
+      return getIndirectParameter(index, type, substTL);
+    case ValueOwnership::InOut:
+      return ParameterConvention::Indirect_Inout;
+    case ValueOwnership::Shared:
+      return ParameterConvention::Indirect_In_Guaranteed;
+    case ValueOwnership::Owned:
+      return ParameterConvention::Indirect_In;
+    }
+  }
+
+  ParameterConvention getDirect(ValueOwnership ownership, bool forSelf,
+                                unsigned index, const AbstractionPattern &type,
+                                const TypeLowering &substTL) const {
+    switch (ownership) {
+    case ValueOwnership::Default:
+      if (forSelf)
+        return getDirectSelfParameter(type);
+      return getDirectParameter(index, type, substTL);
+    case ValueOwnership::InOut:
+      return ParameterConvention::Indirect_Inout;
+    case ValueOwnership::Shared:
+      return ParameterConvention::Direct_Guaranteed;
+    case ValueOwnership::Owned:
+      return ParameterConvention::Direct_Owned;
+    }
+  }
 };
 
 /// A visitor for breaking down formal result types into a SILResultInfo
@@ -523,40 +559,6 @@
     }
   }
 
-  void visitSharedType(AbstractionPattern origType, CanType substType,
-                       SILFunctionTypeRepresentation rep) {
-    NextOrigParamIndex++;
-
-    auto &substTL =
-      M.Types.getTypeLowering(origType, substType);
-    ParameterConvention convention;
-    if (origType.getAs<InOutType>()) {
-      convention = ParameterConvention::Indirect_Inout;
-    } else if (isa<TupleType>(substType) && !origType.isTypeParameter()) {
-      // Do not lower tuples @guaranteed.  This can create conflicts with
-      // substitutions for witness thunks e.g. we take $*(T, T)
-      // @in_guaranteed and try to substitute it for $*T.
-      return visit(origType, substType);
-    } else if (isFormallyPassedIndirectly(origType, substType, substTL)) {
-      if (rep == SILFunctionTypeRepresentation::WitnessMethod)
-        convention = ParameterConvention::Indirect_In_Guaranteed;
-      else
-        convention = Convs.getIndirectSelfParameter(origType);
-      assert(isIndirectFormalParameter(convention));
-
-    } else if (substTL.isTrivial()) {
-      convention = ParameterConvention::Direct_Unowned;
-    } else {
-      convention = Convs.getDirectSelfParameter(origType);
-      assert(!isIndirectFormalParameter(convention));
-    }
-
-    auto loweredType = substTL.getLoweredType().getSwiftRValueType();
-    Inputs.push_back(SILParameterInfo(loweredType, convention));
-
-    maybeAddForeignParameters();
-  }
-
   /// This is a special entry point that allows destructure inputs to handle
   /// self correctly.
   void visitTopLevelParams(AbstractionPattern origType,
@@ -565,11 +567,15 @@
     unsigned numEltTypes = params.size();
     unsigned numNonSelfParams = numEltTypes - 1;
 
+    auto silRepresentation = extInfo.getSILRepresentation();
+
     // We have to declare this out here so that the lambda scope lasts for
     // the duration of the loop below.
     auto handleForeignSelf = [&] {
-      visit(origType.getTupleElementType(numNonSelfParams),
-            params[numNonSelfParams].getType());
+      // This is a "self", but it's not a Swift self, we handle it differently.
+      visit(ValueOwnership::Default,
+            /*forSelf=*/false, origType.getTupleElementType(numNonSelfParams),
+            params[numNonSelfParams].getType(), silRepresentation);
     };
 
     // If we have a foreign-self, install handleSelf as the handler.
@@ -587,7 +593,8 @@
     // to substitute.
     if (params.empty()) {
       if (origType.isTypeParameter())
-        visit(origType, M.getASTContext().TheEmptyTupleType);
+        visit(ValueOwnership::Default, /*forSelf=*/false, origType,
+              M.getASTContext().TheEmptyTupleType, silRepresentation);
       return;
     }
 
@@ -599,13 +606,9 @@
       // If the abstraction pattern is opaque, and the tuple type is
       // materializable -- if it doesn't contain an l-value type -- then it's
       // a valid target for substitution and we should not expand it.
-      auto silExtInfo = extInfo.getSILRepresentation();
       if (!tty || (pattern.isTypeParameter() && !tty->hasInOutElement())) {
-        if (paramFlags.isShared()) {
-          visitSharedType(pattern, ty, silExtInfo);
-        } else {
-          visit(pattern, ty);
-        }
+        visit(paramFlags.getValueOwnership(), /*forSelf=*/false, pattern, ty,
+              silRepresentation);
         return;
       }
 
@@ -613,11 +616,8 @@
         auto patternEltTy = pattern.getTupleElementType(i);
         auto trueEltTy = tty.getElementType(i);
         auto flags = tty->getElement(i).getParameterFlags();
-        if (flags.isShared()) {
-          visitSharedType(patternEltTy, trueEltTy, silExtInfo);
-        } else {
-          visit(patternEltTy, trueEltTy);
-        }
+        visit(flags.getValueOwnership(), /*forSelf=*/false, patternEltTy,
+              trueEltTy, silRepresentation);
       }
     };
 
@@ -647,25 +647,41 @@
     // Process the self parameter.  Note that we implicitly drop self
     // if this is a static foreign-self import.
     if (!Foreign.Self.isImportAsMember()) {
-      visitSharedType(origType.getTupleElementType(numNonSelfParams),
-                      params[numNonSelfParams].getType(),
-                      extInfo.getSILRepresentation());
+      visit(ValueOwnership::Default, /*forSelf=*/true,
+            origType.getTupleElementType(numNonSelfParams),
+            params[numNonSelfParams].getType(), silRepresentation);
     }
 
     // Clear the foreign-self handler for safety.
     HandleForeignSelf.reset();
   }
 
-  void visit(AbstractionPattern origType, CanType substType) {
-    // Expand tuples.
+  void visit(ValueOwnership ownership, bool forSelf,
+             AbstractionPattern origType, CanType substType,
+             SILFunctionTypeRepresentation rep) {
+    // Tuples get handled specially, in some cases:
     CanTupleType substTupleTy = dyn_cast<TupleType>(substType);
     if (substTupleTy && !origType.isTypeParameter()) {
       assert(origType.getNumTupleElements() == substTupleTy->getNumElements());
-      for (auto i : indices(substTupleTy.getElementTypes())) {
-        visit(origType.getTupleElementType(i),
-              substTupleTy.getElementType(i));
+      switch (ownership) {
+      case ValueOwnership::Default:
+      case ValueOwnership::Owned:
+        // Expand the tuple.
+        for (auto i : indices(substTupleTy.getElementTypes())) {
+          visit(ownership, forSelf, origType.getTupleElementType(i),
+                substTupleTy.getElementType(i), rep);
+        }
+        return;
+      case ValueOwnership::Shared:
+        // Do not lower tuples @guaranteed.  This can create conflicts with
+        // substitutions for witness thunks e.g. we take $*(T, T)
+        // @in_guaranteed and try to substitute it for $*T.
+        return visit(ValueOwnership::Default, forSelf, origType, substType,
+                     rep);
+      case ValueOwnership::InOut:
+        // handled below
+        break;
       }
-      return;
     }
 
     unsigned origParamIndex = NextOrigParamIndex++;
@@ -676,14 +692,17 @@
       assert(origType.isTypeParameter() || origType.getAs<InOutType>());
       convention = ParameterConvention::Indirect_Inout;
     } else if (isFormallyPassedIndirectly(origType, substType, substTL)) {
-      convention = Convs.getIndirectParameter(origParamIndex,
-                                              origType, substTL);
+      if (forSelf && rep == SILFunctionTypeRepresentation::WitnessMethod)
+        convention = ParameterConvention::Indirect_In_Guaranteed;
+      else
+        convention = Convs.getIndirect(ownership, forSelf, origParamIndex,
+                                       origType, substTL);
       assert(isIndirectFormalParameter(convention));
     } else if (substTL.isTrivial()) {
       convention = ParameterConvention::Direct_Unowned;
     } else {
-      convention = Convs.getDirectParameter(origParamIndex, origType,
-                                            substTL);
+      convention = Convs.getDirect(ownership, forSelf, origParamIndex, origType,
+                                   substTL);
       assert(!isIndirectFormalParameter(convention));
     }
     auto loweredType = substTL.getLoweredType().getSwiftRValueType();
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index aa511b8..37a0957 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -118,9 +118,9 @@
       // If this is a non-address-only stored 'let' constant, we can capture it
       // by value.  If it is address-only, then we can't load it, so capture it
       // by its address (like a var) instead.
-      if ((var->isLet() || var->isShared())
-          && (!SILModuleConventions(M).useLoweredAddresses() ||
-              !getTypeLowering(var->getType()).isAddressOnly()))
+      if (var->isImmutable() &&
+          (!SILModuleConventions(M).useLoweredAddresses() ||
+           !getTypeLowering(var->getType()).isAddressOnly()))
         return CaptureKind::Constant;
 
       // In-out parameters are captured by address.
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 088b97b..6702ccf 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -15,6 +15,7 @@
 #include "Scope.h"
 #include "swift/Strings.h"
 #include "swift/AST/DiagnosticsSIL.h"
+#include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/PrettyStackTrace.h"
@@ -1204,7 +1205,69 @@
 }
 
 void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) {
-  // TODO
+  // TODO: Key path code emission doesn't handle opaque values properly yet.
+  if (!SILModuleConventions(M).useLoweredAddresses())
+    return;
+  
+  if (!doesPropertyNeedDescriptor(decl))
+    return;
+  
+  auto genericEnv = decl->getInnermostDeclContext()
+                        ->getGenericEnvironmentOfContext();
+  unsigned baseOperand = 0;
+  bool needsGenericContext = true;
+  
+  Type baseTy;
+  if (decl->getDeclContext()->isTypeContext()) {
+    baseTy = decl->getDeclContext()->getSelfInterfaceType();
+    if (decl->isStatic()) {
+      // TODO: Static properties should eventually be referenceable as
+      // keypaths from T.Type -> Element
+      //baseTy = MetatypeType::get(baseTy);
+      return;
+    }
+  } else {
+    // TODO: Global variables should eventually be referenceable as
+    // key paths from ()
+    //baseTy = TupleType::getEmpty(getASTContext());
+    return;
+  }
+  
+  SubstitutionList subs = {};
+  if (genericEnv)
+    subs = genericEnv->getForwardingSubstitutions();
+  
+  // TODO: The hashable conformances for the indices need to be provided by the
+  // client, since they may be post-hoc conformances, or a generic subscript
+  // may be invoked with hashable substitutions. We may eventually allow for
+  // non-hashable keypaths as well.
+  SmallVector<ProtocolConformanceRef, 4> indexHashables;
+  if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
+    auto hashable = getASTContext().getProtocol(KnownProtocolKind::Hashable);
+    for (auto *index : *sub->getIndices()) {
+      if (index->isInOut())
+        return;
+      auto indexTy = index->getInterfaceType();
+      if (genericEnv)
+        indexTy = genericEnv->mapTypeIntoContext(indexTy);
+      
+      auto conformance = sub->getModuleContext()
+                            ->lookupConformance(indexTy, hashable);
+      if (!conformance)
+        return;
+      if (!conformance->getConditionalRequirements().empty())
+        return;
+      indexHashables.push_back(*conformance);
+    }
+  }
+  
+  auto component = emitKeyPathComponentForDecl(SILLocation(decl),
+                                               genericEnv,
+                                               baseOperand, needsGenericContext,
+                                               subs, decl, indexHashables,
+                                               baseTy->getCanonicalType());
+  
+  (void)SILProperty::create(M, /*serialized*/ false, decl, component);
 }
 
 void SILGenModule::emitPropertyBehavior(VarDecl *vd) {
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index 0a8275d..7ae1bf7 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -339,6 +339,16 @@
                                  AccessKind accessKind);
   SILDeclRef getMaterializeForSetDeclRef(AbstractStorageDecl *decl);
 
+  KeyPathPatternComponent
+  emitKeyPathComponentForDecl(SILLocation loc,
+                              GenericEnvironment *genericEnv,
+                              unsigned &baseOperand,
+                              bool &needsGenericContext,
+                              SubstitutionList subs,
+                              AbstractStorageDecl *storage,
+                              ArrayRef<ProtocolConformanceRef> indexHashables,
+                              CanType baseTy);
+
   /// Known functions for bridging.
   SILDeclRef getStringToNSStringFn();
   SILDeclRef getNSStringToStringFn();
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 3f8a2f2..aa265e3 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -5013,6 +5013,9 @@
                                                       ManagedValue base,
                                                       CanType baseFormalType,
                                                       SILDeclRef accessor) {
+  if (!base)
+    return ArgumentSource();
+
   AccessorBaseArgPreparer Preparer(*this, loc, base, baseFormalType, accessor);
   return Preparer.prepare();
 }
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index 946640b..2adb634 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -34,10 +34,10 @@
   Type metatype = ctor->getInterfaceType()->castTo<AnyFunctionType>()->getInput();
   auto *DC = ctor->getInnermostDeclContext();
   auto &AC = SGF.getASTContext();
-  auto VD = new (AC) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
-                               AC.getIdentifier("$metatype"), SourceLoc(),
-                               AC.getIdentifier("$metatype"), Type(),
-                               DC);
+  auto VD =
+      new (AC) ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                         AC.getIdentifier("$metatype"), SourceLoc(),
+                         AC.getIdentifier("$metatype"), Type(), DC);
   VD->setInterfaceType(metatype);
 
   SGF.AllocatorMetatype = SGF.F.begin()->createFunctionArgument(
@@ -61,7 +61,7 @@
   }
 
   auto &AC = SGF.getASTContext();
-  auto VD = new (AC) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
+  auto VD = new (AC) ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
                                AC.getIdentifier("$implicit_value"),
                                SourceLoc(),
                                AC.getIdentifier("$implicit_value"), Type(),
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 72d725b7..5128020 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -2983,6 +2983,11 @@
                       CanType &baseType,
                       SubstitutionList &subs,
                       SmallVectorImpl<Substitution> &subsBuf) {
+  // If the storage is at global scope, then the base value () is a formality.
+  // There no real argument to pass to the underlying accessors.
+  if (!storage->getDeclContext()->isTypeContext())
+    return ManagedValue();
+  
   auto paramOrigValue = subSGF.emitManagedRValueWithCleanup(paramArg);
   auto paramSubstValue = subSGF.emitOrigToSubstValue(loc, paramOrigValue,
                                              AbstractionPattern::getOpaque(),
@@ -3147,7 +3152,7 @@
   
   SmallVector<Substitution, 2> subsBuf;
   
-  auto paramSubstValue = emitKeyPathRValueBase(subSGF, property,
+  auto baseSubstValue = emitKeyPathRValueBase(subSGF, property,
                                                loc, baseArg,
                                                baseType, subs, subsBuf);
   
@@ -3155,7 +3160,7 @@
                                                          indexes,
                                                          indexPtrArg);
   
-  auto resultSubst = subSGF.emitRValueForStorageLoad(loc, paramSubstValue,
+  auto resultSubst = subSGF.emitRValueForStorageLoad(loc, baseSubstValue,
                                    baseType, /*super*/false,
                                    property, std::move(indexValue),
                                    subs, AccessSemantics::Ordinary,
@@ -3448,6 +3453,11 @@
       auto equatable = *subMap
         .lookupConformance(CanType(hashableSig->getGenericParams()[0]),
                            equatableProtocol);
+      
+      assert(equatable.isAbstract() == hashable.isAbstract());
+      if (equatable.isConcrete())
+        assert(equatable.getConcrete()->getType()->isEqual(
+                  hashable.getConcrete()->getType()));
       auto equatableSub = Substitution(formalTy,
                    C.AllocateCopy(ArrayRef<ProtocolConformanceRef>(equatable)));
     
@@ -3690,15 +3700,21 @@
                  bool &needsGenericContext) {
   // Capturing an index value dependent on the generic context means we
   // need the generic context captured in the key path.
-  auto subMap =
-            subscript->getGenericSignature()->getSubstitutionMap(subscriptSubs);
-  auto subscriptSubstTy = subscript->getInterfaceType().subst(subMap);
+  auto subscriptSubstTy = subscript->getInterfaceType();
+  SubstitutionMap subMap;
+  auto sig = subscript->getGenericSignature();
+  if (sig) {
+    subMap = sig->getSubstitutionMap(subscriptSubs);
+    subscriptSubstTy = subscriptSubstTy.subst(subMap);
+  }
   needsGenericContext |= subscriptSubstTy->hasArchetype();
 
   unsigned i = 0;
   for (auto *index : *subscript->getIndices()) {
-    auto indexTy = index->getInterfaceType().subst(subMap)
-                        ->getCanonicalType();
+    auto indexTy = index->getInterfaceType();
+    if (sig) {
+      indexTy = indexTy.subst(subMap);
+    }
     auto hashable = indexHashables[i++];
     assert(hashable.isAbstract() ||
            hashable.getConcrete()->getType()->isEqual(indexTy));
@@ -3718,20 +3734,24 @@
   }
 };
 
-static KeyPathPatternComponent
-emitKeyPathComponentForDecl(SILGenModule &SGM,
-                            SILLocation loc,
-                            GenericEnvironment *genericEnv,
-                            unsigned &baseOperand,
-                            bool &needsGenericContext,
-                            SubstitutionList subs,
-                            AbstractStorageDecl *storage,
-                            ArrayRef<ProtocolConformanceRef> indexHashables,
-                            CanType baseTy) {
+KeyPathPatternComponent
+SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
+                                GenericEnvironment *genericEnv,
+                                unsigned &baseOperand,
+                                bool &needsGenericContext,
+                                SubstitutionList subs,
+                                AbstractStorageDecl *storage,
+                                ArrayRef<ProtocolConformanceRef> indexHashables,
+                                CanType baseTy) {
   if (auto var = dyn_cast<VarDecl>(storage)) {
-    auto componentTy = baseTy->getTypeOfMember(SGM.SwiftModule, var)
-      ->getReferenceStorageReferent()
-      ->getCanonicalType();
+    CanType componentTy;
+    if (!var->getDeclContext()->isTypeContext()) {
+      componentTy = storage->getStorageInterfaceType()->getCanonicalType();
+    } else {
+      componentTy = baseTy->getTypeOfMember(SwiftModule, var)
+        ->getReferenceStorageReferent()
+        ->getCanonicalType();
+    }
   
     switch (auto strategy = var->getAccessStrategy(AccessSemantics::Ordinary,
                                                     AccessKind::ReadWrite)) {
@@ -3741,9 +3761,9 @@
       auto componentObjTy = componentTy->getWithoutSpecifierType();
       if (genericEnv)
         componentObjTy = genericEnv->mapTypeIntoContext(componentObjTy);
-      auto storageTy = SGM.Types.getSubstitutedStorageType(var,
+      auto storageTy = Types.getSubstitutedStorageType(var,
                                                            componentObjTy);
-      auto opaqueTy = SGM.Types
+      auto opaqueTy = Types
         .getLoweredType(AbstractionPattern::getOpaque(), componentObjTy);
       
       if (storageTy.getAddressType() == opaqueTy.getAddressType()) {
@@ -3756,9 +3776,9 @@
     case AccessStrategy::DispatchToAccessor: {
       // We need thunks to bring the getter and setter to the right signature
       // expected by the key path runtime.
-      auto id = getIdForKeyPathComponentComputedProperty(SGM, var,
+      auto id = getIdForKeyPathComponentComputedProperty(*this, var,
                                                          strategy);
-      auto getter = getOrCreateKeyPathGetter(SGM, loc,
+      auto getter = getOrCreateKeyPathGetter(*this, loc,
                var, subs,
                strategy,
                needsGenericContext ? genericEnv : nullptr,
@@ -3766,7 +3786,7 @@
                baseTy, componentTy);
       
       if (var->isSettable(var->getDeclContext())) {
-        auto setter = getOrCreateKeyPathSetter(SGM, loc,
+        auto setter = getOrCreateKeyPathSetter(*this, loc,
                var, subs,
                strategy,
                needsGenericContext ? genericEnv : nullptr,
@@ -3796,28 +3816,30 @@
     auto componentTy = baseSubscriptInterfaceTy.getResult();
   
     SmallVector<KeyPathPatternComponent::Index, 4> indexPatterns;
-    lowerKeyPathSubscriptIndexPatterns(SGM, indexPatterns,
+    lowerKeyPathSubscriptIndexPatterns(*this, indexPatterns,
                                        decl, subs, indexHashables,
                                        baseOperand,
                                        needsGenericContext);
     
     SILFunction *indexEquals = nullptr, *indexHash = nullptr;
-    getOrCreateKeyPathEqualsAndHash(SGM, loc,
+    // TODO: Property descriptors for external key paths should get their
+    // equality and hashing from the client.
+    getOrCreateKeyPathEqualsAndHash(*this, loc,
              needsGenericContext ? genericEnv : nullptr,
              indexPatterns,
              indexEquals, indexHash);
 
-    auto id = getIdForKeyPathComponentComputedProperty(SGM, decl, strategy);
-    auto getter = getOrCreateKeyPathGetter(SGM, loc,
+    auto id = getIdForKeyPathComponentComputedProperty(*this, decl, strategy);
+    auto getter = getOrCreateKeyPathGetter(*this, loc,
              decl, subs,
              strategy,
              needsGenericContext ? genericEnv : nullptr,
              indexPatterns,
              baseTy, componentTy);
   
-    auto indexPatternsCopy = SGM.getASTContext().AllocateCopy(indexPatterns);
+    auto indexPatternsCopy = getASTContext().AllocateCopy(indexPatterns);
     if (decl->isSettable()) {
-      auto setter = getOrCreateKeyPathSetter(SGM, loc,
+      auto setter = getOrCreateKeyPathSetter(*this, loc,
              decl, subs,
              strategy,
              needsGenericContext ? genericEnv : nullptr,
@@ -3952,7 +3974,7 @@
       } else {
         unsigned numOperands = operands.size();
         loweredComponents.push_back(
-          emitKeyPathComponentForDecl(SGF.SGM, SILLocation(E),
+          SGF.SGM.emitKeyPathComponentForDecl(SILLocation(E),
                               SGF.F.getGenericEnvironment(),
                               numOperands,
                               needsGenericContext,
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 2314db6..7ffecf9 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -1573,9 +1573,6 @@
       ///
       /// Valid: reabstraction info, InnerResult, OuterResult.
       ReabstractDirectToDirect,
-
-      /// Ignore the next direct inner result, since the outer is 'Void'.
-      IgnoreDirectResult,
     };
 
     Operation(Kind kind) : TheKind(kind) {}
@@ -1720,24 +1717,6 @@
                                     SILResultInfo outerResult,
                                     SILValue optOuterResultAddr);
 
-  void planIgnoredResult(AbstractionPattern innerOrigType,
-                         CanType innerSubstType, PlanData &planData) {
-    if (innerOrigType.isTuple()) {
-      auto innerSubstTuple = cast<TupleType>(innerSubstType);
-      for (unsigned i = 0, n = innerSubstTuple->getNumElements(); i != n; ++i)
-        planIgnoredResult(innerOrigType.getTupleElementType(i),
-                          innerSubstTuple.getElementType(i), planData);
-      return;
-    }
-
-    auto innerResult = claimNextInnerResult(planData);
-    if (innerResult.isFormalIndirect() &&
-        SGF.silConv.isSILIndirect(innerResult))
-      (void)addInnerIndirectResultTemporary(planData, innerResult);
-    else
-      addIgnoreDirectResult();
-  }
-
   /// Claim the next inner result from the plan data.
   SILResultInfo claimNextInnerResult(PlanData &data) {
     return claimNext(data.InnerResults);
@@ -1887,10 +1866,6 @@
     op.OuterOrigType = outerOrigType;
     op.OuterSubstType = outerSubstType;
   }
-
-  void addIgnoreDirectResult() {
-    (void)addOperation(Operation::IgnoreDirectResult);
-  }
 };
 
 } // end anonymous namespace
@@ -1901,13 +1876,6 @@
                          AbstractionPattern outerOrigType,
                          CanType outerSubstType,
                          PlanData &planData) {
-  // Conversion from `() -> T` to `() -> Void` is allowed when
-  // the argument is a closure.
-  if (!innerSubstType->isVoid() && outerSubstType->isVoid()) {
-    planIgnoredResult(innerOrigType, innerSubstType, planData);
-    return;
-  }
-
   // The substituted types must match up in tuple-ness and arity.
   assert(
       isa<TupleType>(innerSubstType) == isa<TupleType>(outerSubstType) ||
@@ -2616,10 +2584,6 @@
     case Operation::InjectOptionalIndirect:
       SGF.B.createInjectEnumAddr(Loc, op.OuterResultAddr, op.SomeDecl);
       continue;
-
-    case Operation::IgnoreDirectResult:
-      (void)claimNext(innerDirectResults);
-      continue;
     }
     llvm_unreachable("bad operation kind");
   }
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index 8953613..5299b8a 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -283,8 +283,7 @@
         }
       }
     } else {
-      assert((vd->isLet() || vd->isShared())
-             && "expected parameter to be immutable!");
+      assert(vd->isImmutable() && "expected parameter to be immutable!");
       // If the variable is immutable, we can bind the value as is.
       // Leave the cleanup on the argument, if any, in place to consume the
       // argument if we're responsible for it.
diff --git a/lib/SILOptimizer/SILCombiner/SILCombiner.h b/lib/SILOptimizer/SILCombiner/SILCombiner.h
index e0299cb..068f3d6 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombiner.h
+++ b/lib/SILOptimizer/SILCombiner/SILCombiner.h
@@ -283,9 +283,6 @@
                                                SILValue ConcreteTypeDef,
                                                ProtocolConformanceRef Conformance,
                                                ArchetypeType *OpenedArchetype);
-
-  FullApplySite rewriteApplyCallee(FullApplySite apply, SILValue callee);
-
   SILInstruction *
   propagateConcreteTypeOfInitExistential(FullApplySite AI,
       ProtocolDecl *Protocol,
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 393ab1f..b885c70 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -1305,27 +1305,6 @@
   return true;
 }
 
-// Return a new apply with the specified callee. This creates a new apply rather
-// than simply rewriting the callee operand because the apply's SubstCalleeType,
-// derived from the callee and substitution list, may change.
-FullApplySite SILCombiner::rewriteApplyCallee(FullApplySite apply,
-                                              SILValue callee) {
-  SmallVector<SILValue, 4> arguments;
-  for (SILValue arg : apply.getArguments())
-    arguments.push_back(arg);
-
-  Builder.addOpenedArchetypeOperands(apply.getInstruction());
-  if (auto *TAI = dyn_cast<TryApplyInst>(apply)) {
-    return Builder.createTryApply(TAI->getLoc(), callee,
-                                  TAI->getSubstitutions(), arguments,
-                                  TAI->getNormalBB(), TAI->getErrorBB());
-  } else {
-    return Builder.createApply(apply.getLoc(), callee, apply.getSubstitutions(),
-                               arguments,
-                               cast<ApplyInst>(apply)->isNonThrowing());
-  }
-}
-
 SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
   Builder.setCurrentDebugScope(AI->getDebugScope());
   // apply{partial_apply(x,y)}(z) -> apply(z,x,y) is triggered
@@ -1367,11 +1346,20 @@
 
   // (apply (thin_to_thick_function f)) to (apply f)
   if (auto *TTTFI = dyn_cast<ThinToThickFunctionInst>(AI->getCallee())) {
-    // We currently don't remove any possible retain associated with the thick
-    // function when rewriting the callsite. This should be ok because the
-    // ABI normally expects a guaranteed callee.
-    if (!AI->getOrigCalleeType()->isCalleeConsumed())
-      return rewriteApplyCallee(AI, TTTFI->getOperand()).getInstruction();
+    // TODO: Handle substitutions and indirect results
+    if (AI->hasSubstitutions() || AI->hasIndirectResults())
+      return nullptr;
+    SmallVector<SILValue, 4> Arguments;
+    for (auto &Op : AI->getArgumentOperands()) {
+      Arguments.push_back(Op.get());
+    }
+    // The type of the substitution is the source type of the thin to thick
+    // instruction.
+    Builder.addOpenedArchetypeOperands(AI);
+    auto *NewAI = Builder.createApply(AI->getLoc(), TTTFI->getOperand(),
+                                      AI->getSubstitutions(), Arguments,
+                                      AI->isNonThrowing());
+    return NewAI;
   }
 
   // (apply (witness_method)) -> propagate information about
@@ -1489,12 +1477,21 @@
 
   // (try_apply (thin_to_thick_function f)) to (try_apply f)
   if (auto *TTTFI = dyn_cast<ThinToThickFunctionInst>(AI->getCallee())) {
-    // We currently don't remove any possible retain associated with the thick
-    // function when rewriting the callsite. This should be ok because the
-    // ABI normally expects a guaranteed callee.
-    if (!AI->getOrigCalleeType()->isCalleeConsumed())
-      return rewriteApplyCallee(AI, TTTFI->getOperand()).getInstruction();
+    // TODO: Handle substitutions and indirect results
+    if (AI->hasSubstitutions() || AI->hasIndirectResults())
+      return nullptr;
+    SmallVector<SILValue, 4> Arguments;
+    for (auto &Op : AI->getArgumentOperands()) {
+      Arguments.push_back(Op.get());
+    }
+    // The type of the substitution is the source type of the thin to thick
+    // instruction.
+    auto *NewAI = Builder.createTryApply(AI->getLoc(), TTTFI->getOperand(),
+                                         AI->getSubstitutions(), Arguments,
+                                         AI->getNormalBB(), AI->getErrorBB());
+    return NewAI;
   }
+
   // (apply (witness_method)) -> propagate information about
   // a concrete type from init_existential_addr or init_existential_ref.
   if (auto *WMI = dyn_cast<WitnessMethodInst>(AI->getCallee())) {
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 4773f3e..0318c5b 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1998,12 +1998,14 @@
         patternElt.first->setType(patternElt.second);
       
       for (auto paramDeclElt : ParamDeclTypes) {
-        assert(!paramDeclElt.first->isLet() || !paramDeclElt.second->is<InOutType>());
+        assert(!paramDeclElt.first->isImmutable() ||
+               !paramDeclElt.second->is<InOutType>());
         paramDeclElt.first->setType(paramDeclElt.second->getInOutObjectType());
       }
       
       for (auto paramDeclIfaceElt : ParamDeclInterfaceTypes) {
-        assert(!paramDeclIfaceElt.first->isLet() || !paramDeclIfaceElt.second->is<InOutType>());
+        assert(!paramDeclIfaceElt.first->isImmutable() ||
+               !paramDeclIfaceElt.second->is<InOutType>());
         paramDeclIfaceElt.first->setInterfaceType(paramDeclIfaceElt.second->getInOutObjectType());
       }
       
@@ -6471,10 +6473,10 @@
       // 'inout' from type because that might help to diagnose actual problem
       // e.g. type inference doesn't give us much information anyway.
       if (param->isInOut() && paramType->hasUnresolvedType()) {
-        assert(!param->isLet() || !paramType->is<InOutType>());
+        assert(!param->isImmutable() || !paramType->is<InOutType>());
         param->setType(CS.getASTContext().TheUnresolvedType);
         param->setInterfaceType(paramType->getInOutObjectType());
-        param->setSpecifier(swift::VarDecl::Specifier::Owned);
+        param->setSpecifier(swift::VarDecl::Specifier::Default);
       }
     }
 
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index a66963f..497f0ce 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1954,7 +1954,7 @@
         if (auto type = param->getTypeLoc().getType()) {
           // FIXME: Need a better locator for a pattern as a base.
           Type openedType = CS.openUnboundGenericType(type, locator);
-          assert(!param->isLet() || !openedType->is<InOutType>());
+          assert(!param->isImmutable() || !openedType->is<InOutType>());
           param->setType(openedType->getInOutObjectType());
           param->setInterfaceType(openedType->getInOutObjectType());
           continue;
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index f506284..451f047 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -1007,32 +1007,14 @@
   // Compare the type variable bindings.
   auto &tc = cs.getTypeChecker();
   for (auto &binding : diff.typeBindings) {
-    auto type1 = binding.bindings[idx1];
-    auto type2 = binding.bindings[idx2];
-
-    auto &impl = binding.typeVar->getImpl();
-
-    if (auto *locator = impl.getLocator()) {
-      auto path = locator->getPath();
-      if (!path.empty() &&
-          path.back().getKind() == ConstraintLocator::ClosureResult) {
-        // Since we support `() -> T` to `() -> Void` and
-        // `() -> Never` to `() -> T` conversions, it's always
-        // preferable to pick `T` rather than `Never` with
-        // all else being equal.
-        if (type2->isUninhabited())
-          ++score1;
-
-        if (type1->isUninhabited())
-          ++score2;
-      }
-    }
-
     // If the type variable isn't one for which we should be looking at the
     // bindings, don't.
-    if (!impl.prefersSubtypeBinding())
+    if (!binding.typeVar->getImpl().prefersSubtypeBinding())
       continue;
 
+    auto type1 = binding.bindings[idx1];
+    auto type2 = binding.bindings[idx2];
+
     // If the types are equivalent, there's nothing more to do.
     if (type1->isEqual(type2))
       continue;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index e3eddf2..a2b3578 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1212,8 +1212,10 @@
     return result;
 
   // Result type can be covariant (or equal).
-  return matchTypes(func1->getResult(), func2->getResult(), subKind, subflags,
-                    locator.withPathElement(ConstraintLocator::FunctionResult));
+  return matchTypes(func1->getResult(), func2->getResult(), subKind,
+                     subflags,
+                     locator.withPathElement(
+                       ConstraintLocator::FunctionResult));
 }
 
 ConstraintSystem::TypeMatchResult
@@ -1499,8 +1501,6 @@
 ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
                              TypeMatchOptions flags,
                              ConstraintLocatorBuilder locator) {
-  auto origType1 = type1;
-
   bool isArgumentTupleConversion
           = kind == ConstraintKind::ArgumentTupleConversion ||
             kind == ConstraintKind::OperatorArgumentTupleConversion;
@@ -2243,32 +2243,7 @@
   // Allow '() -> T' to '() -> ()' and '() -> Never' to '() -> T' for closure
   // literals.
   if (auto elt = locator.last()) {
-    auto isClosureResult = [&]() {
-      if (elt->getKind() == ConstraintLocator::ClosureResult)
-        return true;
-
-      // If constraint is matching function results where
-      // left-hand side is a 'closure result' we need to allow
-      // certain implicit conversions.
-      if (elt->getKind() != ConstraintLocator::FunctionResult)
-        return false;
-
-      if (auto *typeVar = origType1->getAs<TypeVariableType>()) {
-        auto *locator = typeVar->getImpl().getLocator();
-        if (!locator)
-          return false;
-
-        auto path = locator->getPath();
-        if (path.empty())
-          return false;
-
-        return path.back().getKind() == ConstraintLocator::ClosureResult;
-      }
-
-      return false;
-    };
-
-    if (isClosureResult()) {
+    if (elt->getKind() == ConstraintLocator::ClosureResult) {
       if (concrete && kind >= ConstraintKind::Subtype &&
           (type1->isUninhabited() || type2->isVoid())) {
         increaseScore(SK_FunctionConversion);
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 836b3cd..2dcc3fb 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -203,11 +203,9 @@
   // Add a "(value : T, indices...)" argument list.
   auto storageType = getTypeOfStorage(storage, false);
   auto storageInterfaceType = getTypeOfStorage(storage, true);
-  valueDecl = buildArgument(storage->getLoc(),
-                            storage->getDeclContext(), "value",
-                            storageType,
-                            storageInterfaceType,
-                            VarDecl::Specifier::Owned);
+  valueDecl = buildArgument(storage->getLoc(), storage->getDeclContext(),
+                            "value", storageType, storageInterfaceType,
+                            VarDecl::Specifier::Default);
   params.push_back(buildIndexForwardingParamList(storage, valueDecl));
 
   Type setterRetTy = TupleType::getEmpty(TC.Context);
@@ -314,15 +312,10 @@
   //                           inout storage: Builtin.UnsafeValueBuffer,
   //                           indices...).
   ParamDecl *bufferElements[] = {
-    buildArgument(loc, DC, "buffer",
-                  ctx.TheRawPointerType,
-                  ctx.TheRawPointerType,
-                  VarDecl::Specifier::Owned),
-    buildArgument(loc, DC, "callbackStorage",
-                  ctx.TheUnsafeValueBufferType,
-                  ctx.TheUnsafeValueBufferType,
-                  VarDecl::Specifier::InOut)
-  };
+      buildArgument(loc, DC, "buffer", ctx.TheRawPointerType,
+                    ctx.TheRawPointerType, VarDecl::Specifier::Default),
+      buildArgument(loc, DC, "callbackStorage", ctx.TheUnsafeValueBufferType,
+                    ctx.TheUnsafeValueBufferType, VarDecl::Specifier::InOut)};
   params.push_back(buildIndexForwardingParamList(storage, bufferElements));
 
   // The accessor returns (temporary: Builtin.RawPointer,
@@ -1369,18 +1362,16 @@
     assert(interfaceTy);
     auto contextTy = declaredParamTy.subst(contextMap);
     assert(contextTy);
+    auto declaredSpecifier = declaredParam->getSpecifier();
 
     SmallString<64> ParamNameBuf;
     {
       llvm::raw_svector_ostream names(ParamNameBuf);
       names << "%arg." << i;
     }
-    auto param = new (Context) ParamDecl(VarDecl::Specifier::Owned,
-                                         SourceLoc(), SourceLoc(),
-                                         Identifier(),
-                                         SourceLoc(),
-                                         Context.getIdentifier(ParamNameBuf),
-                                         contextTy, DC);
+    auto param = new (Context) ParamDecl(
+        declaredSpecifier, SourceLoc(), SourceLoc(), Identifier(), SourceLoc(),
+        Context.getIdentifier(ParamNameBuf), contextTy, DC);
     param->setInterfaceType(interfaceTy);
     param->setImplicit();
     Params.push_back(param);
@@ -1936,9 +1927,9 @@
       }
 
       // Create the parameter.
-      auto *arg = new (context) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), 
-                                          Loc, var->getName(),
-                                          Loc, var->getName(), varType, decl);
+      auto *arg = new (context)
+          ParamDecl(VarDecl::Specifier::Default, SourceLoc(), Loc,
+                    var->getName(), Loc, var->getName(), varType, decl);
       arg->setInterfaceType(varInterfaceType);
       arg->setImplicit();
       
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index 62cfdfc..d53187a 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -1433,7 +1433,7 @@
     overloads.push_back(bindOverloadConstraint);
   }
   
-  for (auto choice : choices) {
+  for (auto &choice : choices) {
     if (favoredChoice && (favoredChoice == &choice))
       continue;
     
diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp
index d96e8c7..b6ad8fa 100644
--- a/lib/Sema/DerivedConformanceCodable.cpp
+++ b/lib/Sema/DerivedConformanceCodable.cpp
@@ -484,9 +484,9 @@
                                             Expr *base, Type returnType,
                                             NominalTypeDecl *param) {
   // (keyedBy:)
-  auto *keyedByDecl = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
-                                        SourceLoc(), C.Id_keyedBy, SourceLoc(),
-                                        C.Id_keyedBy, returnType, DC);
+  auto *keyedByDecl = new (C)
+      ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                C.Id_keyedBy, SourceLoc(), C.Id_keyedBy, returnType, DC);
   keyedByDecl->setImplicit();
   keyedByDecl->setInterfaceType(returnType);
 
@@ -727,9 +727,9 @@
 
   // Params: (self [implicit], Encoder)
   auto *selfDecl = ParamDecl::createSelf(SourceLoc(), target);
-  auto *encoderParam = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
-                                         SourceLoc(), C.Id_to, SourceLoc(),
-                                         C.Id_encoder, encoderType, target);
+  auto *encoderParam = new (C)
+      ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), C.Id_to,
+                SourceLoc(), C.Id_encoder, encoderType, target);
   encoderParam->setInterfaceType(encoderType);
 
   ParameterList *params[] = {ParameterList::createWithoutLoc(selfDecl),
@@ -1065,11 +1065,9 @@
   auto *selfDecl = ParamDecl::createSelf(SourceLoc(), target,
                                          /*isStatic=*/false,
                                          /*isInOut=*/inOut);
-  auto *decoderParamDecl = new (C) ParamDecl(VarDecl::Specifier::Owned,
-                                             SourceLoc(),
-                                             SourceLoc(), C.Id_from,
-                                             SourceLoc(), C.Id_decoder,
-                                             decoderType, target);
+  auto *decoderParamDecl = new (C)
+      ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                C.Id_from, SourceLoc(), C.Id_decoder, decoderType, target);
   decoderParamDecl->setImplicit();
   decoderParamDecl->setInterfaceType(decoderType);
 
diff --git a/lib/Sema/DerivedConformanceCodingKey.cpp b/lib/Sema/DerivedConformanceCodingKey.cpp
index 2a03c5b..d1eb3fa 100644
--- a/lib/Sema/DerivedConformanceCodingKey.cpp
+++ b/lib/Sema/DerivedConformanceCodingKey.cpp
@@ -74,10 +74,9 @@
                                              DeclNameLoc(), /*Implicit=*/true);
 
   // rawValue param to init(rawValue:)
-  auto *rawValueDecl = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
-                                         SourceLoc(), C.Id_rawValue,
-                                         SourceLoc(), C.Id_rawValue,
-                                         valueParam->getType(), parentDC);
+  auto *rawValueDecl = new (C) ParamDecl(
+      VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), C.Id_rawValue,
+      SourceLoc(), C.Id_rawValue, valueParam->getType(), parentDC);
   rawValueDecl->setInterfaceType(C.getIntDecl()->getDeclaredType());
   rawValueDecl->setImplicit();
   auto *paramList = ParameterList::createWithoutLoc(rawValueDecl);
@@ -124,9 +123,9 @@
   auto *parentDC = cast<DeclContext>(parentDecl);
 
   // rawValue
-  auto *rawDecl = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
-                                    paramName, SourceLoc(), paramName,
-                                    paramType, parentDC);
+  auto *rawDecl =
+      new (C) ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                        paramName, SourceLoc(), paramName, paramType, parentDC);
   rawDecl->setInterfaceType(paramType);
   rawDecl->setImplicit();
 
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 8cb788c..abf95b5 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -591,10 +591,10 @@
   auto enumTy = parentDC->getDeclaredTypeInContext();
   auto enumIfaceTy = parentDC->getDeclaredInterfaceType();
 
-  auto getParamDecl = [&](StringRef s) -> ParamDecl* {
-    auto *param = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
-                                    Identifier(), SourceLoc(), C.getIdentifier(s),
-                                    enumTy, parentDC);
+  auto getParamDecl = [&](StringRef s) -> ParamDecl * {
+    auto *param = new (C) ParamDecl(VarDecl::Specifier::Default, SourceLoc(),
+                                    SourceLoc(), Identifier(), SourceLoc(),
+                                    C.getIdentifier(s), enumTy, parentDC);
     param->setInterfaceType(enumIfaceTy);
     return param;
   };
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index 43a12a8..e3aaa99 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -292,9 +292,9 @@
   auto *selfDecl = ParamDecl::createSelf(SourceLoc(), parentDC,
                                          /*static*/false, /*inout*/true);
 
-  auto *rawDecl = new (C) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(), SourceLoc(),
-                                    C.Id_rawValue, SourceLoc(),
-                                    C.Id_rawValue, rawType, parentDC);
+  auto *rawDecl = new (C)
+      ParamDecl(VarDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+                C.Id_rawValue, SourceLoc(), C.Id_rawValue, rawType, parentDC);
   rawDecl->setInterfaceType(rawInterfaceType);
   rawDecl->setImplicit();
   auto paramList = ParameterList::createWithoutLoc(rawDecl);
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index 7c5c911..548bbe7 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -2411,7 +2411,7 @@
     // If this is a 'let' value, any stores to it are actually initializations,
     // not mutations.
     auto isWrittenLet = false;
-    if (var->isLet() || var->isShared()) {
+    if (var->isImmutable()) {
       isWrittenLet = (access & RK_Written) != 0;
       access &= ~RK_Written;
     }
@@ -2550,7 +2550,7 @@
     
     // If this is a mutable 'var', and it was never written to, suggest
     // upgrading to 'let'.  We do this even for a parameter.
-    if (!(var->isLet() || var->isShared()) && (access & RK_Written) == 0 &&
+    if (!var->isImmutable() && (access & RK_Written) == 0 &&
         // Don't warn if we have something like "let (x,y) = ..." and 'y' was
         // never mutated, but 'x' was.
         !isVarDeclPartOfPBDThatHadSomeMutation(var)) {
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 0410e3e..879d4c0 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -693,7 +693,7 @@
       storageKind = SK_Subscript;
     else if (storage->getDeclContext()->isTypeContext())
       storageKind = SK_Property;
-    else if (cast<VarDecl>(storage)->isLet())
+    else if (cast<VarDecl>(storage)->isImmutable())
       storageKind = SK_Constant;
     else
       storageKind = SK_Variable;
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 09d7ce0..d7ddff3 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -1219,8 +1219,8 @@
   // 'self' is 'let' for reference types (i.e., classes) or when 'self' is
   // neither inout.
   auto specifier = selfParam.getParameterFlags().isInOut()
-                 ? VarDecl::Specifier::InOut
-                 : VarDecl::Specifier::Owned;
+                       ? VarDecl::Specifier::InOut
+                       : VarDecl::Specifier::Default;
   selfDecl->setSpecifier(specifier);
 
   selfDecl->setInterfaceType(selfParam.getPlainType());
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 4bfcae2..414f497 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -787,10 +787,8 @@
     // If the param is not a 'let' and it is not an 'inout'.
     // It must be a 'var'. Provide helpful diagnostics like a shadow copy
     // in the function body to fix the 'var' attribute.
-    if (!decl->isLet() &&
-        !decl->isImplicit() &&
-        (Ty.isNull() || !Ty->is<InOutType>()) &&
-        !hadError) {
+    if (!decl->isImmutable() && !decl->isImplicit() &&
+        (Ty.isNull() || !Ty->is<InOutType>()) && !hadError) {
       decl->setInvalid();
       hadError = true;
     }
@@ -866,6 +864,8 @@
         param->setSpecifier(VarDecl::Specifier::InOut);
       } else if (isa<SharedTypeRepr>(typeRepr)) {
         param->setSpecifier(VarDecl::Specifier::Shared);
+      } else if (isa<OwnedTypeRepr>(typeRepr)) {
+        param->setSpecifier(VarDecl::Specifier::Owned);
       }
     }
   }
@@ -1616,7 +1616,7 @@
       // Coerce explicitly specified argument type to contextual type
       // only if both types are valid and do not match.
       if (!hadError && isValidType(ty) && !ty->isEqual(paramType)) {
-        assert(!param->isLet() || !ty->is<InOutType>());
+        assert(!param->isImmutable() || !ty->is<InOutType>());
         param->setType(ty->getInOutObjectType());
         param->setInterfaceType(ty->mapTypeOutOfContext()->getInOutObjectType());
       }
@@ -1636,7 +1636,7 @@
     // trying to coerce argument to contextual type would mean erasing
     // valuable diagnostic information.
     if (isValidType(ty) || shouldOverwriteParam(param)) {
-      assert(!param->isLet() || !ty->is<InOutType>());
+      assert(!param->isImmutable() || !ty->is<InOutType>());
       param->setType(ty->getInOutObjectType());
       param->setInterfaceType(ty->mapTypeOutOfContext()->getInOutObjectType());
     }
diff --git a/lib/Sema/TypeCheckREPL.cpp b/lib/Sema/TypeCheckREPL.cpp
index 5caea72..f9a54dc 100644
--- a/lib/Sema/TypeCheckREPL.cpp
+++ b/lib/Sema/TypeCheckREPL.cpp
@@ -229,10 +229,9 @@
   TopLevelCodeDecl *newTopLevel = new (Context) TopLevelCodeDecl(&SF);
 
   // Build function of type T->() which prints the operand.
-  auto *Arg = new (Context) ParamDecl(VarDecl::Specifier::Owned, SourceLoc(),
-                                         SourceLoc(), Identifier(),
-                                         Loc, Context.getIdentifier("arg"),
-                                         E->getType(), /*DC*/ newTopLevel);
+  auto *Arg = new (Context) ParamDecl(
+      VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), Identifier(), Loc,
+      Context.getIdentifier("arg"), E->getType(), /*DC*/ newTopLevel);
   Arg->setInterfaceType(E->getType());
   auto params = ParameterList::createWithoutLoc(Arg);
 
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 3675890..a6b7ced 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -1655,11 +1655,8 @@
 
   // Strip the "is function input" bits unless this is a type that knows about
   // them.
-  if (!isa<InOutTypeRepr>(repr) &&
-      !isa<SharedTypeRepr>(repr) &&
-      !isa<TupleTypeRepr>(repr) &&
-      !isa<AttributedTypeRepr>(repr) &&
-      !isa<FunctionTypeRepr>(repr) &&
+  if (!isa<SpecifierTypeRepr>(repr) && !isa<TupleTypeRepr>(repr) &&
+      !isa<AttributedTypeRepr>(repr) && !isa<FunctionTypeRepr>(repr) &&
       !isa<IdentTypeRepr>(repr)) {
     options -= TypeResolutionFlags::ImmediateFunctionInput;
     options -= TypeResolutionFlags::FunctionInput;
@@ -1677,6 +1674,7 @@
     return resolveAttributedType(cast<AttributedTypeRepr>(repr), options);
   case TypeReprKind::InOut:
   case TypeReprKind::Shared:
+  case TypeReprKind::Owned:
     return resolveSpecifierTypeRepr(cast<SpecifierTypeRepr>(repr), options);
 
   case TypeReprKind::SimpleIdent:
@@ -2656,10 +2654,21 @@
     } else {
       diagID = diag::attr_only_on_parameters;
     }
-    TC.diagnose(repr->getSpecifierLoc(), diagID,
-                (repr->getKind() == TypeReprKind::InOut)
-                  ? "'inout'"
-                  : "'__shared'");
+    StringRef name;
+    switch (repr->getKind()) {
+    case TypeReprKind::InOut:
+      name = "'inout'";
+      break;
+    case TypeReprKind::Shared:
+      name = "'__shared'";
+      break;
+    case TypeReprKind::Owned:
+      name = "'__owned'";
+      break;
+    default:
+      llvm_unreachable("unknown SpecifierTypeRepr kind");
+    }
+    TC.diagnose(repr->getSpecifierLoc(), diagID, name);
     repr->setInvalid();
     return ErrorType::get(Context);
   }
@@ -2860,6 +2869,9 @@
       case TypeReprKind::InOut:
         ownership = ValueOwnership::InOut;
         break;
+      case TypeReprKind::Owned:
+        ownership = ValueOwnership::Owned;
+        break;
       default:
         ownership = ValueOwnership::Default;
         break;
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 8d0c1db..4d215a0 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -2090,6 +2090,7 @@
   CASE(Var)
   CASE(InOut)
   CASE(Shared)
+  CASE(Owned)
   }
 #undef CASE
   return None;
@@ -4055,6 +4056,7 @@
   CASE(Default)
   CASE(InOut)
   CASE(Shared)
+  CASE(Owned)
 #undef CASE
   }
   return None;
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 2135e46..56072c7 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -2607,7 +2607,8 @@
   // Another SIL_VTABLE record means the end of this VTable.
   while (kind != SIL_VTABLE && kind != SIL_WITNESS_TABLE &&
          kind != SIL_DEFAULT_WITNESS_TABLE &&
-         kind != SIL_FUNCTION) {
+         kind != SIL_FUNCTION &&
+         kind != SIL_PROPERTY) {
     assert(kind == SIL_VTABLE_ENTRY &&
            "Content of Vtable should be in SIL_VTABLE_ENTRY.");
     ArrayRef<uint64_t> ListOfValues;
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index dfeb917..7833007 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -2523,6 +2523,8 @@
     return uint8_t(serialization::VarDeclSpecifier::InOut);
   case swift::VarDecl::Specifier::Shared:
     return uint8_t(serialization::VarDeclSpecifier::Shared);
+  case swift::VarDecl::Specifier::Owned:
+    return uint8_t(serialization::VarDeclSpecifier::Owned);
   }
   llvm_unreachable("bad variable decl specifier kind");
 }
@@ -3495,6 +3497,7 @@
   SIMPLE_CASE(ValueOwnership, Default)
   SIMPLE_CASE(ValueOwnership, InOut)
   SIMPLE_CASE(ValueOwnership, Shared)
+  SIMPLE_CASE(ValueOwnership, Owned)
   }
   llvm_unreachable("bad ownership kind");
 }
diff --git a/stdlib/public/Reflection/TypeRef.cpp b/stdlib/public/Reflection/TypeRef.cpp
index e9cc98f..db1d588 100644
--- a/stdlib/public/Reflection/TypeRef.cpp
+++ b/stdlib/public/Reflection/TypeRef.cpp
@@ -145,15 +145,24 @@
         OS << '\n';
       }
 
-      if (flags.isInOut())
+      switch (flags.getValueOwnership()) {
+      case ValueOwnership::Default:
+        /* nothing */
+        break;
+      case ValueOwnership::InOut:
         printHeader("inout");
+        break;
+      case ValueOwnership::Shared:
+        printHeader("shared");
+        break;
+      case ValueOwnership::Owned:
+        printHeader("owned");
+        break;
+      }
 
       if (flags.isVariadic())
         printHeader("variadic");
 
-      if (flags.isShared())
-        printHeader("shared");
-
       printRec(param.getType());
 
       if (!flags.isNone()) {
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index f2d0eab..39cdc31 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -625,7 +625,16 @@
   /// almost never is.
   @_inlineable // FIXME(sil-serialize-all)
   public var ulp: ${Self} {
-    if !isFinite { return ${Self}.nan }
+%if bits != 80:
+    guard _fastPath(isFinite) else { return .nan }
+    if _fastPath(isNormal) {
+      let bitPattern_ = bitPattern & ${Self}.infinity.bitPattern
+      return ${Self}(bitPattern: bitPattern_) * 0x1p-${SignificandBitCount}
+    }
+    // On arm, flush subnormal values to 0.
+    return .leastNormalMagnitude * 0x1p-${SignificandBitCount}
+%else:
+    guard _fastPath(isFinite) else { return .nan }
     if exponentBitPattern > UInt(${Self}.significandBitCount) {
       // self is large enough that self.ulp is normal, so we just compute its
       // exponent and construct it with a significand of zero.
@@ -645,6 +654,7 @@
     return ${Self}(sign: .plus,
       exponentBitPattern: 0,
       significandBitPattern: 1)
+%end
   }
 
   /// The least positive normal number.
@@ -917,17 +927,23 @@
   /// - If `x` is `greatestFiniteMagnitude`, then `x.nextUp` is `infinity`.
   @_inlineable // FIXME(sil-serialize-all)
   public var nextUp: ${Self} {
-    if isNaN { return self }
-    if sign == .minus {
+%if bits != 80:
+    // Silence signaling NaNs, map -0 to +0.
+    let x = self + 0
 #if arch(arm)
-      // On arm, subnormals are flushed to zero.
-      if (exponentBitPattern == 1 && significandBitPattern == 0) ||
-         (exponentBitPattern == 0 && significandBitPattern != 0) {
-        return ${Self}(sign: .minus,
-          exponentBitPattern: 0,
-          significandBitPattern: 0)
-      }
+    // On arm, treat subnormal values as zero.
+    if _slowPath(x == 0) { return .leastNonzeroMagnitude }
+    if _slowPath(x == -.leastNonzeroMagnitude) { return -0.0 }
 #endif
+    if _fastPath(x < .infinity) {
+      let increment = Int${bits}(bitPattern: x.bitPattern) &>> ${bits - 1} | 1
+      let bitPattern_ = x.bitPattern &+ UInt${bits}(bitPattern: increment)
+      return ${Self}(bitPattern: bitPattern_)
+    }
+    return x
+%else:
+    if isNaN { /* Silence signaling NaNs. */ return self + 0 }
+    if sign == .minus {
       if significandBitPattern == 0 {
         if exponentBitPattern == 0 {
           return .leastNonzeroMagnitude
@@ -946,15 +962,10 @@
         exponentBitPattern: exponentBitPattern + 1,
         significandBitPattern: 0)
     }
-#if arch(arm)
-    // On arm, subnormals are skipped.
-    if exponentBitPattern == 0 {
-      return .leastNonzeroMagnitude
-    }
-#endif
     return ${Self}(sign: .plus,
       exponentBitPattern: exponentBitPattern,
       significandBitPattern: significandBitPattern + 1)
+%end
   }
 
   /// Rounds the value to an integral value using the specified rounding rule.
@@ -1360,7 +1371,19 @@
   ///     // y.exponent == 4
   @_inlineable // FIXME(sil-serialize-all)
   public var binade: ${Self} {
-    if !isFinite { return .nan }
+%if bits != 80:
+    guard _fastPath(isFinite) else { return .nan }
+#if !arch(arm)
+    if _slowPath(isSubnormal) {
+      let bitPattern_ =
+        (self * 0x1p${SignificandBitCount}).bitPattern
+          & (-${Self}.infinity).bitPattern
+      return ${Self}(bitPattern: bitPattern_) * 0x1p-${SignificandBitCount}
+    }
+#endif
+    return ${Self}(bitPattern: bitPattern & (-${Self}.infinity).bitPattern)
+%else:
+    guard _fastPath(isFinite) else { return .nan }
     if exponentBitPattern != 0 {
       return ${Self}(sign: sign, exponentBitPattern: exponentBitPattern,
         significandBitPattern: 0)
@@ -1370,6 +1393,7 @@
     let index = significandBitPattern._binaryLogarithm()
     return ${Self}(sign: sign, exponentBitPattern: 0,
       significandBitPattern: 1 &<< index)
+%end
   }
 
   /// The number of bits required to represent the value's significand.
@@ -1481,6 +1505,7 @@
 %   if bits == builtinFloatLiteralBits:
     self = ${Self}(_bits: value)
 %   elif bits < builtinFloatLiteralBits:
+    // FIXME: This can result in double rounding errors (SR-7124).
     self = ${Self}(_bits: Builtin.fptrunc_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value))
 %   else:
     // FIXME: This is actually losing precision <rdar://problem/14073102>.
diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp
index af0d7fe..760dd58 100644
--- a/stdlib/public/runtime/Demangle.cpp
+++ b/stdlib/public/runtime/Demangle.cpp
@@ -495,14 +495,24 @@
       auto flags = func->getParameterFlags(i);
       auto input = _swift_buildDemanglingForMetadata(param, Dem);
 
-      if (flags.isInOut()) {
-        NodePointer inout = Dem.createNode(Node::Kind::InOut);
-        inout->addChild(input, Dem);
-        input = inout;
-      } else if (flags.isShared()) {
-        NodePointer shared = Dem.createNode(Node::Kind::Shared);
-        shared->addChild(input, Dem);
-        input = shared;
+      auto wrapInput = [&](Node::Kind kind) {
+        auto parent = Dem.createNode(kind);
+        parent->addChild(input, Dem);
+        input = parent;
+      };
+      switch (flags.getValueOwnership()) {
+      case ValueOwnership::Default:
+        /* nothing */
+        break;
+      case ValueOwnership::InOut:
+        wrapInput(Node::Kind::InOut);
+        break;
+      case ValueOwnership::Shared:
+        wrapInput(Node::Kind::Shared);
+        break;
+      case ValueOwnership::Owned:
+        wrapInput(Node::Kind::Owned);
+        break;
       }
 
       inputs.push_back({input, flags.isVariadic()});
diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift
index ed45e11..005ba6c 100644
--- a/test/Constraints/closures.swift
+++ b/test/Constraints/closures.swift
@@ -630,6 +630,7 @@
   let iter = I_33429010()
   var acc: Int = 0 // expected-warning {{}}
   let _: Int = AnySequence { iter }.rdar33429010(into: acc, { $0 + $1 })
+  // expected-warning@-1 {{result of operator '+' is unused}}
   let _: Int = AnySequence { iter }.rdar33429010(into: acc, { $0.rdar33429010_incr($1) })
 }
 
@@ -651,38 +652,3 @@
      str.replaceSubrange(range, with: str[range].reversed())
   }])
 }
-
-protocol P_37790062 {
-  associatedtype T
-  var elt: T { get }
-}
-
-func rdar37790062() {
-  struct S<T> {
-    init(_ a: () -> T, _ b: () -> T) {}
-  }
-
-  class C1 : P_37790062 {
-    typealias T = Int
-    var elt: T { return 42 }
-  }
-
-  class C2 : P_37790062 {
-    typealias T = (String, Int, Void)
-    var elt: T { return ("question", 42, ()) }
-  }
-
-  func foo() -> Int { return 42 }
-  func bar() -> Void {}
-  func baz() -> (String, Int) { return ("question", 42) }
-  func bzz<T>(_ a: T) -> T { return a }
-  func faz<T: P_37790062>(_ a: T) -> T.T { return a.elt }
-
-  _ = S({ foo() }, { bar() }) // Ok, should infer T to be 'Void'
-  _ = S({ baz() }, { bar() }) // Ok, should infer T to be 'Void'
-  _ = S({ bzz(("question", 42)) }, { bar() }) // Ok
-  _ = S({ bzz(String.self) }, { bar() }) // Ok
-  _ = S({ bzz(((), (()))) }, { bar() }) // Ok
-  _ = S({ bzz(C1()) }, { bar() }) // Ok
-  _ = S({ faz(C2()) }, { bar() }) // Ok
-}
diff --git a/test/Constraints/rdar37790062.swift b/test/Constraints/rdar37790062.swift
deleted file mode 100644
index 13d2f8c..0000000
--- a/test/Constraints/rdar37790062.swift
+++ /dev/null
@@ -1,46 +0,0 @@
-// RUN: %target-typecheck-verify-swift
-
-protocol A {
-  associatedtype V
-  associatedtype E: Error
-
-  init(value: V)
-  init(error: E)
-
-  func foo<U>(value: (V) -> U, error: (E) -> U) -> U
-}
-
-enum R<T, E: Error> : A {
-  case foo(T)
-  case bar(E)
-
-  init(value: T) { self = .foo(value) }
-  init(error: E) { self = .bar(error) }
-
-  func foo<R>(value: (T) -> R, error: (E) -> R) -> R {
-    fatalError()
-  }
-}
-
-protocol P {
-  associatedtype V
-
-  @discardableResult
-  func baz(callback: @escaping (V) -> Void) -> Self
-}
-
-class C<V> : P {
-  func baz(callback: @escaping (V) -> Void) -> Self { return self }
-}
-class D<T, E: Error> : C<R<T, E>> {
-  init(fn: (_ ret: @escaping (V) -> Void) -> Void) {}
-}
-
-extension A where V: P, V.V: A, E == V.V.E {
-  func bar() -> D<V.V.V, V.V.E> {
-    return D { complete in
-      foo(value: { promise in promise.baz { result in } },
-          error: { complete(R(error: $0)) })
-    }
-  }
-}
diff --git a/test/IRGen/objc_retainAutoreleasedReturnValue.swift b/test/IRGen/objc_retainAutoreleasedReturnValue.swift
index 204c791..a8d1a27 100644
--- a/test/IRGen/objc_retainAutoreleasedReturnValue.swift
+++ b/test/IRGen/objc_retainAutoreleasedReturnValue.swift
@@ -24,15 +24,13 @@
 // popq   %rbp  ;<== Blocks the handshake from objc_autoreleaseReturnValue
 // jmp    0x01ec20 ; symbol stub for: objc_retainAutoreleasedReturnValue
 
-// CHECK-LABEL: define {{.*}}swiftcc %TSo12NSEnumeratorC* @"$S34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFSo12NSEnumeratorCADXEfU_"(%TSo12NSDictionaryC*)
+// CHECK-LABEL: define {{.*}}swiftcc void @"$S34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFyADXEfU_"(%TSo12NSDictionaryC*)
 // CHECK: entry:
 // CHECK:   call {{.*}}@objc_msgSend
 // CHECK:   notail call i8* @objc_retainAutoreleasedReturnValue
-// CHECK:   ret %TSo12NSEnumeratorC*
+// CHECK:   ret void
 
-// CHECK-LABEL: define {{.*}}swiftcc void @"$SSo12NSDictionaryCSo12NSEnumeratorCIgxo_ABIegx_TR"(%TSo12NSDictionaryC*, i8*, %swift.opaque*)
-
-// OPT-LABEL: define {{.*}}swiftcc void @"$S34objc_retainAutoreleasedReturnValue10useClosureyySo12NSDictionaryC_yADXEtF06$SSo12h44CSo12NSEnumeratorCIgxo_ABIegx_TR049$S34objc_bcD42Value4testyySo12a6CFSo12B8CADXEfU_Tf3npf_nTf1nc_nTf4g_n"(%TSo12NSDictionaryC*)
+// OPT-LABEL: define {{.*}}swiftcc void @"$S34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFyADXEfU_"(%TSo12NSDictionaryC*)
 // OPT: entry:
 // OPT:   call {{.*}}@objc_msgSend
 // OPT:   notail call i8* @objc_retainAutoreleasedReturnValue
diff --git a/test/Interpreter/protocol_initializers.swift b/test/Interpreter/protocol_initializers.swift
index 48826cf..513fa36 100644
--- a/test/Interpreter/protocol_initializers.swift
+++ b/test/Interpreter/protocol_initializers.swift
@@ -4,6 +4,9 @@
 // RUN: %target-run %t/a.out
 // REQUIRES: executable_test
 
+// FIXME: <https://bugs.swift.org/browse/SR-7138> 2 tests are failing on linux in optimized mode
+// UNSUPPORTED: OS=linux-gnu
+
 import StdlibUnittest
 
 var ProtocolInitTestSuite = TestSuite("ProtocolInit")
diff --git a/test/Parse/invalid.swift b/test/Parse/invalid.swift
index fdfe9b3..3cb9fc7 100644
--- a/test/Parse/invalid.swift
+++ b/test/Parse/invalid.swift
@@ -13,9 +13,9 @@
 // expected-error @-1 {{'__shared' before a parameter name is not allowed, place it before the parameter type instead}} {{13-21=}} {{30-30=__shared }}
 
 func test1o(__owned var x : Int) {}  // expected-error {{parameter must not have multiple '__owned', 'inout', '__shared', 'var', or 'let' specifiers}} {{21-25=}}
-// expected-error @-1 {{'__owned' as a parameter attribute is not allowed}} {{13-20=}}
+// expected-error @-1 {{'__owned' before a parameter name is not allowed, place it before the parameter type instead}} {{13-20=}}
 func test2o(__owned let x : Int) {}  // expected-error {{parameter must not have multiple '__owned', 'inout', '__shared', 'var', or 'let' specifiers}} {{21-25=}}
-// expected-error @-1 {{'__owned' as a parameter attribute is not allowed}} {{13-20=}}
+// expected-error @-1 {{'__owned' before a parameter name is not allowed, place it before the parameter type instead}} {{13-20=}}
 
 func test3() {
   undeclared_func( // expected-error {{use of unresolved identifier 'undeclared_func'}}
diff --git a/test/SILGen/keypath_property_descriptors.swift b/test/SILGen/keypath_property_descriptors.swift
new file mode 100644
index 0000000..61f306d
--- /dev/null
+++ b/test/SILGen/keypath_property_descriptors.swift
@@ -0,0 +1,80 @@
+// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+
+// TODO: globals should get descriptors
+public var a: Int = 0
+
+@_inlineable
+public var b: Int { return 0 }
+
+@_versioned
+internal var c: Int = 0
+
+// no descriptor
+// CHECK-NOT: sil_property #d
+internal var d: Int = 0
+// CHECK-NOT: sil_property #e
+private var e: Int = 0
+
+public struct A {
+  // CHECK-LABEL: sil_property #A.a
+  public var a: Int = 0
+
+  // CHECK-LABEL: sil_property #A.b
+  @_inlineable
+  public var b: Int { return 0 }
+
+  // CHECK-LABEL: sil_property #A.c
+  @_versioned
+  internal var c: Int = 0
+
+  // no descriptor
+  // CHECK-NOT: sil_property #A.d
+  internal var d: Int = 0
+  // CHECK-NOT: sil_property #A.e
+  fileprivate var e: Int = 0
+  // CHECK-NOT: sil_property #A.f
+  private var f: Int = 0
+
+  // TODO: static vars should get descriptors
+  public static var a: Int = 0
+  @_inlineable
+  public static var b: Int { return 0 }
+  @_versioned
+  internal static var c: Int = 0
+
+  // no descriptor
+  // CHECK-NOT: sil_property #A.d
+  internal static var d: Int = 0
+  // CHECK-NOT: sil_property #A.e
+  fileprivate static var e: Int = 0
+  // CHECK-NOT: sil_property #A.f
+  private static var f: Int = 0
+
+  // CHECK-LABEL: sil_property #A.subscript
+  public subscript(a x: Int) -> Int { return x }
+  // CHECK-LABEL: sil_property #A.subscript
+  @_inlineable
+  public subscript(b x: Int) -> Int { return x }
+  // CHECK-LABEL: sil_property #A.subscript
+  @_versioned
+  internal subscript(c x: Int) -> Int { return x }
+  
+  // no descriptor
+  // CHECK-NOT: sil_property #A.subscript
+  internal subscript(d x: Int) -> Int { return x }
+  fileprivate subscript(e x: Int) -> Int { return x }
+  private subscript(f x: Int) -> Int { return x }
+
+  // TODO: Subscripts with non-hashable subscripts should get descriptors
+  public subscript<T>(a x: T) -> T { return x }
+  @_inlineable
+  public subscript<T>(b x: T) -> T { return x }
+  @_versioned
+  internal subscript<T>(c x: T) -> T { return x }
+  
+  // no descriptor
+  internal subscript<T>(d x: T) -> T { return x }
+  fileprivate subscript<T>(e x: T) -> T { return x }
+  private subscript<T>(f x: T) -> T { return x }
+}
+
diff --git a/test/SILGen/owned.swift b/test/SILGen/owned.swift
new file mode 100644
index 0000000..bee04be
--- /dev/null
+++ b/test/SILGen/owned.swift
@@ -0,0 +1,24 @@
+// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -emit-silgen %s -disable-objc-attr-requires-foundation-module -enable-sil-ownership -enable-guaranteed-normal-arguments | %FileCheck %s
+
+// see shared.swift for thunks/conversions between __shared and __owned.
+
+class RefAggregate {}
+struct ValueAggregate { let x = RefAggregate() }
+
+// CHECK-LABEL: sil hidden @$S5owned0A10_arguments7trivial5value3refySin_AA14ValueAggregateVnAA03RefG0CntF : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> () {
+func owned_arguments(trivial : __owned Int, value : __owned ValueAggregate, ref : __owned RefAggregate) {
+    let t = trivial
+    let v = value
+    let r = ref
+}
+
+struct Foo {
+    var x: ValueAggregate
+
+    // CHECK-LABEL: sil hidden @$S5owned3FooV20methodOwnedArguments7trivial5value3refySin_AA14ValueAggregateVnAA03RefJ0CntF : $@convention(method) (Int, @owned ValueAggregate, @owned RefAggregate, @guaranteed Foo) -> () {
+    func methodOwnedArguments(trivial : __owned Int, value : __owned ValueAggregate, ref : __owned RefAggregate) {
+        let t = trivial
+        let v = value
+        let r = ref
+    }
+}
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 0f4a3af..b87ca63 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -1522,8 +1522,8 @@
 sil @eliminate_thin_to_thick_apply : $@convention(thin) () -> () {
 bb0:
   %0 = function_ref @eliminate_dead_thin_to_thick_function_fun : $@convention(thin) () -> ()
-  %1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_guaranteed () -> ()
-  %2 = apply %1() : $@callee_guaranteed () -> ()
+  %1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_owned () -> ()
+  %2 = apply %1() : $@callee_owned () -> ()
   return %2 : $()
 }
 
diff --git a/test/SILOptimizer/sil_combine_apply.sil b/test/SILOptimizer/sil_combine_apply.sil
index d091147..241c6a7 100644
--- a/test/SILOptimizer/sil_combine_apply.sil
+++ b/test/SILOptimizer/sil_combine_apply.sil
@@ -517,56 +517,3 @@
   %return = tuple ()
   return %return : $()
 }
-
-sil shared [transparent] [thunk] @genericClosure : $@convention(thin) <T> (@in T) -> @out T {
-bb0(%0 : $*T, %1 : $*T):
-  %12 = tuple ()
-  return %12 : $()
-}
-
-// CHECK-LABEL: sil shared @genericThinToThick : $@convention(thin) () -> ()
-// CHECK: [[F:%.*]] = function_ref @genericClosure : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @out τ_0_0
-// CHECK: apply [[F]]<Builtin.Int64>(%{{.*}}, %{{.*}}) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @out τ_0_0
-// CHECK-LABEL: } // end sil function 'genericThinToThick'
-sil shared @genericThinToThick : $@convention(thin) () -> () {
-bb0:
-  %fn = function_ref @genericClosure : $@convention(thin) <T> (@in T) -> @out T
-  %thick = thin_to_thick_function %fn : $@convention(thin) <T> (@in T) -> @out T to $@noescape @callee_guaranteed <T> (@in T) -> @out T
-  %in = alloc_stack $Builtin.Int64
-  %out = alloc_stack $Builtin.Int64
-  %c3 = integer_literal $Builtin.Int64, 3
-  store %c3 to %in : $*Builtin.Int64
-  %call = apply %thick<Builtin.Int64>(%out, %in) : $@noescape @callee_guaranteed <T> (@in T) -> @out T
-  dealloc_stack %out : $*Builtin.Int64
-  dealloc_stack %in : $*Builtin.Int64
-  %999 = tuple ()
-  return %999 : $()
-}
-
-sil shared [transparent] [thunk] @indirectClosure : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64 {
-bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64):
-  %val = load %1 : $*Builtin.Int64
-  store %val to %0 : $*Builtin.Int64
-  %999 = tuple ()
-  return %999 : $()
-}
-
-// CHECK-LABEL: sil shared @appliedEscapeToNoEscape : $@convention(thin) () -> () {
-// CHECK: [[F:%.*]] = function_ref @indirectClosure : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64 // user: %5
-// CHECK: apply [[F]](%{{.*}}, %{{.*}}) : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
-sil shared @appliedEscapeToNoEscape : $@convention(thin) () -> () {
-bb0:
-  %fn = function_ref @indirectClosure : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
-  %pa = partial_apply [callee_guaranteed] %fn() : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
-  %cvt = convert_escape_to_noescape %pa : $@callee_guaranteed (@in Builtin.Int64) -> @out Builtin.Int64 to $@noescape @callee_guaranteed (@in Builtin.Int64) -> @out Builtin.Int64
-  %out = alloc_stack $Builtin.Int64
-  %in = alloc_stack $Builtin.Int64
-  %c3 = integer_literal $Builtin.Int64, 3
-  store %c3 to %in : $*Builtin.Int64
-  %call = apply %cvt(%out, %in) : $@noescape @callee_guaranteed (@in Builtin.Int64) -> @out Builtin.Int64
-  dealloc_stack %in : $*Builtin.Int64
-  dealloc_stack %out : $*Builtin.Int64
-  strong_release %pa : $@callee_guaranteed (@in Builtin.Int64) -> @out Builtin.Int64
-  %999 = tuple ()
-  return %999 : $()
-}
diff --git a/test/SwiftSyntax/Inputs/closure.swift b/test/SwiftSyntax/Inputs/closure.swift
new file mode 100644
index 0000000..64b2c2a
--- /dev/null
+++ b/test/SwiftSyntax/Inputs/closure.swift
@@ -0,0 +1,3 @@
+// A closure without a signature. The test will ensure it stays the same after
+// applying a rewriting pass.
+let x: () -> Void = {}
\ No newline at end of file
diff --git a/test/SwiftSyntax/VisitorTest.swift b/test/SwiftSyntax/VisitorTest.swift
index 4a8ade8..7d9b0ae 100644
--- a/test/SwiftSyntax/VisitorTest.swift
+++ b/test/SwiftSyntax/VisitorTest.swift
@@ -37,4 +37,20 @@
   })
 }
 
+VisitorTests.test("RewritingNodeWithEmptyChild") {
+  class ClosureRewriter: SyntaxRewriter {
+    override func visit(_ node: ClosureExprSyntax) -> ExprSyntax {
+      // Perform a no-op transform that requires rebuilding the node.
+      return node.withSignature(node.signature)
+    }
+  }
+  expectDoesNotThrow({
+    let parsed = try SourceFileSyntax.decodeSourceFileSyntax(try
+      SwiftLang.parse(getInput("closure.swift")))
+    let rewriter = ClosureRewriter()
+    let rewritten = rewriter.visit(parsed)
+    expectEqual(parsed.description, rewritten.description)
+  })
+}
+
 runAllTests()
diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift
index 2539461..6d043e9 100644
--- a/test/expr/closure/closures.swift
+++ b/test/expr/closure/closures.swift
@@ -259,6 +259,7 @@
 func takesVoidFunc(_ f: () -> ()) {}
 var i: Int = 1
 
+// expected-warning @+1 {{expression of type 'Int' is unused}}
 takesVoidFunc({i})
 // expected-warning @+1 {{expression of type 'Int' is unused}}
 var f1: () -> () = {i}
diff --git a/test/stdlib/ErrorHandling.swift b/test/stdlib/ErrorHandling.swift
index ea5d427..a45d0a6 100644
--- a/test/stdlib/ErrorHandling.swift
+++ b/test/stdlib/ErrorHandling.swift
@@ -1,6 +1,9 @@
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 
+// FIXME: <https://bugs.swift.org/browse/SR-7138> 2 tests are failing on linux in optimized mode
+// UNSUPPORTED: OS=linux-gnu
+
 //
 // Tests for error handling in standard library APIs.
 //
diff --git a/test/stdlib/FloatingPoint.swift.gyb b/test/stdlib/FloatingPoint.swift.gyb
index 9b23ece..24cd535 100644
--- a/test/stdlib/FloatingPoint.swift.gyb
+++ b/test/stdlib/FloatingPoint.swift.gyb
@@ -529,7 +529,6 @@
 %end
 
 let floatNextUpDownTests: [(Float, Float)] = [
-  (.nan, .nan),
   (.greatestFiniteMagnitude, .infinity),
   (0x1.ffff_fe__p-1, 1.0), (1.0, 0x1.0000_02__p+0),
   (0.0, .leastNonzeroMagnitude),
@@ -553,7 +552,6 @@
 }
 
 let doubleNextUpDownTests: [(Double, Double)] = [
-  (.nan, .nan),
   (.greatestFiniteMagnitude, .infinity),
   (0x1.ffff_ffff_ffff_fp-1, 1.0), (1.0, 0x1.0000_0000_0000_1p+0),
   (0.0, .leastNonzeroMagnitude),
@@ -576,6 +574,16 @@
   expectBitwiseEqual(-prev, (-succ).nextUp)
 }
 
+%for Self in ['Float', 'Double']:
+FloatingPoint.test("${Self}.nextUp, .nextDown/nan") {
+  let x = ${Self}.nan
+  expectBitwiseEqual(x, x.nextUp)
+  expectBitwiseEqual(x, x.nextDown)
+  expectTrue((-x).nextDown.isNaN)
+  expectTrue((-x).nextUp.isNaN)
+}
+%end
+
 #if arch(i386) || arch(x86_64)
 
 FloatingPoint.test("Float80/ExpressibleByIntegerLiteral") {
diff --git a/test/type/types.swift b/test/type/types.swift
index c542f0c..f03fcca 100644
--- a/test/type/types.swift
+++ b/test/type/types.swift
@@ -51,8 +51,8 @@
   var bad_is : (Int) -> (__shared Int, Int)  // expected-error {{'__shared' may only be used on parameters}}
   func bad_is2(_ a: (__shared Int, Int)) {}    // expected-error {{'__shared' may only be used on parameters}}
   
-  var bad_iow : (Int) -> (__owned Int, Int)
-  func bad_iow2(_ a: (__owned Int, Int)) {}
+  var bad_iow : (Int) -> (__owned Int, Int)  // expected-error {{'__owned' may only be used on parameters}}
+  func bad_iow2(_ a: (__owned Int, Int)) {}  // expected-error {{'__owned' may only be used on parameters}}
 }
 
 // <rdar://problem/15588967> Array type sugar default construction syntax doesn't work
diff --git a/tools/SwiftSyntax/CMakeLists.txt b/tools/SwiftSyntax/CMakeLists.txt
index f098baf..ed83610 100644
--- a/tools/SwiftSyntax/CMakeLists.txt
+++ b/tools/SwiftSyntax/CMakeLists.txt
@@ -21,7 +21,7 @@
   SyntaxNodes.swift.gyb
   SyntaxRewriter.swift.gyb
   TokenKind.swift.gyb
-  Trivia.swift
+  Trivia.swift.gyb
 
   SWIFT_MODULE_DEPENDS Foundation
   INSTALL_IN_COMPONENT swift-syntax
diff --git a/tools/SwiftSyntax/Syntax.swift b/tools/SwiftSyntax/Syntax.swift
index 33595f2..efce76f 100644
--- a/tools/SwiftSyntax/Syntax.swift
+++ b/tools/SwiftSyntax/Syntax.swift
@@ -68,6 +68,12 @@
     return SyntaxChildren(node: self)
   }
 
+  /// The number of children, `present` or `missing`, in this node.
+  /// This value can be used safely with `child(at:)`.
+  public var numberOfChildren: Int {
+    return data.childCaches.count
+  }
+
   /// Whether or not this node it marked as `present`.
   public var isPresent: Bool {
     return raw.presence == .present
diff --git a/tools/SwiftSyntax/SyntaxRewriter.swift.gyb b/tools/SwiftSyntax/SyntaxRewriter.swift.gyb
index 15ba796..ea5ecce 100644
--- a/tools/SwiftSyntax/SyntaxRewriter.swift.gyb
+++ b/tools/SwiftSyntax/SyntaxRewriter.swift.gyb
@@ -64,7 +64,17 @@
   }
 
   func visitChildren(_ node: Syntax) -> Syntax {
-    let newLayout = node.children.map { visit($0).raw }
+    // Visit all children of this node, returning `nil` if child is not
+    // present. This will ensure that there are always the same number
+    // of children after transforming.
+    let newLayout = (0..<node.numberOfChildren).map { (i: Int) -> RawSyntax? in
+      guard let child = node.child(at: i) else { return nil }
+      return visit(child).raw
+    }
+
+    // Sanity check, ensure the new children are the same length.
+    assert(newLayout.count == node.raw.layout.count)
+
     return makeSyntax(node.raw.replacingLayout(newLayout))
   }
 }
diff --git a/tools/SwiftSyntax/Trivia.swift b/tools/SwiftSyntax/Trivia.swift
deleted file mode 100644
index 1a78a40..0000000
--- a/tools/SwiftSyntax/Trivia.swift
+++ /dev/null
@@ -1,401 +0,0 @@
-//===------------------- Trivia.swift - Source Trivia Enum ----------------===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-
-import Foundation
-
-/// A contiguous stretch of a single kind of trivia. The constituent part of
-/// a `Trivia` collection.
-///
-/// For example, four spaces would be represented by
-/// `.spaces(4)`
-///
-/// In general, you should deal with the actual Trivia collection instead
-/// of individual pieces whenever possible.
-public enum TriviaPiece: Codable {
-  enum CodingKeys: CodingKey {
-    case kind, value
-  }
-  public init(from decoder: Decoder) throws {
-    let container = try decoder.container(keyedBy: CodingKeys.self)
-    let kind = try container.decode(String.self, forKey: .kind)
-    switch kind {
-    case "Space":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .spaces(value)
-    case "Tab":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .tabs(value)
-    case "VerticalTab":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .verticalTabs(value)
-    case "Formfeed":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .formfeeds(value)
-    case "Newline":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .newlines(value)
-    case "CarriageReturn":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .carriageReturns(value)
-    case "CarriageReturnLineFeed":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .carriageReturnLineFeeds(value)
-    case "Backtick":
-      let value = try container.decode(Int.self, forKey: .value)
-      self = .backticks(value)
-    case "LineComment":
-      let value = try container.decode(String.self, forKey: .value)
-      self = .lineComment(value)
-    case "BlockComment":
-      let value = try container.decode(String.self, forKey: .value)
-      self = .blockComment(value)
-    case "DocLineComment":
-      let value = try container.decode(String.self, forKey: .value)
-      self = .docLineComment(value)
-    case "DocBlockComment":
-      let value = try container.decode(String.self, forKey: .value)
-      self = .docLineComment(value)
-    case "GarbageText":
-      let value = try container.decode(String.self, forKey: .value)
-      self = .garbageText(value)
-    default:
-      let context =
-        DecodingError.Context(codingPath: [CodingKeys.kind],
-                              debugDescription: "invalid TriviaPiece kind \(kind)")
-      throw DecodingError.valueNotFound(String.self, context)
-    }
-  }
-
-  public func encode(to encoder: Encoder) throws {
-    var container = encoder.container(keyedBy: CodingKeys.self)
-    switch self {
-    case .blockComment(let comment):
-      try container.encode("BlockComment", forKey: .kind)
-      try container.encode(comment, forKey: .value)
-    case .docBlockComment(let comment):
-      try container.encode("DocBlockComment", forKey: .kind)
-      try container.encode(comment, forKey: .value)
-    case .docLineComment(let comment):
-      try container.encode("DocLineComment", forKey: .kind)
-      try container.encode(comment, forKey: .value)
-    case .lineComment(let comment):
-      try container.encode("LineComment", forKey: .kind)
-      try container.encode(comment, forKey: .value)
-    case .garbageText(let text):
-      try container.encode("GarbageText", forKey: .kind)
-      try container.encode(text, forKey: .value)
-    case .formfeeds(let count):
-      try container.encode("Formfeed", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .backticks(let count):
-      try container.encode("Backtick", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .newlines(let count):
-      try container.encode("Newline", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .carriageReturns(let count):
-      try container.encode("CarriageReturn", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .carriageReturnLineFeeds(let count):
-      try container.encode("CarriageReturnLineFeeds", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .spaces(let count):
-      try container.encode("Space", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .tabs(let count):
-      try container.encode("Tab", forKey: .kind)
-      try container.encode(count, forKey: .value)
-    case .verticalTabs(let count):
-      try container.encode("VerticalTab", forKey: .kind)
-      try container.encode(count, forKey: .value)
-
-    }
-  }
-
-  /// A space ' ' character.
-  case spaces(Int)
-
-  /// A tab '\t' character.
-  case tabs(Int)
-
-  /// A vertical tab '\v' character.
-  case verticalTabs(Int)
-
-  /// A form-feed '\f' character.
-  case formfeeds(Int)
-
-  /// A newline '\n' character.
-  case newlines(Int)
-
-  /// A carriage-return '\r' character.
-  case carriageReturns(Int)
-  
-  /// A newline two bytes sequence consists of '\r' and '\n' characters.
-  case carriageReturnLineFeeds(Int)
-
-  /// A backtick '`' character, used to escape identifiers.
-  case backticks(Int)
-
-  /// A developer line comment, starting with '//'
-  case lineComment(String)
-
-  /// A developer block comment, starting with '/*' and ending with '*/'.
-  case blockComment(String)
-
-  /// A documentation line comment, starting with '///'.
-  case docLineComment(String)
-
-  /// A documentation block comment, starting with '/**' and ending with '*/.
-  case docBlockComment(String)
-
-  /// Any skipped text.
-  case garbageText(String)
-}
-
-extension TriviaPiece: TextOutputStreamable {
-  /// Prints the provided trivia as they would be written in a source file.
-  ///
-  /// - Parameter stream: The stream to which to print the trivia.
-  public func write<Target>(to target: inout Target)
-    where Target: TextOutputStream {
-    func printRepeated(_ character: String, count: Int) {
-      for _ in 0..<count { target.write(character) }
-    }
-    switch self {
-    case let .spaces(count): printRepeated(" ", count: count)
-    case let .tabs(count): printRepeated("\t", count: count)
-    case let .verticalTabs(count): printRepeated("\u{2B7F}", count: count)
-    case let .formfeeds(count): printRepeated("\u{240C}", count: count)
-    case let .newlines(count): printRepeated("\n", count: count)
-    case let .carriageReturns(count): printRepeated("\r", count: count)
-    case let .carriageReturnLineFeeds(count): printRepeated("\r\n", count: count)
-    case let .backticks(count): printRepeated("`", count: count)
-    case let .lineComment(text),
-         let .blockComment(text),
-         let .docLineComment(text),
-         let .docBlockComment(text),
-         let .garbageText(text):
-      target.write(text)
-    }
-  }
-
-  /// Computes the information from this trivia to inform the source locations
-  /// of the associated tokens.
-  /// Specifically, walks through the trivia and keeps track of every newline
-  /// to give a number of how many newlines and UTF8 characters appear in the
-  /// trivia, along with the UTF8 offset of the last column.
-  func characterSizes() -> (lines: Int, lastColumn: Int, utf8Length: Int) {
-    switch self {
-    case .spaces(let n),
-         .tabs(let n),
-         .verticalTabs(let n),
-         .formfeeds(let n),
-         .backticks(let n):
-      return (lines: 0, lastColumn: n, utf8Length: n)
-    case .newlines(let n):
-      return (lines: n, lastColumn: 0, utf8Length: n)
-    case .carriageReturns(let n):
-      return (lines: n, lastColumn: 0, utf8Length: n)
-    case .carriageReturnLineFeeds(let n):
-      return (lines: n, lastColumn: 0, utf8Length: n * 2)
-    case .lineComment(let text),
-         .docLineComment(let text):
-      let length = text.utf8.count
-      return (lines: 0, lastColumn: length, utf8Length: length)
-    case .blockComment(let text),
-         .docBlockComment(let text),
-         .garbageText(let text):
-      var lines = 0
-      var col = 0
-      var total = 0
-      var prevChar: UInt8? = nil
-      // TODO: CR + LF should be regarded as one newline
-      for char in text.utf8 {
-        total += 1
-        switch char {
-        case 0x0a:
-          if prevChar == 0x0d {
-            /* ASCII CR LF */
-            assert(col == 0)
-          } else {
-            /* ASCII newline */
-            col = 0
-            lines += 1
-          }
-        /* ASCII carriage-return */
-        case 0x0d:
-          col = 0
-          lines += 1
-        
-        default:
-          col += 1
-        }
-        prevChar = char
-      }
-      return (lines: lines, lastColumn: col, utf8Length: total)
-    }
-  }
-}
-
-/// A collection of leading or trailing trivia. This is the main data structure
-/// for thinking about trivia.
-public struct Trivia: Codable {
-  let pieces: [TriviaPiece]
-
-  /// Creates Trivia with the provided underlying pieces.
-  public init(pieces: [TriviaPiece]) {
-    self.pieces = pieces
-  }
-
-  public init(from decoder: Decoder) throws {
-    var container = try decoder.unkeyedContainer()
-    var pieces = [TriviaPiece]()
-    while let piece = try container.decodeIfPresent(TriviaPiece.self) {
-      pieces.append(piece)
-    }
-    self.pieces = pieces
-  }
-
-  public func encode(to encoder: Encoder) throws {
-    var container = encoder.unkeyedContainer()
-    for piece in pieces {
-      try container.encode(piece)
-    }
-  }
-
-  /// Creates Trivia with no pieces.
-  public static var zero: Trivia {
-    return Trivia(pieces: [])
-  }
-
-  /// Creates a new `Trivia` by appending the provided `TriviaPiece` to the end.
-  public func appending(_ piece: TriviaPiece) -> Trivia {
-    var copy = pieces
-    copy.append(piece)
-    return Trivia(pieces: copy)
-  }
-
-  /// Return a piece of trivia for some number of space characters in a row.
-  public static func spaces(_ count: Int) -> Trivia {
-    return [.spaces(count)]
-  }
-
-  /// Return a piece of trivia for some number of tab characters in a row.
-  public static func tabs(_ count: Int) -> Trivia {
-    return [.tabs(count)]
-  }
-
-  /// A vertical tab '\v' character.
-  public static func verticalTabs(_ count: Int) -> Trivia {
-    return [.verticalTabs(count)]
-  }
-
-  /// A form-feed '\f' character.
-  public static func formfeeds(_ count: Int) -> Trivia {
-    return [.formfeeds(count)]
-  }
-
-  /// Return a piece of trivia for some number of newline characters
-  /// in a row.
-  public static func newlines(_ count: Int) -> Trivia {
-    return [.newlines(count)]
-  }
-
-  /// Return a piece of trivia for some number of carriage-return characters
-  /// in a row.
-  public static func carriageReturns(_ count: Int) -> Trivia {
-    return [.carriageReturns(count)]
-  }
-
-  /// Return a piece of trivia for some number of two bytes sequence
-  /// consists of CR and LF in a row.
-  public static func carriageReturnLineFeeds(_ count: Int) -> Trivia {
-    return [.carriageReturnLineFeeds(count)]
-  }
-
-  /// Return a piece of trivia for some number of backtick '`' characters
-  /// in a row.
-  public static func backticks(_ count: Int) -> Trivia {
-    return [.backticks(count)]
-  }
-
-  /// Return a piece of trivia for a single line of ('//') developer comment.
-  public static func lineComment(_ text: String) -> Trivia {
-    return [.lineComment(text)]
-  }
-
-  /// Return a piece of trivia for a block comment ('/* ... */')
-  public static func blockComment(_ text: String) -> Trivia {
-    return [.blockComment(text)]
-  }
-
-  /// Return a piece of trivia for a single line of ('///') doc comment.
-  public static func docLineComment(_ text: String) -> Trivia {
-    return [.docLineComment(text)]
-  }
-
-  /// Return a piece of trivia for a documentation block comment ('/** ... */')
-  public static func docBlockComment(_ text: String) -> Trivia {
-    return [.docBlockComment(text)]
-  }
-
-  /// Return a piece of trivia for any garbage text.
-  public static func garbageText(_ text: String) -> Trivia {
-    return [.garbageText(text)]
-  }
-
-  /// Computes the total sizes and offsets of all pieces in this Trivia.
-  func characterSizes() -> (lines: Int, lastColumn: Int, utf8Length: Int) {
-    var lines = 0
-    var lastColumn = 0
-    var length = 0
-    for piece in pieces {
-      let (ln, col, len) = piece.characterSizes()
-      lines += ln
-      lastColumn = col
-      length += len
-    }
-    return (lines: lines, lastColumn: lastColumn, utf8Length: length)
-  }
-}
-
-/// Conformance for Trivia to the Collection protocol.
-extension Trivia: Collection {
-  public var startIndex: Int {
-    return pieces.startIndex
-  }
-
-  public var endIndex: Int {
-    return pieces.endIndex
-  }
-
-  public func index(after i: Int) -> Int {
-    return pieces.index(after: i)
-  }
-
-  public subscript(_ index: Int) -> TriviaPiece {
-    return pieces[index]
-  }
-}
-
-
-extension Trivia: ExpressibleByArrayLiteral {
-  /// Creates Trivia from the provided pieces.
-  public init(arrayLiteral elements: TriviaPiece...) {
-    self.pieces = elements
-  }
-}
-
-/// Concatenates two collections of `Trivia` into one collection.
-public func +(lhs: Trivia, rhs: Trivia) -> Trivia {
-  return Trivia(pieces: lhs.pieces + rhs.pieces)
-}
diff --git a/tools/SwiftSyntax/Trivia.swift.gyb b/tools/SwiftSyntax/Trivia.swift.gyb
new file mode 100644
index 0000000..29f765b
--- /dev/null
+++ b/tools/SwiftSyntax/Trivia.swift.gyb
@@ -0,0 +1,258 @@
+%{
+  # -*- mode: Swift -*-
+  from gyb_syntax_support.Trivia import TRIVIAS
+  # Ignore the following admonition it applies to the resulting .swift file only
+}%
+//// Automatically Generated From Trivia.swift.gyb.
+//// Do Not Edit Directly!
+//===------------------- Trivia.swift - Source Trivia Enum ----------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+import Foundation
+
+/// A contiguous stretch of a single kind of trivia. The constituent part of
+/// a `Trivia` collection.
+///
+/// For example, four spaces would be represented by
+/// `.spaces(4)`
+///
+/// In general, you should deal with the actual Trivia collection instead
+/// of individual pieces whenever possible.
+public enum TriviaPiece: Codable {
+  enum CodingKeys: CodingKey {
+    case kind, value
+  }
+  public init(from decoder: Decoder) throws {
+    let container = try decoder.container(keyedBy: CodingKeys.self)
+    let kind = try container.decode(String.self, forKey: .kind)
+    switch kind {
+% for trivia in TRIVIAS:
+    case "${trivia.name}":
+%   if trivia.is_collection():
+      let value = try container.decode(Int.self, forKey: .value)
+      self = .${trivia.lower_name}s(value)
+%   else:
+      let value = try container.decode(String.self, forKey: .value)
+      self = .${trivia.lower_name}(value)
+%   end
+% end
+    default:
+      let context =
+        DecodingError.Context(codingPath: [CodingKeys.kind],
+                              debugDescription: "invalid TriviaPiece kind \(kind)")
+      throw DecodingError.valueNotFound(String.self, context)
+    }
+  }
+
+  public func encode(to encoder: Encoder) throws {
+    var container = encoder.container(keyedBy: CodingKeys.self)
+    switch self {
+% for trivia in TRIVIAS:
+%   if trivia.is_collection():
+    case .${trivia.lower_name}s(let count):
+      try container.encode("${trivia.name}", forKey: .kind)
+      try container.encode(count, forKey: .value)
+%   else:
+    case .${trivia.lower_name}(let text):
+      try container.encode("${trivia.name}", forKey: .kind)
+      try container.encode(text, forKey: .value)
+%   end
+% end
+    }
+  }
+
+% for trivia in TRIVIAS:
+    /// ${trivia.comment}
+%   if trivia.is_collection():
+    case ${trivia.lower_name}s(Int)
+%   else:
+    case ${trivia.lower_name}(String)
+%   end
+% end
+}
+
+extension TriviaPiece: TextOutputStreamable {
+  /// Prints the provided trivia as they would be written in a source file.
+  ///
+  /// - Parameter stream: The stream to which to print the trivia.
+  public func write<Target>(to target: inout Target)
+    where Target: TextOutputStream {
+    func printRepeated(_ character: String, count: Int) {
+      for _ in 0..<count { target.write(character) }
+    }
+    switch self {
+% for trivia in TRIVIAS:
+%   if trivia.is_collection():
+%   joined = ''.join(trivia.swift_characters)
+    case let .${trivia.lower_name}s(count):
+      printRepeated("${joined}", count: count)
+%   else:
+    case let .${trivia.lower_name}(text):
+      target.write(text)
+%   end
+% end
+    }
+  }
+
+  /// Computes the information from this trivia to inform the source locations
+  /// of the associated tokens.
+  /// Specifically, walks through the trivia and keeps track of every newline
+  /// to give a number of how many newlines and UTF8 characters appear in the
+  /// trivia, along with the UTF8 offset of the last column.
+  func characterSizes() -> (lines: Int, lastColumn: Int, utf8Length: Int) {
+    func calculateTextSizes(_ text: String) ->
+        (lines: Int, lastColumn: Int, utf8Length: Int) {
+      var lines = 0
+      var col = 0
+      var total = 0
+      var prevChar: UInt8? = nil
+      // TODO: CR + LF should be regarded as one newline
+      for char in text.utf8 {
+        total += 1
+        switch char {
+        case 0x0a:
+          if prevChar == 0x0d {
+            /* ASCII CR LF */
+            assert(col == 0)
+          } else {
+            /* ASCII newline */
+            col = 0
+            lines += 1
+          }
+        /* ASCII carriage-return */
+        case 0x0d:
+          col = 0
+          lines += 1
+
+        default:
+          col += 1
+        }
+        prevChar = char
+      }
+      return (lines: lines, lastColumn: col, utf8Length: total)
+    }
+    switch self {
+% for trivia in TRIVIAS:
+%   if trivia.is_new_line:
+    case let .${trivia.lower_name}s(n):
+      return (lines: n, lastColumn: 0, utf8Length: n * ${trivia.characters_len()})
+%   elif trivia.is_collection():
+    case let .${trivia.lower_name}s(n):
+      return (lines: 0, lastColumn: n, utf8Length: n * ${trivia.characters_len()})
+%   else:
+    case let .${trivia.lower_name}(text):
+      return calculateTextSizes(text)
+%   end
+% end
+    }
+  }
+}
+
+/// A collection of leading or trailing trivia. This is the main data structure
+/// for thinking about trivia.
+public struct Trivia: Codable {
+  let pieces: [TriviaPiece]
+
+  /// Creates Trivia with the provided underlying pieces.
+  public init(pieces: [TriviaPiece]) {
+    self.pieces = pieces
+  }
+
+  public init(from decoder: Decoder) throws {
+    var container = try decoder.unkeyedContainer()
+    var pieces = [TriviaPiece]()
+    while let piece = try container.decodeIfPresent(TriviaPiece.self) {
+      pieces.append(piece)
+    }
+    self.pieces = pieces
+  }
+
+  public func encode(to encoder: Encoder) throws {
+    var container = encoder.unkeyedContainer()
+    for piece in pieces {
+      try container.encode(piece)
+    }
+  }
+
+  /// Creates Trivia with no pieces.
+  public static var zero: Trivia {
+    return Trivia(pieces: [])
+  }
+
+  /// Creates a new `Trivia` by appending the provided `TriviaPiece` to the end.
+  public func appending(_ piece: TriviaPiece) -> Trivia {
+    var copy = pieces
+    copy.append(piece)
+    return Trivia(pieces: copy)
+  }
+
+% for trivia in TRIVIAS:
+%   if trivia.is_collection():
+%   joined = ''.join(trivia.swift_characters)
+    /// Return a piece of trivia for some number of '${joined}' characters.
+    public static func ${trivia.lower_name}s(_ count: Int) -> Trivia {
+      return [.${trivia.lower_name}s(count)]
+    }
+%   else:
+    /// Return a piece of trivia for ${trivia.name}.
+    public static func ${trivia.lower_name}(_ text: String) -> Trivia {
+      return [.${trivia.lower_name}(text)]
+    }
+%   end
+% end
+
+  /// Computes the total sizes and offsets of all pieces in this Trivia.
+  func characterSizes() -> (lines: Int, lastColumn: Int, utf8Length: Int) {
+    var lines = 0
+    var lastColumn = 0
+    var length = 0
+    for piece in pieces {
+      let (ln, col, len) = piece.characterSizes()
+      lines += ln
+      lastColumn = col
+      length += len
+    }
+    return (lines: lines, lastColumn: lastColumn, utf8Length: length)
+  }
+}
+
+/// Conformance for Trivia to the Collection protocol.
+extension Trivia: Collection {
+  public var startIndex: Int {
+    return pieces.startIndex
+  }
+
+  public var endIndex: Int {
+    return pieces.endIndex
+  }
+
+  public func index(after i: Int) -> Int {
+    return pieces.index(after: i)
+  }
+
+  public subscript(_ index: Int) -> TriviaPiece {
+    return pieces[index]
+  }
+}
+
+
+extension Trivia: ExpressibleByArrayLiteral {
+  /// Creates Trivia from the provided pieces.
+  public init(arrayLiteral elements: TriviaPiece...) {
+    self.pieces = elements
+  }
+}
+
+/// Concatenates two collections of `Trivia` into one collection.
+public func +(lhs: Trivia, rhs: Trivia) -> Trivia {
+  return Trivia(pieces: lhs.pieces + rhs.pieces)
+}
diff --git a/unittests/Parse/LexerTests.cpp b/unittests/Parse/LexerTests.cpp
index c64aa40..3350182 100644
--- a/unittests/Parse/LexerTests.cpp
+++ b/unittests/Parse/LexerTests.cpp
@@ -1,3 +1,5 @@
+#include "swift/AST/DiagnosticConsumer.h"
+#include "swift/AST/DiagnosticEngine.h"
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Parse/Lexer.h"
@@ -703,3 +705,76 @@
   std::vector<Token> Toks = checkLex(Source, ExpectedTokens);
   EXPECT_EQ("<#aa#>", Toks[2].getText());
 }
+
+class StringCaptureDiagnosticConsumer : public DiagnosticConsumer {
+public:
+  virtual void handleDiagnostic(SourceManager &SM, SourceLoc Loc,
+                                DiagnosticKind Kind, StringRef FormatString,
+                                ArrayRef<DiagnosticArgument> FormatArgs,
+                                const swift::DiagnosticInfo &Info) override {
+    std::string DiagMsg;
+    llvm::raw_string_ostream DiagOS(DiagMsg);
+    DiagnosticEngine::formatDiagnosticText(DiagOS, FormatString, FormatArgs);
+    auto LC = SM.getLineAndColumn(Loc);
+    std::ostringstream StrOS;
+    StrOS << LC.first << ", " << LC.second << ": " << DiagOS.str();
+    messages.push_back(StrOS.str());
+  }
+
+  std::vector<std::string> messages;
+};
+
+bool containsPrefix(const std::vector<std::string> &strs,
+                    const std::string &prefix) {
+  for (auto &str : strs) {
+    if (StringRef(str).startswith(StringRef(prefix))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+TEST_F(LexerTest, DiagnoseEmbeddedNul) {
+  const char Source[] = " \0 \0 aaa \0 \0 bbb";
+  size_t SourceLen = sizeof(Source) - 1;
+
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source, SourceLen));
+
+  StringCaptureDiagnosticConsumer DiagConsumer;
+  DiagnosticEngine Diags(SourceMgr);
+  Diags.addConsumer(DiagConsumer);
+
+  Lexer L(LangOpts, SourceMgr, BufferID, &Diags,
+          /*InSILMode=*/false, CommentRetentionMode::None,
+          TriviaRetentionMode::WithTrivia);
+
+  ASSERT_TRUE(containsPrefix(DiagConsumer.messages,
+                             "1, 2: nul character embedded in middle of file"));
+  ASSERT_TRUE(containsPrefix(DiagConsumer.messages,
+                             "1, 4: nul character embedded in middle of file"));
+}
+
+TEST_F(LexerTest, DiagnoseEmbeddedNulOffset) {
+  const char Source[] = " \0 \0 aaa \0 \0 bbb";
+  size_t SourceLen = sizeof(Source) - 1;
+
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(StringRef(Source, SourceLen));
+
+  StringCaptureDiagnosticConsumer DiagConsumer;
+  DiagnosticEngine Diags(SourceMgr);
+  Diags.addConsumer(DiagConsumer);
+
+  Lexer L(LangOpts, SourceMgr, BufferID, &Diags,
+          /*InSILMode=*/false, CommentRetentionMode::None,
+          TriviaRetentionMode::WithTrivia,
+          /*Offset=*/5, /*EndOffset=*/SourceLen);
+
+  ASSERT_FALSE(containsPrefix(
+      DiagConsumer.messages, "1, 2: nul character embedded in middle of file"));
+  ASSERT_FALSE(containsPrefix(
+      DiagConsumer.messages, "1, 4: nul character embedded in middle of file"));
+}
diff --git a/unittests/Reflection/TypeRef.cpp b/unittests/Reflection/TypeRef.cpp
index 5e0df43..f9cba95 100644
--- a/unittests/Reflection/TypeRef.cpp
+++ b/unittests/Reflection/TypeRef.cpp
@@ -148,9 +148,10 @@
 
   // Test parameter with and without inout/shared/variadic and/or label.
   ParameterFlags paramFlags;
-  auto inoutFlags = paramFlags.withInOut(true);
+  auto inoutFlags = paramFlags.withValueOwnership(ValueOwnership::InOut);
   auto variadicFlags = paramFlags.withVariadic(true);
-  auto sharedFlags = paramFlags.withShared(true);
+  auto sharedFlags = paramFlags.withValueOwnership(ValueOwnership::Shared);
+  auto ownedFlags = paramFlags.withValueOwnership(ValueOwnership::Owned);
 
   auto F6 = Builder.createFunctionType({Param1.withFlags(inoutFlags)}, Result,
                                        FunctionTypeFlags());
@@ -170,17 +171,27 @@
                                          Result, FunctionTypeFlags());
   EXPECT_EQ(F8, F8_1);
 
-  auto F9 = Builder.createFunctionType({Param1}, Result, FunctionTypeFlags());
-  auto F9_1 = Builder.createFunctionType({Param1.withLabel("foo")}, Result,
+  auto F9 = Builder.createFunctionType({Param1.withFlags(ownedFlags)}, Result,
+                                       FunctionTypeFlags());
+  auto F9_1 = Builder.createFunctionType({Param1.withFlags(ownedFlags)},
+                                         Result, FunctionTypeFlags());
+  EXPECT_EQ(F9, F9_1);
+
+  auto F10 = Builder.createFunctionType({Param1}, Result, FunctionTypeFlags());
+  auto F10_1 = Builder.createFunctionType({Param1.withLabel("foo")}, Result,
                                          FunctionTypeFlags());
-  EXPECT_NE(F9, F9_1);
+  EXPECT_NE(F10, F10_1);
 
   EXPECT_NE(F6, F7);
   EXPECT_NE(F6, F8);
   EXPECT_NE(F6, F9);
+  EXPECT_NE(F6, F10);
   EXPECT_NE(F7, F8);
   EXPECT_NE(F7, F9);
+  EXPECT_NE(F7, F10);
   EXPECT_NE(F8, F9);
+  EXPECT_NE(F8, F10);
+  EXPECT_NE(F9, F10);
 
   auto VoidVoid1 =
       Builder.createFunctionType(VoidParams, VoidResult, FunctionTypeFlags());
@@ -191,14 +202,14 @@
   EXPECT_NE(VoidVoid1, F1);
 
   // Test escaping.
-  auto F10 = Builder.createFunctionType(Parameters1, Result,
-                                        FunctionTypeFlags().withEscaping(true));
   auto F11 = Builder.createFunctionType(Parameters1, Result,
                                         FunctionTypeFlags().withEscaping(true));
-  auto F12 = Builder.createFunctionType(
+  auto F12 = Builder.createFunctionType(Parameters1, Result,
+                                        FunctionTypeFlags().withEscaping(true));
+  auto F13 = Builder.createFunctionType(
       Parameters1, Result, FunctionTypeFlags().withEscaping(false));
-  EXPECT_EQ(F10, F11);
-  EXPECT_NE(F10, F12);
+  EXPECT_EQ(F11, F12);
+  EXPECT_NE(F11, F13);
 }
 
 TEST(TypeRefTest, UniqueProtocolTypeRef) {
diff --git a/utils/gyb_syntax_support/Trivia.py b/utils/gyb_syntax_support/Trivia.py
index 6a24081..fe32541 100644
--- a/utils/gyb_syntax_support/Trivia.py
+++ b/utils/gyb_syntax_support/Trivia.py
@@ -2,13 +2,20 @@
 
 
 class Trivia(object):
-    def __init__(self, name, comment, characters=[], is_new_line=False):
+    def __init__(self, name, comment, characters=[], swift_characters=[],
+                 is_new_line=False):
         self.name = name
         self.comment = comment
         self.characters = characters
         self.lower_name = lowercase_first_word(name)
         self.is_new_line = is_new_line
 
+        # Swift sometimes doesn't support escaped characters like \f or \v;
+        # we should allow specifying alternatives explicitly.
+        self.swift_characters = swift_characters if swift_characters else\
+            characters
+        assert len(self.swift_characters) == len(self.characters)
+
     def characters_len(self):
         return len(self.characters)
 
@@ -20,8 +27,9 @@
     Trivia('Space', 'A space \' \' character.', characters=[' ']),
     Trivia('Tab', 'A tab \'\\t\' character.', characters=['\\t']),
     Trivia('VerticalTab', 'A vertical tab \'\\v\' character.',
-           characters=['\\v']),
-    Trivia('Formfeed', 'A form-feed \'f\' character.', characters=['\\f']),
+           characters=['\\v'], swift_characters=['\\u{2B7F}']),
+    Trivia('Formfeed', 'A form-feed \'f\' character.', characters=['\\f'],
+           swift_characters=['\\u{240C}']),
     Trivia('Newline', 'A newline \'\\n\' character.', characters=['\\n'],
            is_new_line=True),
     Trivia('CarriageReturn', 'A newline \'\\r\' character.',