Merge pull request #27821 from apple/tensorflow-merge2

Merge swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a into tensorflow
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..4a44c64
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+*.swift.gyb linguist-language=Swift
+*.cpp.gyb linguist-language=C++
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43bb350..5bf3186 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -58,63 +58,6 @@
   (foo as Magic)(5)
   ```
 
-* [SR-11298][]:
-
-  A class-constrained protocol extension, where the extended protocol does
-  not impose a class constraint, will now infer the constraint implicitly.
-
-  ```swift
-  protocol Foo {}
-  class Bar: Foo {
-    var someProperty: Int = 0
-  }
-
-  // Even though 'Foo' does not impose a class constraint, it is automatically
-  // inferred due to the Self: Bar constraint.
-  extension Foo where Self: Bar {
-    var anotherProperty: Int {
-      get { return someProperty }
-      // As a result, the setter is now implicitly nonmutating, just like it would
-      // be if 'Foo' had a class constraint.
-      set { someProperty = newValue }
-    }
-  }
-  ```
-  
-  As a result, this could lead to code that currently compiles today to throw an error.
-  
-  ```swift
-  protocol Foo {
-    var someProperty: Int { get set }
-  }
-  
-  class Bar: Foo {
-    var someProperty = 0
-  }
-  
-  extension Foo where Self: Bar {
-    var anotherProperty1: Int {
-      get { return someProperty }
-      // This will now error, because the protocol requirement
-      // is implicitly mutating and the setter is implicitly 
-      // nonmutating.
-      set { someProperty = newValue } // Error
-    }
-  }
-  ```
-
-  **Workaround**: Define a new mutable variable inside the setter that has a reference to `self`:
-  
-  ```swift
-  var anotherProperty1: Int {
-    get { return someProperty }
-    set {
-      var mutableSelf = self
-      mutableSelf.someProperty = newValue // Okay
-    }
-  }
-  ```
-
 * [SE-0253][]:
 
   Values of types that declare `func callAsFunction` methods can be called
@@ -140,7 +83,7 @@
 
 * [SR-4206][]:
 
-  A method override is no longer allowed to have a generic signature with
+  A method override is no longer allowed to have a generic signature with 
   requirements not imposed by the base method. For example:
 
   ```
@@ -7856,5 +7799,4 @@
 [SR-8974]: <https://bugs.swift.org/browse/SR-8974>
 [SR-9043]: <https://bugs.swift.org/browse/SR-9043>
 [SR-9827]: <https://bugs.swift.org/browse/SR-9827>
-[SR-11298]: <https://bugs.swift.org/browse/SR-11298>
 [SR-11429]: <https://bugs.swift.org/browse/SR-11429>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ccdfd40..bfc2598 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,8 @@
 list(APPEND CMAKE_MODULE_PATH
     "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
 
+set(CMAKE_DISABLE_IN_SOURCE_BUILD YES)
+
 if(DEFINED CMAKE_JOB_POOLS)
   # CMake < 3.11 doesn't support CMAKE_JOB_POOLS. Manually set the property.
   set_property(GLOBAL PROPERTY JOB_POOLS "${CMAKE_JOB_POOLS}")
diff --git a/cmake/modules/SwiftSource.cmake b/cmake/modules/SwiftSource.cmake
index ef56a89..e60ff97 100644
--- a/cmake/modules/SwiftSource.cmake
+++ b/cmake/modules/SwiftSource.cmake
@@ -323,12 +323,12 @@
     set(module_base "${module_dir}/${SWIFTFILE_MODULE_NAME}")
     if(SWIFTFILE_SDK IN_LIST SWIFT_APPLE_PLATFORMS)
       set(specific_module_dir "${module_base}.swiftmodule")
-      set(specific_module_private_dir "${specific_module_dir}/Private")
-      set(source_info_file "${specific_module_private_dir}/${SWIFTFILE_ARCHITECTURE}.swiftsourceinfo")
+      set(specific_module_project_dir "${specific_module_dir}/Project")
+      set(source_info_file "${specific_module_project_dir}/${SWIFTFILE_ARCHITECTURE}.swiftsourceinfo")
       set(module_base "${module_base}.swiftmodule/${SWIFTFILE_ARCHITECTURE}")
     else()
       set(specific_module_dir)
-      set(specific_module_private_dir)
+      set(specific_module_project_dir)
       set(source_info_file "${module_base}.swiftsourceinfo")
     endif()
     set(module_file "${module_base}.swiftmodule")
@@ -367,7 +367,7 @@
                                DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${library_subdir}"
                                COMPONENT "${SWIFTFILE_INSTALL_IN_COMPONENT}"
                                OPTIONAL
-                               PATTERN "Private" EXCLUDE)
+                               PATTERN "Project" EXCLUDE)
   else()
     swift_install_in_component(FILES ${module_outputs}
                                DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${library_subdir}"
@@ -508,7 +508,7 @@
         COMMAND
           "${CMAKE_COMMAND}" "-E" "make_directory" ${module_dir}
           ${specific_module_dir}
-          ${specific_module_private_dir}
+          ${specific_module_project_dir}
         COMMAND
           "${PYTHON_EXECUTABLE}" "${line_directive_tool}" "@${file_path}" --
           "${swift_compiler_tool}" "-emit-module" "-o" "${module_file}"
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 7457135..92600e7 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -99,8 +99,7 @@
 Warning: Creating the above links usually requires administrator privileges. The quick and easy way to do this is to open a second developer prompt by right clicking whatever shortcut you used to open the first one, choosing Run As Administrator, and pasting the above commands into the resulting window. You can then close the privileged prompt; this is the only step which requires elevation.
 
 ## 6. Build LLVM/Clang
-- This must be done from within a developer command prompt. LLVM and Clang are
-  large projects, so building might take a few hours. Make sure that the build
+- This must be done from within a developer command prompt. Make sure that the build
   type for LLVM/Clang is compatible with the build type for Swift. That is,
   either build everything `Debug` or some variant of `Release` (e.g. `Release`,
   `RelWithDebInfo`).
@@ -126,8 +125,8 @@
 path S:\b\llvm\bin;%PATH%
 ```
 ## 7. Build CMark
-- This must be done from within a developer command prompt. CMark is a fairly
-  small project and should only take a few minutes to build.
+- This must be done from within a developer command prompt.
+
 ```cmd
 md "S:\b\cmark"
 cd "S:\b\cmark"
@@ -180,8 +179,8 @@
 ```
 
 ## 9. Build lldb
-- This must be done from within a developer command prompt and could take hours
-  depending on your system.
+- This must be done from within a developer command prompt.
+
 ```cmd
 md "S:\b\lldb"
 cd "S:\b\lldb"
diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h
index 7a6bc43..9e449f5 100644
--- a/include/swift/AST/ASTScope.h
+++ b/include/swift/AST/ASTScope.h
@@ -30,6 +30,7 @@
 
 #include "swift/AST/ASTNode.h"
 #include "swift/AST/NameLookup.h" // for DeclVisibilityKind
+#include "swift/AST/SimpleRequest.h"
 #include "swift/Basic/Compiler.h"
 #include "swift/Basic/LLVM.h"
 #include "swift/Basic/NullablePtr.h"
@@ -88,6 +89,14 @@
   ASTScopeImpl *insertionPoint;
   const char *explanation;
 };
+} // namespace ast_scope
+
+namespace ast_scope {
+
+void simple_display(llvm::raw_ostream &out, const ASTScopeImpl *);
+void simple_display(llvm::raw_ostream &out, const ScopeCreator *);
+
+SourceLoc extractNearestSourceLoc(std::tuple<ASTScopeImpl *, ScopeCreator *>);
 
 #pragma mark the root ASTScopeImpl class
 
@@ -333,6 +342,11 @@
 public:
   /// expandScope me, sending deferred nodes to my descendants.
   /// Return the scope into which to place subsequent decls
+  ASTScopeImpl *expandAndBeCurrentDetectingRecursion(ScopeCreator &);
+
+  /// Expand or reexpand the scope if unexpanded or if not current.
+  /// There are several places in the compiler that mutate the AST after the
+  /// fact, above and beyond adding Decls to the SourceFile.
   ASTScopeImpl *expandAndBeCurrent(ScopeCreator &);
 
   unsigned getASTAncestorScopeCount() const { return astAncestorScopeCount; }
@@ -344,6 +358,12 @@
   void setWasExpanded() { wasExpanded = true; }
   virtual ASTScopeImpl *expandSpecifically(ScopeCreator &) = 0;
   virtual void beCurrent();
+  virtual bool doesExpansionOnlyAddNewDeclsAtEnd() const;
+
+public:
+  bool isExpansionNeeded(const ScopeCreator &) const;
+
+protected:
   bool isCurrent() const;
   virtual bool isCurrentIfWasExpanded() const;
 
@@ -374,16 +394,7 @@
 
   bool isATypeDeclScope() const;
 
-  /// There are several places in the compiler that mutate the AST after the
-  /// fact, above and beyond adding Decls to the SourceFile. These are
-  /// documented in: rdar://53018839, rdar://53027266, rdar://53027733,
-  /// rdar://53028050
-  /// Return true if did reexpand
-  bool reexpandIfObsolete(ScopeCreator &);
-
 private:
-  void reexpand(ScopeCreator &);
-
   virtual ScopeCreator &getScopeCreator();
 
 #pragma mark - - creation queries
@@ -533,8 +544,8 @@
   /// The number of \c Decls in the \c SourceFile that were already seen.
   /// Since parsing can be interleaved with type-checking, on every
   /// lookup, look at creating scopes for any \c Decls beyond this number.
-  /// rdar://55562483 Unify with numberOfChildrenWhenLastExpanded
-  int numberOfDeclsAlreadySeen = 0;
+  /// TODO: Unify with numberOfChildrenWhenLastExpanded
+  size_t numberOfDeclsAlreadySeen = 0;
 
   ASTSourceFileScope(SourceFile *SF, ScopeCreator *scopeCreator);
 
@@ -548,7 +559,6 @@
 public:
   NullablePtr<DeclContext> getDeclContext() const override;
 
-  void addNewDeclsToScopeTree();
   void buildFullyExpandedTree();
   void
   buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals();
@@ -559,11 +569,15 @@
 
 protected:
   ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
+  bool isCurrentIfWasExpanded() const override;
+  void beCurrent() override;
+  bool doesExpansionOnlyAddNewDeclsAtEnd() const override;
 
   ScopeCreator &getScopeCreator() override;
 
 private:
-  void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
+  AnnotatedInsertionPoint
+  expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &);
 };
 
 class Portion {
@@ -1148,7 +1162,6 @@
   /// false positives, that that doesn't hurt anything. However, the result of
   /// the conservative source range computation doesn't seem to be stable. So
   /// keep the original here, and use it for source range queries.
-  /// rdar://55263708
 
   const SourceRange sourceRangeWhenCreated;
 
@@ -1251,7 +1264,6 @@
 };
 
 class PatternEntryInitializerScope final : public AbstractPatternEntryScope {
-  // Should be able to remove this when rdar://53921703 is accomplished.
   Expr *initAsWrittenWhenCreated;
 
 public:
diff --git a/include/swift/AST/ASTTypeIDZone.def b/include/swift/AST/ASTTypeIDZone.def
index 2d76e23..b5b5493 100644
--- a/include/swift/AST/ASTTypeIDZone.def
+++ b/include/swift/AST/ASTTypeIDZone.def
@@ -18,6 +18,7 @@
 SWIFT_TYPEID(AncestryFlags)
 SWIFT_TYPEID(CtorInitializerKind)
 SWIFT_TYPEID(GenericSignature)
+SWIFT_TYPEID(ParamSpecifier)
 SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)
 SWIFT_TYPEID(PropertyWrapperTypeInfo)
 SWIFT_TYPEID(Requirement)
diff --git a/include/swift/AST/ASTTypeIDs.h b/include/swift/AST/ASTTypeIDs.h
index 58eb5af..bd20306 100644
--- a/include/swift/AST/ASTTypeIDs.h
+++ b/include/swift/AST/ASTTypeIDs.h
@@ -35,6 +35,8 @@
 class NominalTypeDecl;
 class OperatorDecl;
 class OpaqueTypeDecl;
+class ParamDecl;
+enum class ParamSpecifier : uint8_t;
 class PrecedenceGroupDecl;
 struct PropertyWrapperBackingPropertyInfo;
 struct PropertyWrapperTypeInfo;
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index e07cf3b..2e425e6 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -2040,7 +2040,7 @@
 public:
   template <typename ATTR, bool AllowInvalid>
   using AttributeKindRange =
-      OptionalTransformRange<llvm::iterator_range<const_iterator>,
+      OptionalTransformRange<iterator_range<const_iterator>,
                              ToAttributeKind<ATTR, AllowInvalid>,
                              const_iterator>;
 
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index cb935a0..07c18da 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -369,18 +369,14 @@
     IsPropertyWrapperBackingProperty : 1
   );
 
-  SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 2+1+NumDefaultArgumentKindBits,
+  SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 1+2+NumDefaultArgumentKindBits,
+    /// Whether we've computed the specifier yet.
+    SpecifierComputed : 1,
+
     /// The specifier associated with this parameter.  This determines
     /// the storage semantics of the value e.g. mutability.
     Specifier : 2,
 
-    /// True if the type is implicitly specified in the source, but this has an
-    /// apparently valid typeRepr.  This is used in accessors, which look like:
-    ///    set (value) {
-    /// but need to get the typeRepr from the property as a whole so Sema can
-    /// resolve the type.
-    IsTypeLocImplicit : 1,
-
     /// Information about a symbolic default argument, like #file.
     defaultArgumentKind : NumDefaultArgumentKindBits
   );
@@ -2982,9 +2978,6 @@
   /// Retrieve a sugared interface type containing the structure of the interface
   /// type before any semantic validation has occured.
   Type getStructuralType() const;
-
-  /// Set the interface type of this typealias declaration from the underlying type.
-  void computeType();
   
   bool isCompatibilityAlias() const {
     return Bits.TypeAliasDecl.IsCompatibilityAlias;
@@ -3173,10 +3166,6 @@
     TrailingWhere = trailingWhereClause;
   }
 
-  /// Set the interface type of this associated type declaration to a dependent
-  /// member type of 'Self'.
-  void computeType();
-
   /// Retrieve the associated type "anchor", which is the associated type
   /// declaration that will be used to describe this associated type in the
   /// ABI.
@@ -3366,10 +3355,6 @@
     Bits.NominalTypeDecl.AddedImplicitInitializers = true;
   }
 
-  /// Set the interface type of this nominal type to the metatype of the
-  /// declared interface type.
-  void computeType();
-
   /// getDeclaredType - Retrieve the type declared by this entity, without
   /// any generic parameters bound if this is a generic type.
   Type getDeclaredType() const;
@@ -3565,8 +3550,6 @@
     return SourceRange(EnumLoc, getBraces().End);
   }
 
-  EnumElementDecl *getElement(Identifier Name) const;
-  
 public:
   /// A range for iterating the elements of an enum.
   using ElementRange = DowncastFilterRange<EnumElementDecl, DeclRange>;
@@ -4827,8 +4810,7 @@
           bool issCaptureList, SourceLoc nameLoc, Identifier name,
           DeclContext *dc, StorageIsMutable_t supportsMutation);
 
-  /// This is the type specified, including location information.
-  TypeLoc typeLoc;
+  TypeRepr *ParentRepr = nullptr;
 
   Type typeInContext;
 
@@ -4848,8 +4830,10 @@
     return hasName() ? getBaseName().getIdentifier().str() : "_";
   }
 
-  TypeLoc &getTypeLoc() { return typeLoc; }
-  TypeLoc getTypeLoc() const { return typeLoc; }
+  /// Retrieve the TypeRepr corresponding to the parsed type of the parent
+  /// pattern, if it exists.
+  TypeRepr *getTypeRepr() const { return ParentRepr; }
+  void setTypeRepr(TypeRepr *repr) { ParentRepr = repr; }
 
   bool hasType() const {
     // We have a type if either the type has been computed already or if
@@ -5184,6 +5168,13 @@
   }
 };
 
+enum class ParamSpecifier : uint8_t {
+  Default = 0,
+  InOut = 1,
+  Shared = 2,
+  Owned = 3,
+};
+
 /// A function parameter declaration.
 class ParamDecl : public VarDecl {
   Identifier ArgumentName;
@@ -5210,23 +5201,15 @@
   llvm::PointerIntPair<StoredDefaultArgument *, 2, OptionSet<Flags>>
       DefaultValueAndFlags;
 
-public:
-  enum class Specifier : uint8_t {
-    Default = 0,
-    InOut = 1,
-    Shared = 2,
-    Owned = 3,
-  };
+  friend class ParamSpecifierRequest;
 
-  ParamDecl(Specifier specifier,
-            SourceLoc specifierLoc, SourceLoc argumentNameLoc,
+public:
+  ParamDecl(SourceLoc specifierLoc, SourceLoc argumentNameLoc,
             Identifier argumentName, SourceLoc parameterNameLoc,
             Identifier parameterName, DeclContext *dc);
 
-  /// Clone constructor, allocates a new ParamDecl identical to the first.
-  /// Intentionally not defined as a typical copy constructor to avoid
-  /// accidental copies.
-  ParamDecl(ParamDecl *PD, bool withTypes);
+  /// Create a new ParamDecl identical to the first except without the interface type.
+  static ParamDecl *cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD);
   
   /// Retrieve the argument (API) name for this function parameter.
   Identifier getArgumentName() const { return ArgumentName; }
@@ -5243,10 +5226,7 @@
   SourceLoc getParameterNameLoc() const { return ParameterNameLoc; }
 
   SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
-    
-  bool isTypeLocImplicit() const { return Bits.ParamDecl.IsTypeLocImplicit; }
-  void setIsTypeLocImplicit(bool val) { Bits.ParamDecl.IsTypeLocImplicit = val; }
-  
+
   DefaultArgumentKind getDefaultArgumentKind() const {
     return static_cast<DefaultArgumentKind>(Bits.ParamDecl.defaultArgumentKind);
   }
@@ -5349,10 +5329,17 @@
   /// Determine whether this declaration is an anonymous closure parameter.
   bool isAnonClosureParam() const;
 
-  /// Return the raw specifier value for this parameter.
-  Specifier getSpecifier() const {
-    return static_cast<Specifier>(Bits.ParamDecl.Specifier);
+  using Specifier = ParamSpecifier;
+
+  Optional<Specifier> getCachedSpecifier() const {
+    if (Bits.ParamDecl.SpecifierComputed)
+      return Specifier(Bits.ParamDecl.Specifier);
+
+    return None;
   }
+
+  /// Return the raw specifier value for this parameter.
+  Specifier getSpecifier() const;
   void setSpecifier(Specifier Spec);
 
   /// Is the type of this parameter 'inout'?
@@ -5510,10 +5497,6 @@
   TypeLoc &getElementTypeLoc() { return ElementTy; }
   const TypeLoc &getElementTypeLoc() const { return ElementTy; }
 
-  /// Compute the interface type of this subscript from the parameter and
-  /// element types.
-  void computeType();
-
   /// Determine the kind of Objective-C subscripting this declaration
   /// implies.
   ObjCSubscriptKind getObjCSubscriptKind() const;
@@ -5844,11 +5827,6 @@
     Bits.AbstractFunctionDecl.Synthesized = value;
   }
 
-private:
-  void computeNeedsNewVTableEntry();
-
-  void computeSelfDeclType();
-
 public:
   /// Compute the interface type of this function declaration from the
   /// parameter types.
@@ -6383,13 +6361,7 @@
                   ParameterList *Params,
                   SourceLoc EqualsLoc,
                   LiteralExpr *RawValueExpr,
-                  DeclContext *DC)
-  : DeclContext(DeclContextKind::EnumElementDecl, DC),
-    ValueDecl(DeclKind::EnumElement, DC, Name, IdentifierLoc),
-    Params(Params),
-    EqualsLoc(EqualsLoc),
-    RawValueExpr(RawValueExpr)
-  {}
+                  DeclContext *DC);
 
   Identifier getName() const { return getFullName().getBaseIdentifier(); }
 
@@ -6399,12 +6371,9 @@
     return hasName() ? getBaseName().getIdentifier().str() : "_";
   }
 
-  /// Set the interface type of this enum element to the constructor function
-  /// type; (Self.Type) -> Self or (Self.Type) -> (Args...) -> Self.
-  void computeType();
-
   Type getArgumentInterfaceType() const;
 
+  void setParameterList(ParameterList *params);
   ParameterList *getParameterList() const { return Params; }
 
   /// Retrieves a fully typechecked raw value expression associated
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index b1dfee0..4805fdc 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -261,10 +261,7 @@
 
   /// Returns the kind of context this is.
   DeclContextKind getContextKind() const;
-
-  /// Returns whether this context has value semantics.
-  bool hasValueSemantics() const;
-
+  
   /// Determines whether this context is itself a local scope in a
   /// code block.  A context that appears in such a scope, like a
   /// local type declaration, does not itself become a local context.
@@ -667,7 +664,7 @@
 
 /// The range of declarations stored within an iterable declaration
 /// context.
-typedef IteratorRange<DeclIterator> DeclRange;
+using DeclRange = iterator_range<DeclIterator>;
 
 /// The kind of an \c IterableDeclContext.
 enum class IterableDeclContextKind : uint8_t {  
diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def
index 6253a4e..29732ba 100644
--- a/include/swift/AST/DiagnosticsCommon.def
+++ b/include/swift/AST/DiagnosticsCommon.def
@@ -163,6 +163,11 @@
 NOTE(kind_declname_declared_here,none,
      "%0 %1 declared here", (DescriptiveDeclKind, DeclName))
 
+WARNING(warn_property_wrapper_module_scope,none,
+        "ignoring associated type %0 in favor of module-scoped property "
+        "wrapper %0; please qualify the reference with %1",
+        (DeclName, Identifier))
+
 #ifndef DIAG_NO_UNDEF
 # if defined(DIAG)
 #  undef DIAG
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index ccadc9b..98cd135 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -979,6 +979,8 @@
 // Yield Statment
 ERROR(expected_expr_yield,PointsToFirstBadToken,
       "expected expression in 'yield' statement", ())
+ERROR(unexpected_arg_label_yield,none,
+      "unexpected argument label in 'yield' statement", ())
 
 // Defer Statement
 ERROR(expected_lbrace_after_defer,PointsToFirstBadToken,
diff --git a/include/swift/AST/DiagnosticsSIL.def b/include/swift/AST/DiagnosticsSIL.def
index 1922e09..3e62245 100644
--- a/include/swift/AST/DiagnosticsSIL.def
+++ b/include/swift/AST/DiagnosticsSIL.def
@@ -434,7 +434,7 @@
 NOTE(constexpr_unknown_control_flow_due_to_skip,none, "branch depends on "
      "non-constant value produced by an unevaluated instructions", ())
 NOTE(constexpr_returned_by_unevaluated_instruction,none,
-     "return value of an unevaluated instruction is not a constant", ())
+     "result of an unevaluated instruction is not a constant", ())
 NOTE(constexpr_mutated_by_unevaluated_instruction,none, "value mutable by an "
     "unevaluated instruction is not a constant", ())
 
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index df2333a..aac8f34 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -381,8 +381,8 @@
       (Type,Type))
 
 NOTE(candidate_has_invalid_argument_at_position,none,
-     "candidate expects value of type %0 for parameter #%1",
-     (Type, unsigned))
+     "candidate expects %select{|in-out }2value of type %0 for parameter #%1",
+     (Type, unsigned, bool))
 
 ERROR(cannot_convert_array_to_variadic,none,
       "cannot pass array of type %0 as variadic arguments of type %1",
@@ -3697,6 +3697,8 @@
 ERROR(single_tuple_parameter_mismatch_normal,none,
       "%0 %1 expects a single parameter of type %2%3",
       (DescriptiveDeclKind, DeclBaseName, Type, StringRef))
+NOTE(note_maybe_forgot_to_form_tuple,none,
+     "did you mean to pass a tuple?", ())
 ERROR(unknown_single_tuple_parameter_mismatch,none,
       "single parameter of type %0 is expected in call", (Type))
 ERROR(cannot_convert_single_tuple_into_multiple_arguments,none,
@@ -4750,8 +4752,6 @@
       (DeclName, Type, Type))
 ERROR(property_wrapper_failable_init, none,
       "%0 cannot be failable", (DeclName))
-ERROR(property_wrapper_ambiguous_default_value_init, none,
-  "property wrapper type %0 has multiple default-value initializers", (Type))
 ERROR(property_wrapper_type_requirement_not_accessible,none,
       "%select{private|fileprivate|internal|public|open}0 %1 %2 cannot have "
       "more restrictive access than its enclosing property wrapper type %3 "
diff --git a/include/swift/AST/FileUnit.h b/include/swift/AST/FileUnit.h
index c58f8c1..e09f13b 100644
--- a/include/swift/AST/FileUnit.h
+++ b/include/swift/AST/FileUnit.h
@@ -131,6 +131,10 @@
     return None;
   }
 
+  virtual Optional<BasicDeclLocs> getBasicLocsForDecl(const Decl *D) const {
+    return None;
+  }
+
   virtual void collectAllGroups(std::vector<StringRef> &Names) const {}
 
   /// Returns an implementation-defined "discriminator" for \p D, which
diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h
index 5617ae7..87afbd2 100644
--- a/include/swift/AST/NameLookupRequests.h
+++ b/include/swift/AST/NameLookupRequests.h
@@ -30,6 +30,10 @@
 class GenericParamList;
 class TypeAliasDecl;
 class TypeDecl;
+namespace ast_scope {
+class ASTScopeImpl;
+class ScopeCreator;
+} // namespace ast_scope
 
 /// Display a nominal type or extension thereof.
 void simple_display(
@@ -324,6 +328,30 @@
   bool isCached() const { return true; }
 };
 
+/// Expand the given ASTScope. Requestified to detect recursion.
+class ExpandASTScopeRequest
+    : public SimpleRequest<ExpandASTScopeRequest,
+                           ast_scope::ASTScopeImpl *(ast_scope::ASTScopeImpl *,
+                                                     ast_scope::ScopeCreator *),
+                           CacheKind::SeparatelyCached> {
+public:
+  using SimpleRequest::SimpleRequest;
+
+private:
+  friend SimpleRequest;
+
+  // Evaluation.
+  llvm::Expected<ast_scope::ASTScopeImpl *>
+  evaluate(Evaluator &evaluator, ast_scope::ASTScopeImpl *,
+           ast_scope::ScopeCreator *) const;
+
+public:
+  // Separate caching.
+  bool isCached() const;
+  Optional<ast_scope::ASTScopeImpl *> getCachedResult() const;
+  void cacheResult(ast_scope::ASTScopeImpl *) const {}
+};
+
 #define SWIFT_TYPEID_ZONE NameLookup
 #define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def"
 #include "swift/Basic/DefineTypeIDZone.h"
diff --git a/include/swift/AST/NameLookupTypeIDZone.def b/include/swift/AST/NameLookupTypeIDZone.def
index b33c93f..87de963 100644
--- a/include/swift/AST/NameLookupTypeIDZone.def
+++ b/include/swift/AST/NameLookupTypeIDZone.def
@@ -18,6 +18,10 @@
 SWIFT_REQUEST(NameLookup, CustomAttrNominalRequest,
               NominalTypeDecl *(CustomAttr *, DeclContext *), Cached,
               NoLocationInfo)
+SWIFT_REQUEST(NameLookup, ExpandASTScopeRequest,
+              ast_scope::ASTScopeImpl* (ast_scope::ASTScopeImpl*, ast_scope::ScopeCreator*),
+              SeparatelyCached,
+              NoLocationInfo)
 SWIFT_REQUEST(NameLookup, ExtendedNominalRequest,
               NominalTypeDecl *(ExtensionDecl *), SeparatelyCached,
               NoLocationInfo)
diff --git a/include/swift/AST/ParameterList.h b/include/swift/AST/ParameterList.h
index 7fd7dfa..1a431a2 100644
--- a/include/swift/AST/ParameterList.h
+++ b/include/swift/AST/ParameterList.h
@@ -111,8 +111,6 @@
     /// The cloned pattern is for an inherited constructor; mark default
     /// arguments as inherited, and mark unnamed arguments as named.
     Inherited = 0x02,
-    /// The cloned pattern will strip type information.
-    WithoutTypes = 0x04,
   };
 
   friend OptionSet<CloneFlags> operator|(CloneFlags flag1, CloneFlags flag2) {
diff --git a/include/swift/AST/PropertyWrappers.h b/include/swift/AST/PropertyWrappers.h
index 50e71d0..f290975 100644
--- a/include/swift/AST/PropertyWrappers.h
+++ b/include/swift/AST/PropertyWrappers.h
@@ -43,9 +43,12 @@
     HasInitialValueInit
   } wrappedValueInit = NoWrappedValueInit;
 
-  /// The initializer `init()` that will be called to default-initialize a
+  /// The initializer that will be called to default-initialize a
   /// value with an attached property wrapper.
-  ConstructorDecl *defaultInit = nullptr;
+  enum {
+    NoDefaultValueInit = 0,
+    HasDefaultValueInit
+  } defaultInit = NoDefaultValueInit;
 
   /// The property through which the projection value ($foo) will be accessed.
   ///
diff --git a/include/swift/AST/RawComment.h b/include/swift/AST/RawComment.h
index 1133ceb..524e4ee 100644
--- a/include/swift/AST/RawComment.h
+++ b/include/swift/AST/RawComment.h
@@ -78,6 +78,19 @@
   uint32_t SourceOrder;
 };
 
+struct LineColumn {
+  uint32_t Line = 0;
+  uint32_t Column = 0;
+  bool isValid() const { return Line && Column; }
+};
+
+struct BasicDeclLocs {
+  StringRef SourceFilePath;
+  LineColumn Loc;
+  LineColumn StartLoc;
+  LineColumn EndLoc;
+};
+
 } // namespace swift
 
 #endif // LLVM_SWIFT_AST_RAW_COMMENT_H
diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h
index 4688535..15b65ff 100644
--- a/include/swift/AST/SourceFile.h
+++ b/include/swift/AST/SourceFile.h
@@ -279,6 +279,7 @@
 
   Identifier getDiscriminatorForPrivateValue(const ValueDecl *D) const override;
   Identifier getPrivateDiscriminator() const { return PrivateDiscriminator; }
+  Optional<BasicDeclLocs> getBasicLocsForDecl(const Decl *D) const override;
 
   virtual bool walk(ASTWalker &walker) override;
 
diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h
index 9dfc7d3..1a3ad26 100644
--- a/include/swift/AST/TypeCheckRequests.h
+++ b/include/swift/AST/TypeCheckRequests.h
@@ -1238,6 +1238,7 @@
   bool isCached() const { return true; }
 };
 
+/// Computes the raw values for an enum type.
 class EnumRawValuesRequest :
     public SimpleRequest<EnumRawValuesRequest,
                          bool (EnumDecl *, TypeResolutionStage),
@@ -1263,6 +1264,7 @@
   void cacheResult(bool value) const;
 };
 
+/// Determines if an override is ABI compatible with its base method.
 class IsABICompatibleOverrideRequest
     : public SimpleRequest<IsABICompatibleOverrideRequest, bool(ValueDecl *),
                            CacheKind::Cached> {
@@ -1321,6 +1323,9 @@
   void cacheResult(bool value) const;
 };
 
+/// Determines if a method override should introduce a new vtable entry,
+/// because the override is not ABI compatible, or the base method is
+/// less visible than the override.
 class NeedsNewVTableEntryRequest
     : public SimpleRequest<NeedsNewVTableEntryRequest,
                            bool(AbstractFunctionDecl *),
@@ -1342,6 +1347,51 @@
   void cacheResult(bool value) const;
 };
 
+/// Determines the specifier for a parameter (inout, __owned, etc).
+class ParamSpecifierRequest
+    : public SimpleRequest<ParamSpecifierRequest,
+                           ParamSpecifier(ParamDecl *),
+                           CacheKind::SeparatelyCached> {
+public:
+  using SimpleRequest::SimpleRequest;
+
+private:
+  friend SimpleRequest;
+
+  // Evaluation.
+  llvm::Expected<ParamSpecifier>
+  evaluate(Evaluator &evaluator, ParamDecl *decl) const;
+
+public:
+  // Separate caching.
+  bool isCached() const { return true; }
+  Optional<ParamSpecifier> getCachedResult() const;
+  void cacheResult(ParamSpecifier value) const;
+};
+
+/// Determines the result type of a function or element type of a subscript.
+class ResultTypeRequest
+    : public SimpleRequest<ResultTypeRequest,
+                           Type(ValueDecl *),
+                           CacheKind::SeparatelyCached> {
+public:
+  using SimpleRequest::SimpleRequest;
+
+private:
+  friend SimpleRequest;
+
+  TypeLoc &getResultTypeLoc() const;
+
+  // Evaluation.
+  llvm::Expected<Type> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
+
+public:
+  // Separate caching.
+  bool isCached() const { return true; }
+  Optional<Type> getCachedResult() const;
+  void cacheResult(Type value) const;
+};
+
 // Allow AnyValue to compare two Type values, even though Type doesn't
 // support ==.
 template<>
diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def
index 0bfa811..16b8144 100644
--- a/include/swift/AST/TypeCheckerTypeIDZone.def
+++ b/include/swift/AST/TypeCheckerTypeIDZone.def
@@ -151,3 +151,7 @@
               bool(FuncDecl *), SeparatelyCached, NoLocationInfo)
 SWIFT_REQUEST(TypeChecker, NeedsNewVTableEntryRequest,
               bool(AbstractFunctionDecl *), SeparatelyCached, NoLocationInfo)
+SWIFT_REQUEST(TypeChecker, ParamSpecifierRequest,
+              ParamDecl::Specifier(ParamDecl *), SeparatelyCached, NoLocationInfo)
+SWIFT_REQUEST(TypeChecker, ResultTypeRequest,
+              Type(ValueDecl *), SeparatelyCached, NoLocationInfo)
diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h
index 0c42c37..97ad289 100644
--- a/include/swift/AST/TypeRepr.h
+++ b/include/swift/AST/TypeRepr.h
@@ -653,7 +653,7 @@
   TypeRepr *Type;
   SourceLoc TrailingCommaLoc;
 
-  TupleTypeReprElement() {}
+  TupleTypeReprElement(): Type(nullptr) {}
   TupleTypeReprElement(TypeRepr *Type): Type(Type) {}
 };
 
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index a1fada1..06bb879 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -4141,13 +4141,11 @@
   };
   using IndirectFormalResultIter =
       llvm::filter_iterator<const SILResultInfo *, IndirectFormalResultFilter>;
-  using IndirectFormalResultRange = IteratorRange<IndirectFormalResultIter>;
+  using IndirectFormalResultRange = iterator_range<IndirectFormalResultIter>;
 
   /// A range of SILResultInfo for all formally indirect results.
   IndirectFormalResultRange getIndirectFormalResults() const {
-    auto filter =
-        llvm::make_filter_range(getResults(), IndirectFormalResultFilter());
-    return makeIteratorRange(filter.begin(), filter.end());
+    return llvm::make_filter_range(getResults(), IndirectFormalResultFilter());
   }
 
   struct DirectFormalResultFilter {
@@ -4157,13 +4155,11 @@
   };
   using DirectFormalResultIter =
       llvm::filter_iterator<const SILResultInfo *, DirectFormalResultFilter>;
-  using DirectFormalResultRange = IteratorRange<DirectFormalResultIter>;
+  using DirectFormalResultRange = iterator_range<DirectFormalResultIter>;
 
   /// A range of SILResultInfo for all formally direct results.
   DirectFormalResultRange getDirectFormalResults() const {
-    auto filter =
-        llvm::make_filter_range(getResults(), DirectFormalResultFilter());
-    return makeIteratorRange(filter.begin(), filter.end());
+    return llvm::make_filter_range(getResults(), DirectFormalResultFilter());
   }
 
   /// Get a single non-address SILType that represents all formal direct
diff --git a/include/swift/AST/USRGeneration.h b/include/swift/AST/USRGeneration.h
index 45f8c3d..7b96c4d 100644
--- a/include/swift/AST/USRGeneration.h
+++ b/include/swift/AST/USRGeneration.h
@@ -22,6 +22,7 @@
 #include "swift/Basic/LLVM.h"
 
 namespace swift {
+class Decl;
 class AbstractStorageDecl;
 class ValueDecl;
 class ExtensionDecl;
@@ -39,9 +40,9 @@
 /// \returns true if it failed, false on success.
 bool printDeclTypeUSR(const ValueDecl *D, raw_ostream &OS);
 
-/// Prints out the USR for the given Decl.
+/// Prints out the USR for the given ValueDecl.
 /// \returns true if it failed, false on success.
-bool printDeclUSR(const ValueDecl *D, raw_ostream &OS);
+bool printValueDeclUSR(const ValueDecl *D, raw_ostream &OS);
 
 /// Prints out the USR for the given ModuleEntity.
 /// \returns true if it failed, false on success.
@@ -56,6 +57,10 @@
 /// \returns true if it failed, false on success.
 bool printExtensionUSR(const ExtensionDecl *ED, raw_ostream &OS);
 
+/// Prints out the USR for the given Decl.
+/// \returns true if it failed, false on success.
+bool printDeclUSR(const Decl *D, raw_ostream &OS);
+
 } // namespace ide
 } // namespace swift
 
diff --git a/include/swift/Basic/BlotSetVector.h b/include/swift/Basic/BlotSetVector.h
index f6da190..bf57c31 100644
--- a/include/swift/Basic/BlotSetVector.h
+++ b/include/swift/Basic/BlotSetVector.h
@@ -67,14 +67,14 @@
 
   ArrayRef<Optional<ValueT>> getArray() const { return vector; }
 
-  llvm::iterator_range<const_iterator> getRange() const {
+  iterator_range<const_iterator> getRange() const {
     return {begin(), end()};
   }
 
   using const_reverse_iterator = typename VectorT::const_reverse_iterator;
   const_reverse_iterator rbegin() const { return vector.rbegin(); }
   const_reverse_iterator rend() const { return vector.rend(); }
-  llvm::iterator_range<const_reverse_iterator> getReverseRange() const {
+  iterator_range<const_reverse_iterator> getReverseRange() const {
     return {rbegin(), rend()};
   }
 
diff --git a/include/swift/Basic/LLVM.h b/include/swift/Basic/LLVM.h
index 3ce78f9..e3876ae 100644
--- a/include/swift/Basic/LLVM.h
+++ b/include/swift/Basic/LLVM.h
@@ -43,6 +43,7 @@
   template<typename T> class TinyPtrVector;
   template<typename T> class Optional;
   template <typename ...PTs> class PointerUnion;
+  template <typename IteratorT> class iterator_range;
   class SmallBitVector;
 
   // Other common classes.
@@ -63,6 +64,7 @@
 
   // Containers.
   using llvm::ArrayRef;
+  using llvm::iterator_range;
   using llvm::MutableArrayRef;
   using llvm::None;
   using llvm::Optional;
diff --git a/include/swift/Basic/Range.h b/include/swift/Basic/Range.h
index 8f46941..94f5661 100644
--- a/include/swift/Basic/Range.h
+++ b/include/swift/Basic/Range.h
@@ -15,8 +15,6 @@
 ///  This file provides classes and functions for conveniently working
 ///  with ranges,
 ///
-///  reversed returns an iterator_range out of the reverse iterators of a type.
-///
 ///  map creates an iterator_range which applies a function to all the elements
 ///  in another iterator_range.
 ///
@@ -26,10 +24,6 @@
 ///  indices returns the range of indices from [0..size()) on a
 ///  subscriptable type.
 ///
-///  Note that this is kept in Swift because it's really only useful in
-///  C++11, and there aren't any major open-source subprojects of LLVM
-///  that can use C++11 yet.
-///
 //===----------------------------------------------------------------------===//
 
 #ifndef SWIFT_BASIC_RANGE_H
@@ -44,14 +38,7 @@
 
 namespace swift {
   using llvm::make_range;
-  using llvm::iterator_range;
 
-  template<typename T>
-  inline auto reversed(T &&container)
-  -> decltype(llvm::make_range(container.rbegin(), container.rend())) {
-    return llvm::make_range(container.rbegin(), container.rend());
-  }
-  
   // Wrapper for std::transform that creates a new back-insertable container
   // and transforms a range into it.
   template<typename T, typename InputRange, typename MapFn>
@@ -234,9 +221,9 @@
 
 /// Returns a reverse Int range (start, end].
 static inline auto reverse_range(unsigned start, unsigned end) ->
-  decltype(reversed(range(start+1, end+1))) {
+  decltype(llvm::reverse(range(start+1, end+1))) {
   assert(start <= end && "Invalid integral range");
-  return reversed(range(start+1, end+1));
+  return llvm::reverse(range(start+1, end+1));
 }
 
 } // end namespace swift
diff --git a/include/swift/Basic/STLExtras.h b/include/swift/Basic/STLExtras.h
index 231737f..5c143c1 100644
--- a/include/swift/Basic/STLExtras.h
+++ b/include/swift/Basic/STLExtras.h
@@ -251,37 +251,13 @@
 
 /// @}
 
-/// A range of iterators.
-/// TODO: Add `llvm::iterator_range::empty()`, then remove this helper, along
-/// with the superfluous TransformIterator.
-template<typename Iterator>
-class IteratorRange {
-  Iterator First, Last;
-
-public:
-  using iterator = Iterator;
-
-  IteratorRange(Iterator first, Iterator last) : First(first), Last(last) { }
-  iterator begin() const { return First; }
-  iterator end() const { return Last; }
-  bool empty() const { return First == Last; }
-
-  typename std::iterator_traits<iterator>::value_type front() const { 
-    assert(!empty() && "Front of empty range");
-    return *begin(); 
-  }
-};
-
-/// Create a new iterator range.
-template<typename Iterator>
-inline IteratorRange<Iterator> 
-makeIteratorRange(Iterator first, Iterator last) {
-  return IteratorRange<Iterator>(first, last);
-}
 
 /// An iterator that transforms the result of an underlying bidirectional
 /// iterator with a given operation.
 ///
+/// Slightly different semantics from llvm::map_iterator, but we should
+/// probably figure out how to merge them eventually.
+///
 /// \tparam Iterator the underlying iterator.
 ///
 /// \tparam Operation A function object that transforms the underlying
diff --git a/include/swift/Basic/StringExtras.h b/include/swift/Basic/StringExtras.h
index b83b0d5..f60c533 100644
--- a/include/swift/Basic/StringExtras.h
+++ b/include/swift/Basic/StringExtras.h
@@ -315,29 +315,6 @@
     size_t findWord(StringRef string, StringRef word);
   } // end namespace camel_case
 
-/// Describes the role that a particular name has within a
-/// signature, which can affect how we omit needless words.
-enum class NameRole {
-  /// The base name of a function or method.
-  BaseName,
-
-  /// The base name of a method where the omission type name is the
-  /// 'self' type.
-  BaseNameSelf,
-
-  /// The first parameter of a function or method.
-  FirstParameter,
-
-  // Subsequent parameters in a function or method.
-  SubsequentParameter,
-
-  // The name of a property.
-  Property,
-
-  // A partial name; used internally.
-  Partial,
-};
-
 /// Flags used by \c OmissionTypeName to describe the input type.
 enum class OmissionTypeFlags {
   /// Whether the parameter with this type has a default argument.
diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h
index be9ab93..b9c0c38 100644
--- a/include/swift/Frontend/Frontend.h
+++ b/include/swift/Frontend/Frontend.h
@@ -395,6 +395,7 @@
   struct PartialModuleInputs {
     std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer;
     std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer;
+    std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer;
   };
 
   /// Contains \c MemoryBuffers for partial serialized module files and
@@ -555,13 +556,23 @@
 
   Optional<unsigned> getRecordedBufferID(const InputFile &input, bool &failed);
 
+  struct ModuleBuffers {
+    std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer;
+    std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer;
+    std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer;
+    ModuleBuffers(std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer,
+                  std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer = nullptr,
+                  std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer = nullptr):
+                    ModuleBuffer(std::move(ModuleBuffer)),
+                    ModuleDocBuffer(std::move(ModuleDocBuffer)),
+                    ModuleSourceInfoBuffer(std::move(ModuleSourceInfoBuffer)) {}
+  };
+
   /// Given an input file, return a buffer to use for its contents,
   /// and a buffer for the corresponding module doc file if one exists.
   /// On failure, return a null pointer for the first element of the returned
   /// pair.
-  std::pair<std::unique_ptr<llvm::MemoryBuffer>,
-            std::unique_ptr<llvm::MemoryBuffer>>
-  getInputBufferAndModuleDocBufferIfPresent(const InputFile &input);
+  Optional<ModuleBuffers> getInputBuffersIfPresent(const InputFile &input);
 
   /// Try to open the module doc file corresponding to the input parameter.
   /// Return None for error, nullptr if no such file exists, or the buffer if
@@ -569,6 +580,11 @@
   Optional<std::unique_ptr<llvm::MemoryBuffer>>
   openModuleDoc(const InputFile &input);
 
+  /// Try to open the module source info file corresponding to the input parameter.
+  /// Return None for error, nullptr if no such file exists, or the buffer if
+  /// one was found.
+  Optional<std::unique_ptr<llvm::MemoryBuffer>>
+  openModuleSourceInfo(const InputFile &input);
 public:
   /// Parses and type-checks all input files.
   void performSema();
diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h
index 0b027b5..e4a1e16 100644
--- a/include/swift/Frontend/ModuleInterfaceLoader.h
+++ b/include/swift/Frontend/ModuleInterfaceLoader.h
@@ -149,8 +149,10 @@
   std::error_code findModuleFilesInDirectory(
     AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
     StringRef ModuleDocFilename,
+    StringRef ModuleSourceInfoFilename,
     std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
 
   bool isCached(StringRef DepPath) override;
 
diff --git a/include/swift/Parse/ASTGen.h b/include/swift/Parse/ASTGen.h
index d139a6b..312f90f1 100644
--- a/include/swift/Parse/ASTGen.h
+++ b/include/swift/Parse/ASTGen.h
@@ -37,6 +37,9 @@
 
   // FIXME: remove when Syntax can represent all types and ASTGen can handle
   // them
+  /// Exprs that cannot be represented by Syntax or generated by ASTGen.
+  llvm::DenseMap<SourceLoc, Expr *> Exprs;
+
   /// Decl attributes that cannot be represented by Syntax or generated by
   /// ASTGen.
   llvm::DenseMap<SourceLoc, DeclAttributes> ParsedDeclAttrs;
@@ -81,6 +84,12 @@
 
   Expr *generate(const syntax::ExprSyntax &Expr, const SourceLoc Loc);
   Expr *generate(const syntax::IdentifierExprSyntax &Expr, const SourceLoc Loc);
+  Expr *generate(const syntax::SuperRefExprSyntax &Expr, const SourceLoc Loc);
+  Expr *generate(const syntax::ArrayExprSyntax &Expr, const SourceLoc Loc);
+  Expr *generate(const syntax::DictionaryExprSyntax &Expr, const SourceLoc Loc);
+  Expr *generate(const syntax::TupleExprSyntax &E, const SourceLoc Loc);
+  Expr *generate(const syntax::FunctionCallExprSyntax &E, const SourceLoc Loc);
+  Expr *generate(const syntax::MemberAccessExprSyntax &E, const SourceLoc Loc);
   Expr *generate(const syntax::EditorPlaceholderExprSyntax &Expr,
                  const SourceLoc Loc);
   Expr *generate(const syntax::SpecializeExprSyntax &Expr, const SourceLoc Loc);
@@ -99,6 +108,12 @@
                  const SourceLoc Loc);
   Expr *generate(const syntax::PoundDsohandleExprSyntax &Expr,
                  const SourceLoc Loc);
+  Expr *generate(const syntax::ObjcKeyPathExprSyntax &Expr,
+                 const SourceLoc Loc);
+  Expr *generate(const syntax::ObjectLiteralExprSyntax &Expr,
+                 const SourceLoc Loc);
+  Expr *generate(const syntax::CodeCompletionExprSyntax &Expr,
+                 const SourceLoc Loc);
   Expr *generate(const syntax::UnknownExprSyntax &Expr, const SourceLoc Loc);
 
   std::pair<DeclName, DeclNameLoc> generateUnqualifiedDeclName(
@@ -106,7 +121,14 @@
       const Optional<syntax::DeclNameArgumentsSyntax> &args,
       const SourceLoc Loc);
 
+  void generateExprTupleElementList(const syntax::TupleExprElementListSyntax &elements,
+                                    const SourceLoc Loc, bool isForCallArguments,
+                                    SmallVectorImpl<Expr *> &exprs,
+                                    SmallVectorImpl<Identifier> &exprLabels,
+                                    SmallVectorImpl<SourceLoc> &exprLabelLocs);
+
 private:
+  void validateCollectionElement(Expr *elementExpr);
 
   Expr *generateMagicIdentifierLiteralExpression(
       const syntax::TokenSyntax &PoundToken, const SourceLoc Loc);
@@ -210,6 +232,13 @@
   static SourceLoc advanceLocBegin(const SourceLoc &Loc,
                                    const syntax::Syntax &Node);
 
+  /// Advance \p Loc to the last non-missing token of the \p Node or, if it
+  /// doesn't contain any, the last non-missing token preceding it in the tree.
+  /// \p Loc must be the leading trivia of the first token in the tree in which
+  /// \p Node resides
+  static SourceLoc advanceLocEnd(const SourceLoc &Loc,
+                                 const syntax::Syntax &Node);
+
   ValueDecl *lookupInScope(DeclName Name);
 
   void addToScope(ValueDecl *D, bool diagnoseRedefinitions = true);
@@ -219,9 +248,13 @@
   TypeRepr *lookupType(syntax::TypeSyntax Type);
 
 public:
+  void addExpr(Expr *Expr, const SourceLoc Loc);
+  bool hasExpr(const SourceLoc Loc) const;
+  Expr *takeExpr(const SourceLoc Loc);
+
   void addDeclAttributes(DeclAttributes attrs, const SourceLoc Loc);
   bool hasDeclAttributes(SourceLoc Loc) const;
-  DeclAttributes getDeclAttributes(const SourceLoc Loc) const;
+  DeclAttributes takeDeclAttributes(const SourceLoc Loc);
 };
 } // namespace swift
 
diff --git a/include/swift/Parse/ParsedRawSyntaxNode.h b/include/swift/Parse/ParsedRawSyntaxNode.h
index 4cbd13f..b1cd403 100644
--- a/include/swift/Parse/ParsedRawSyntaxNode.h
+++ b/include/swift/Parse/ParsedRawSyntaxNode.h
@@ -52,6 +52,7 @@
   };
   struct DeferredLayoutNode {
     MutableArrayRef<ParsedRawSyntaxNode> Children;
+    CharSourceRange Range;
   };
   struct DeferredTokenNode {
     const ParsedTriviaPiece *TriviaPieces;
@@ -72,9 +73,9 @@
   /// Primary used for capturing a deferred missing token.
   bool IsMissing = false;
 
-  ParsedRawSyntaxNode(syntax::SyntaxKind k,
+  ParsedRawSyntaxNode(syntax::SyntaxKind k, CharSourceRange r,
                       MutableArrayRef<ParsedRawSyntaxNode> deferredNodes)
-    : DeferredLayout({deferredNodes}),
+    : DeferredLayout({deferredNodes, r}),
       SynKind(uint16_t(k)), TokKind(uint16_t(tok::unknown)),
       DK(DataKind::DeferredLayout) {
     assert(getKind() == k && "Syntax kind with too large value!");
@@ -211,14 +212,12 @@
     return copy;
   }
 
-  CharSourceRange getDeferredRange(bool includeTrivia) const {
+  CharSourceRange getDeferredRange() const {
     switch (DK) { 
     case DataKind::DeferredLayout:
-      return getDeferredLayoutRange(includeTrivia);
+      return getDeferredLayoutRange();
     case DataKind::DeferredToken:
-      return includeTrivia
-        ? getDeferredTokenRangeWithTrivia()
-        : getDeferredTokenRange();
+      return getDeferredTokenRangeWithTrivia();
     default:
       llvm_unreachable("node not deferred");
     }
@@ -243,20 +242,9 @@
 
   // Deferred Layout Data ====================================================//
 
-  CharSourceRange getDeferredLayoutRange(bool includeTrivia) const {
+  CharSourceRange getDeferredLayoutRange() const {
     assert(DK == DataKind::DeferredLayout);
-    auto HasValidRange = [includeTrivia](const ParsedRawSyntaxNode &Child) {
-      return !Child.isNull() && !Child.isMissing() &&
-        Child.getDeferredRange(includeTrivia).isValid();
-    };
-    auto first = llvm::find_if(getDeferredChildren(), HasValidRange);
-    if (first == getDeferredChildren().end())
-      return CharSourceRange();
-    auto last = llvm::find_if(llvm::reverse(getDeferredChildren()),
-                              HasValidRange);
-    auto firstRange = first->getDeferredRange(includeTrivia);
-    firstRange.widen(last->getDeferredRange(includeTrivia));
-    return firstRange;
+    return DeferredLayout.Range;
   }
   ArrayRef<ParsedRawSyntaxNode> getDeferredChildren() const {
     assert(DK == DataKind::DeferredLayout);
diff --git a/include/swift/Parse/ParsedSyntaxNodes.h.gyb b/include/swift/Parse/ParsedSyntaxNodes.h.gyb
index 36d3cc1..9c08e76 100644
--- a/include/swift/Parse/ParsedSyntaxNodes.h.gyb
+++ b/include/swift/Parse/ParsedSyntaxNodes.h.gyb
@@ -32,6 +32,9 @@
 %   if not node.is_syntax_collection():
 class Parsed${node.name};
 %   end
+%   if node.is_buildable():
+class Parsed${node.name}Builder;
+%   end
 % end
 
 % for node in SYNTAX_NODES + PARSEONLY_NODES:
@@ -79,6 +82,10 @@
   static bool classof(const ParsedSyntax *S) {
     return kindof(S->getKind());
   }
+
+%     if node.is_buildable():
+  using Builder = Parsed${node.name}Builder;
+%     end
 };
 
 %   end
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 04d8548..56ac653 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -924,12 +924,12 @@
                          bool AllowSepAfterLast, Diag<> ErrorDiag,
                          syntax::SyntaxKind Kind,
                          llvm::function_ref<ParserStatus()> callback);
-  ParserStatus parseListSyntax(tok RightK, SourceLoc LeftLoc,
-                               llvm::Optional<ParsedTokenSyntax> &LastComma,
-                               llvm::Optional<ParsedTokenSyntax> &Right,
-                               llvm::SmallVectorImpl<ParsedSyntax>& Junk,
-                               bool AllowSepAfterLast, Diag<> ErrorDiag,
-                               llvm::function_ref<ParserStatus()> callback);
+  template <typename ParsedNode>
+  ParserStatus parseListSyntax(
+      SmallVectorImpl<ParsedNode> &elements, bool AllowEmpty,
+      bool AllowSepAfterLast, llvm::function_ref<bool()> isAtCloseTok,
+      llvm::function_ref<ParserStatus(typename ParsedNode::Builder &)>
+          callback);
 
   void consumeTopLevelDecl(ParserPosition BeginParserPosition,
                            TopLevelCodeDecl *TLCD);
@@ -1482,6 +1482,7 @@
 
   //===--------------------------------------------------------------------===//
   // Expression Parsing
+  ParsedSyntaxResult<ParsedExprSyntax> parseExpressionSyntax(Diag<> ID);
   ParserResult<Expr> parseExpr(Diag<> ID) {
     return parseExprImpl(ID, /*isExprBasic=*/false);
   }
@@ -1505,9 +1506,14 @@
   ParserResult<Expr> parseExprPrimary(Diag<> ID, bool isExprBasic);
   ParserResult<Expr> parseExprUnary(Diag<> ID, bool isExprBasic);
   ParserResult<Expr> parseExprKeyPathObjC();
+  ParsedSyntaxResult<ParsedExprSyntax> parseExprObjcKeyPathSyntax();
   ParserResult<Expr> parseExprKeyPath();
   ParserResult<Expr> parseExprSelector();
   ParserResult<Expr> parseExprSuper();
+  ParsedSyntaxResult<ParsedExprSyntax> parseExprSuperSyntax();
+  ParserResult<Expr> parseExprUnresolvedMember(bool isExprBasic);
+  ParsedSyntaxResult<ParsedExprSyntax>
+  parseExprUnresolvedMemberSyntax(bool isExprBasic);
   ParserResult<Expr> parseExprStringLiteral();
 
   // todo [gsoc]: create new result type for ParsedSyntax
@@ -1610,8 +1616,11 @@
                                       SourceLoc &inLoc);
 
   Expr *parseExprAnonClosureArg();
-  ParserResult<Expr> parseExprList(tok LeftTok, tok RightTok,
-                                   syntax::SyntaxKind Kind);
+  ParserResult<Expr> parseExprParenOrTuple();
+  ParsedSyntaxResult<ParsedExprSyntax> parseExprTupleSyntax();
+  ParserStatus parseExprTupleElementListSyntax(
+      SmallVectorImpl<ParsedTupleExprElementSyntax> &elements,
+      llvm::function_ref<bool()> isAtCloseTok);
 
   /// Parse an expression list, keeping all of the pieces separated.
   ParserStatus parseExprList(tok leftTok, tok rightTok,
@@ -1622,33 +1631,43 @@
                              SmallVectorImpl<Identifier> &exprLabels,
                              SmallVectorImpl<SourceLoc> &exprLabelLocs,
                              SourceLoc &rightLoc,
-                             Expr *&trailingClosure,
-                             syntax::SyntaxKind Kind);
-
+                             Expr *&trailingClosure);
+  ParserStatus parseExprListSyntax(
+  tok leftK, tok rightK, bool isPostfix, bool isExprBasic,
+  llvm::function_ref<void(
+      ParsedTokenSyntax &&, ParsedTupleExprElementListSyntax &&,
+      Optional<ParsedTokenSyntax> &&, Optional<ParsedClosureExprSyntax> &&)>
+                      callback);
   ParserResult<Expr> parseTrailingClosure(SourceRange calleeRange);
+  ParsedSyntaxResult<ParsedClosureExprSyntax>
+  parseTrailingClosureSyntax(SourceRange calleeRange);
 
-  /// Parse an object literal.
-  ///
-  /// \param LK The literal kind as determined by the first token.
-  ParserResult<Expr> parseExprObjectLiteral(ObjectLiteralExpr::LiteralKind LK,
-                                            bool isExprBasic);
+  ParserResult<Expr> parseExprObjectLiteral(bool isExprBasic);
+  ParsedSyntaxResult<ParsedExprSyntax>
+  parseExprObjectLiteralSyntax(bool isExprBasic);
   ParserResult<Expr> parseExprQuoteLiteral();
   ParserResult<Expr> parseExprUnquote();
   ParserResult<Expr> parseExprCallSuffix(ParserResult<Expr> fn,
                                          bool isExprBasic);
   ParserResult<Expr> parseExprCollection();
-  ParserResult<Expr> parseExprCollectionElement(Optional<bool> &isDictionary);
+  ParsedSyntaxResult<ParsedExprSyntax> parseExprCollectionSyntax();
+  ParsedSyntaxResult<ParsedExprSyntax>
+  parseExprArraySyntax(ParsedTokenSyntax &&LSquare, SourceLoc LSquareLoc,
+                       ParsedSyntaxResult<ParsedExprSyntax> &&firstExpr);
+  ParsedSyntaxResult<ParsedExprSyntax>
+  parseExprDictionarySyntax(ParsedTokenSyntax &&LSquare, SourceLoc LSquareLoc,
+                            ParsedSyntaxResult<ParsedExprSyntax> &&firstExpr);
+
   ParserResult<Expr> parseExprPoundAssert();
-  ParserResult<Expr> parseExprArray(SourceLoc LSquareLoc);
-  ParserResult<Expr> parseExprDictionary(SourceLoc LSquareLoc);
   ParserResult<Expr> parseExprPoundUnknown(SourceLoc LSquareLoc);
+  ParsedSyntaxResult<ParsedExprSyntax>
+  parseExprPoundUnknownSyntax(Optional<ParsedTokenSyntax> &&LSquare,
+                              SourceLoc LSquareLoc);
   ParserResult<Expr>
   parseExprPoundCodeCompletion(Optional<StmtKind> ParentKind);
 
   UnresolvedDeclRefExpr *parseExprOperator();
 
-  void validateCollectionElement(ParserResult<Expr> element);
-
   //===--------------------------------------------------------------------===//
   // Statement Parsing
 
diff --git a/include/swift/SIL/Notifications.h b/include/swift/SIL/Notifications.h
index 6df8d36..91ab29c 100644
--- a/include/swift/SIL/Notifications.h
+++ b/include/swift/SIL/Notifications.h
@@ -194,7 +194,7 @@
   using iterator = llvm::mapped_iterator<
       decltype(handlerSet)::const_iterator,
       decltype(&DeserializationNotificationHandlerSet::getUnderlyingHandler)>;
-  using range = llvm::iterator_range<iterator>;
+  using range = iterator_range<iterator>;
 
   /// Returns an iterator to the first element of the handler set.
   ///
diff --git a/include/swift/SIL/SILFunctionConventions.h b/include/swift/SIL/SILFunctionConventions.h
index 92713b0..b4014e4 100644
--- a/include/swift/SIL/SILFunctionConventions.h
+++ b/include/swift/SIL/SILFunctionConventions.h
@@ -193,10 +193,9 @@
     if (silConv.loweredAddresses)
       return funcTy->getIndirectFormalResults();
 
-    auto filter = llvm::make_filter_range(
-        makeIteratorRange((const SILResultInfo *)0, (const SILResultInfo *)0),
+    return llvm::make_filter_range(
+        llvm::make_range((const SILResultInfo *)0, (const SILResultInfo *)0),
         SILFunctionType::IndirectFormalResultFilter());
-    return makeIteratorRange(filter.begin(), filter.end());
   }
 
   struct SILResultTypeFunc {
@@ -210,16 +209,12 @@
 
   using IndirectSILResultTypeIter =
       llvm::mapped_iterator<IndirectSILResultIter, SILResultTypeFunc>;
-  using IndirectSILResultTypeRange = IteratorRange<IndirectSILResultTypeIter>;
+  using IndirectSILResultTypeRange = iterator_range<IndirectSILResultTypeIter>;
 
   /// Return a range of SILTypes for each result passed as an address-typed SIL
   /// argument.
   IndirectSILResultTypeRange getIndirectSILResultTypes() const {
-    return makeIteratorRange(
-        IndirectSILResultTypeIter(getIndirectSILResults().begin(),
-                                  SILResultTypeFunc(silConv)),
-        IndirectSILResultTypeIter(getIndirectSILResults().end(),
-                                  SILResultTypeFunc(silConv)));
+    return llvm::map_range(getIndirectSILResults(), SILResultTypeFunc(silConv));
   }
 
   /// Get the number of SIL results directly returned by SIL value.
@@ -238,28 +233,23 @@
   };
   using DirectSILResultIter =
       llvm::filter_iterator<const SILResultInfo *, DirectSILResultFilter>;
-  using DirectSILResultRange = IteratorRange<DirectSILResultIter>;
+  using DirectSILResultRange = iterator_range<DirectSILResultIter>;
 
   /// Return a range of direct result information for results directly returned
   /// by SIL value.
   DirectSILResultRange getDirectSILResults() const {
-    auto filter = llvm::make_filter_range(
+    return llvm::make_filter_range(
         funcTy->getResults(), DirectSILResultFilter(silConv.loweredAddresses));
-    return makeIteratorRange(filter.begin(), filter.end());
   }
 
   using DirectSILResultTypeIter =
       llvm::mapped_iterator<DirectSILResultIter, SILResultTypeFunc>;
-  using DirectSILResultTypeRange = IteratorRange<DirectSILResultTypeIter>;
+  using DirectSILResultTypeRange = iterator_range<DirectSILResultTypeIter>;
 
   /// Return a range of SILTypes for each result directly returned
   /// by SIL value.
   DirectSILResultTypeRange getDirectSILResultTypes() const {
-    return makeIteratorRange(
-        DirectSILResultTypeIter(getDirectSILResults().begin(),
-                                SILResultTypeFunc(silConv)),
-        DirectSILResultTypeIter(getDirectSILResults().end(),
-                                SILResultTypeFunc(silConv)));
+    return llvm::map_range(getDirectSILResults(), SILResultTypeFunc(silConv));
   }
 
   //===--------------------------------------------------------------------===//
@@ -288,16 +278,13 @@
 
   using SILParameterTypeIter =
       llvm::mapped_iterator<const SILParameterInfo *, SILParameterTypeFunc>;
-  using SILParameterTypeRange = IteratorRange<SILParameterTypeIter>;
+  using SILParameterTypeRange = iterator_range<SILParameterTypeIter>;
 
   /// Return a range of SILTypes for each function parameter, not including
   /// indirect results.
   SILParameterTypeRange getParameterSILTypes() const {
-    return makeIteratorRange(
-        SILParameterTypeIter(funcTy->getParameters().begin(),
-                             SILParameterTypeFunc(silConv)),
-        SILParameterTypeIter(funcTy->getParameters().end(),
-                             SILParameterTypeFunc(silConv)));
+    return llvm::map_range(funcTy->getParameters(),
+                           SILParameterTypeFunc(silConv));
   }
 
   //===--------------------------------------------------------------------===//
@@ -312,14 +299,10 @@
 
   using SILYieldTypeIter =
       llvm::mapped_iterator<const SILYieldInfo *, SILParameterTypeFunc>;
-  using SILYieldTypeRange = IteratorRange<SILYieldTypeIter>;
+  using SILYieldTypeRange = iterator_range<SILYieldTypeIter>;
 
   SILYieldTypeRange getYieldSILTypes() const {
-    return makeIteratorRange(
-        SILYieldTypeIter(funcTy->getYields().begin(),
-                         SILParameterTypeFunc(silConv)),
-        SILYieldTypeIter(funcTy->getYields().end(),
-                         SILParameterTypeFunc(silConv)));
+    return llvm::map_range(funcTy->getYields(), SILParameterTypeFunc(silConv));
   }
 
   SILYieldInfo getYieldInfoForOperandIndex(unsigned opIndex) const {
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 37e3508..b889162 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -170,12 +170,12 @@
   reverse_iterator rbegin() const;
   reverse_iterator rend() const;
 
-  using range = llvm::iterator_range<iterator>;
+  using range = iterator_range<iterator>;
   range getValues() const;
-  using reverse_range = llvm::iterator_range<reverse_iterator>;
+  using reverse_range = iterator_range<reverse_iterator>;
   reverse_range getReversedValues() const;
 
-  using type_range = llvm::iterator_range<
+  using type_range = iterator_range<
     llvm::mapped_iterator<iterator, SILType(*)(SILValue), SILType>>;
   type_range getTypes() const;
 
diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h
index 6d4e918..3a73ea0 100644
--- a/include/swift/SIL/SILValue.h
+++ b/include/swift/SIL/SILValue.h
@@ -282,7 +282,7 @@
   template <typename Subclass>
   using DowncastUserFilterRange =
       DowncastFilterRange<Subclass,
-                          llvm::iterator_range<llvm::mapped_iterator<
+                          iterator_range<llvm::mapped_iterator<
                               use_iterator, UseToUser, SILInstruction *>>>;
 
   /// Iterate over the use list of this ValueBase visiting all users that are of
diff --git a/include/swift/SILOptimizer/Analysis/ClosureScope.h b/include/swift/SILOptimizer/Analysis/ClosureScope.h
index b785579..7c428ac 100644
--- a/include/swift/SILOptimizer/Analysis/ClosureScope.h
+++ b/include/swift/SILOptimizer/Analysis/ClosureScope.h
@@ -102,7 +102,7 @@
       return None;
     }
   };
-  using IndexRange = IteratorRange<int *>;
+  using IndexRange = iterator_range<int *>;
 
 public:
   // A range of SILFunction scopes converted from their scope indices and
diff --git a/include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h b/include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h
index c3682a3..985b9cb 100644
--- a/include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h
@@ -591,11 +591,11 @@
     return getSubregionData().rend();
   }
 
-  llvm::iterator_range<subregion_iterator> getSubregions() const {
+  iterator_range<subregion_iterator> getSubregions() const {
     return {subregion_begin(), subregion_end()};
   }
 
-  llvm::iterator_range<subregion_reverse_iterator>
+  iterator_range<subregion_reverse_iterator>
   getReverseSubregions() const {
     return {subregion_rbegin(), subregion_rend()};
   }
@@ -674,7 +674,7 @@
   unsigned succ_size() const { return Succs.size(); }
 
 private:
-  using InnerSuccRange = IteratorRange<decltype(Succs)::const_iterator>;
+  using InnerSuccRange = iterator_range<decltype(Succs)::const_iterator>;
 
 public:
   using SuccRange =
@@ -964,7 +964,7 @@
   const_iterator end() const { return IDToRegionMap.end(); }
   unsigned size() const { return IDToRegionMap.size(); }
   bool empty() const { return IDToRegionMap.empty(); }
-  llvm::iterator_range<const_iterator> getRegions() const {
+  iterator_range<const_iterator> getRegions() const {
     return {begin(), end()};
   }
 
diff --git a/include/swift/SILOptimizer/Utils/InstOptUtils.h b/include/swift/SILOptimizer/Utils/InstOptUtils.h
index 15c5f82..5d1af19 100644
--- a/include/swift/SILOptimizer/Utils/InstOptUtils.h
+++ b/include/swift/SILOptimizer/Utils/InstOptUtils.h
@@ -38,13 +38,12 @@
 /// Transform a Use Range (Operand*) into a User Range (SILInstruction*)
 using UserTransform = std::function<SILInstruction *(Operand *)>;
 using ValueBaseUserRange =
-    TransformRange<IteratorRange<ValueBase::use_iterator>, UserTransform>;
+    TransformRange<iterator_range<ValueBase::use_iterator>, UserTransform>;
 
 inline ValueBaseUserRange
 makeUserRange(iterator_range<ValueBase::use_iterator> range) {
   auto toUser = [](Operand *operand) { return operand->getUser(); };
-  return makeTransformRange(makeIteratorRange(range.begin(), range.end()),
-                            UserTransform(toUser));
+  return makeTransformRange(range, UserTransform(toUser));
 }
 
 using DeadInstructionSet = llvm::SmallSetVector<SILInstruction *, 8>;
diff --git a/include/swift/Sema/IDETypeChecking.h b/include/swift/Sema/IDETypeChecking.h
index e0577e1..2ab4540 100644
--- a/include/swift/Sema/IDETypeChecking.h
+++ b/include/swift/Sema/IDETypeChecking.h
@@ -20,21 +20,31 @@
 #define SWIFT_SEMA_IDETYPECHECKING_H
 
 #include "llvm/ADT/MapVector.h"
+#include "swift/AST/Identifier.h"
 #include "swift/Basic/SourceLoc.h"
 #include <memory>
 
 namespace swift {
   class AbstractFunctionDecl;
+  class ASTContext;
+  class ConcreteDeclRef;
   class Decl;
+  class DeclContext;
+  class DeclName;
+  enum class DeclRefKind;
   class Expr;
   class ExtensionDecl;
+  class FunctionType;
+  class NominalTypeDecl;
+  class PatternBindingDecl;
   class ProtocolDecl;
+  class SourceFile;
+  class SubscriptDecl;
+  class TopLevelCodeDecl;
   class Type;
   class TypeChecker;
-  class DeclContext;
-  class ConcreteDeclRef;
   class ValueDecl;
-  class DeclName;
+  struct PrintOptions;
 
   /// Typecheck binding initializer at \p bindingIndex.
   void typeCheckPatternBinding(PatternBindingDecl *PBD, unsigned bindingIndex);
@@ -127,12 +137,6 @@
   /// \returns true on success, false on error.
   bool typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD);
 
-  /// Creates a type checker instance on the given AST context, if it
-  /// doesn't already have one.
-  ///
-  /// \returns a reference to the type checker instance.
-  TypeChecker &createTypeChecker(ASTContext &Ctx);
-
   struct ExtensionInfo {
     // The extension with the declarations to apply.
     ExtensionDecl *Ext;
diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h
index cb1c185..7a5f884 100644
--- a/include/swift/Serialization/SerializedModuleLoader.h
+++ b/include/swift/Serialization/SerializedModuleLoader.h
@@ -53,6 +53,7 @@
   bool findModule(AccessPathElem moduleID,
                   std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
                   std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
+                  std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
                   bool &isFramework, bool &isSystemModule);
 
   /// Attempts to search the provided directory for a loadable serialized
@@ -70,20 +71,30 @@
   virtual std::error_code findModuleFilesInDirectory(
       AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
       StringRef ModuleDocFilename,
+      StringRef ModuleSourceInfoFilename,
       std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-      std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) = 0;
+      std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+      std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) = 0;
 
   std::error_code
   openModuleFiles(AccessPathElem ModuleID,
                   StringRef ModulePath, StringRef ModuleDocPath,
+                  StringRef ModuleSourceInfoName,
                   std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-                  std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer);
+                  std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+                  std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer);
 
   std::error_code
   openModuleDocFile(AccessPathElem ModuleID,
                     StringRef ModuleDocPath,
                     std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer);
 
+  void
+  openModuleSourceInfoFileIfPresent(AccessPathElem ModuleID,
+                                    StringRef ModulePath,
+                                    StringRef ModuleSourceInfoFileName,
+                  std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer);
+
   /// If the module loader subclass knows that all options have been tried for
   /// loading an architecture-specific file out of a swiftmodule bundle, try
   /// to list the architectures that \e are present.
@@ -116,6 +127,7 @@
   FileUnit *loadAST(ModuleDecl &M, Optional<SourceLoc> diagLoc,
                     std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
                     std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
+                    std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
                     bool isFramework, bool treatAsPartialModule);
 
   /// Check whether the module with a given name can be imported without
@@ -163,8 +175,10 @@
   std::error_code findModuleFilesInDirectory(
       AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
       StringRef ModuleDocFilename,
+      StringRef ModuleSourceInfoFilename,
       std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-      std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
+      std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+      std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
 
   bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
                                    StringRef moduleName,
@@ -203,8 +217,10 @@
   std::error_code findModuleFilesInDirectory(
       AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
       StringRef ModuleDocFilename,
+      StringRef ModuleSourceInfoFilename,
       std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-      std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
+      std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+      std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
 
   bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
                                    StringRef moduleName,
@@ -317,6 +333,8 @@
 
   Optional<StringRef> getGroupNameByUSR(StringRef USR) const override;
 
+  Optional<BasicDeclLocs> getBasicLocsForDecl(const Decl *D) const override;
+
   void collectAllGroups(std::vector<StringRef> &Names) const override;
 
   virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h
index bd2931a..fa47753 100644
--- a/include/swift/Subsystems.h
+++ b/include/swift/Subsystems.h
@@ -65,6 +65,7 @@
   class SyntaxParsingCache;
   class Token;
   class TopLevelContext;
+  class TypeChecker;
   struct TypeLoc;
   class UnifiedStatsReporter;
   enum class SourceFileKind;
@@ -194,6 +195,12 @@
     SkipNonInlinableFunctionBodies = 1 << 4,
   };
 
+  /// Creates a type checker instance on the given AST context, if it
+  /// doesn't already have one.
+  ///
+  /// \returns a reference to the type checker instance.
+  TypeChecker &createTypeChecker(ASTContext &Ctx);
+
   /// Once parsing and name-binding are complete, this walks the AST to resolve
   /// types and diagnose problems therein.
   ///
diff --git a/include/swift/Syntax/Syntax.h b/include/swift/Syntax/Syntax.h
index 31fac98..0ca7754 100644
--- a/include/swift/Syntax/Syntax.h
+++ b/include/swift/Syntax/Syntax.h
@@ -169,6 +169,9 @@
   /// Returns true if the node is "present" in the source.
   bool isPresent() const;
 
+  /// Get the node immediately before this current node that does contain a
+  /// non-missing token. Return nullptr if we cannot find such node.
+  Optional<Syntax> getPreviousNode() const;
 
   /// Returns the first non-missing token in this syntax. Returns None if there
   /// is no non-missing token.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 9288d42..8905b96 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4808,7 +4808,6 @@
   ctx.getImpl().OriginalWrappedProperties[this] = originalProperty;
 }
 
-// SWIFT_ENABLE_TENSORFLOW
 IndexSubset *
 IndexSubset::get(ASTContext &ctx, const SmallBitVector &indices) {
   auto &foldingSet = ctx.getImpl().IndexSubsets;
@@ -4829,7 +4828,7 @@
   foldingSet.InsertNode(newNode, insertPos);
   return newNode;
 }
-
+// TODO(saeta): CHECK IF CAN BE REMOVED!
 AutoDiffDerivativeFunctionIdentifier *
 AutoDiffDerivativeFunctionIdentifier::get(
     AutoDiffDerivativeFunctionKind kind, IndexSubset *parameterIndices,
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index bca3561..40fa577 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -967,19 +967,21 @@
         PrintWithColorRAII(OS, InterfaceTypeColor) << "'";
       }
 
-      switch (P->getSpecifier()) {
-      case ParamDecl::Specifier::Default:
-        /* nothing */
-        break;
-      case ParamDecl::Specifier::InOut:
-        OS << " inout";
-        break;
-      case ParamDecl::Specifier::Shared:
-        OS << " shared";
-        break;
-      case ParamDecl::Specifier::Owned:
-        OS << " owned";
-        break;
+      if (auto specifier = P->getCachedSpecifier()) {
+        switch (*specifier) {
+        case ParamDecl::Specifier::Default:
+          /* nothing */
+          break;
+        case ParamDecl::Specifier::InOut:
+          OS << " inout";
+          break;
+        case ParamDecl::Specifier::Shared:
+          OS << " shared";
+          break;
+        case ParamDecl::Specifier::Owned:
+          OS << " owned";
+          break;
+        }
       }
 
       if (P->isVariadic())
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index c379427..04d8b64 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -657,6 +657,8 @@
 
   if (auto AFD = dyn_cast<AbstractFunctionDecl>(D->getDeclContext())) {
     ParamList = AFD->getParameters();
+  } else if (auto EED = dyn_cast<EnumElementDecl>(D->getDeclContext())) {
+    ParamList = EED->getParameterList();
   } else {
     auto ACE = cast<AbstractClosureExpr>(D->getDeclContext());
     ParamList = ACE->getParameters();
@@ -1226,7 +1228,7 @@
   }
   if (auto gpRoot = dyn_cast<GenericTypeParamType>(base)) {
     bool first = true;
-    for (auto *member : reversed(path)) {
+    for (auto *member : llvm::reverse(path)) {
       appendAssociatedTypeName(member);
       appendListSeparator(first);
     }
@@ -1458,7 +1460,7 @@
     module = Mod ? Mod : nominal->getModuleContext();
     subMap = type->getContextSubstitutionMap(module, nominal);
   }
-  
+
   appendRetroactiveConformances(subMap, module);
 }
 
@@ -2619,7 +2621,7 @@
 
   auto conformingType = conformance->getType();
   appendType(conformingType->getCanonicalType());
-  
+
   appendProtocolName(conformance->getProtocol());
 
   bool needsModule = true;
@@ -2741,6 +2743,17 @@
                                       const ProtocolConformance *conformance) {
   auto module = conformance->getDeclContext()->getParentModule();
 
+  // It's possible that we might not have a generic signature here to get
+  // the conformance access path (for example, when mangling types for
+  // debugger). In that case, we can use the generic signature of the
+  // conformance (if it's present).
+  auto conformanceSig = conformance->getGenericSignature();
+  auto shouldUseConformanceSig = !CurGenericSignature && conformanceSig;
+  llvm::SaveAndRestore<CanGenericSignature> savedSignature(
+      CurGenericSignature, shouldUseConformanceSig
+                               ? conformanceSig->getCanonicalSignature()
+                               : CurGenericSignature);
+
   // Conforming type.
   Type conformingType = conformance->getType();
   if (conformingType->hasArchetype())
@@ -2770,7 +2783,7 @@
         assert(CurGenericSignature &&
                "Need a generic signature to resolve conformance");
         auto conformanceAccessPath =
-          CurGenericSignature->getConformanceAccessPath(type, proto);
+            CurGenericSignature->getConformanceAccessPath(type, proto);
         appendDependentProtocolConformance(conformanceAccessPath);
       } else if (auto opaqueType = canType->getAs<OpaqueTypeArchetypeType>()) {
         GenericSignature opaqueSignature = opaqueType->getBoundSignature();
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 03d9cb0..a6a4584 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -2526,8 +2526,10 @@
     });
   if (decl->hasInterfaceType()) {
     Printer << ": ";
-    auto tyLoc = decl->getTypeLoc();
-    if (!tyLoc.getTypeRepr())
+    TypeLoc tyLoc;
+    if (auto *repr = decl->getTypeRepr())
+      tyLoc = TypeLoc(repr, decl->getInterfaceType());
+    else
       tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());
 
     Printer.printDeclResultTypePre(decl, tyLoc);
@@ -2595,13 +2597,15 @@
     Printer << ": ";
   };
 
-  auto TheTypeLoc = param->getTypeLoc();
-
   printAttributes(param);
   printArgName();
 
-  if (!TheTypeLoc.getTypeRepr() && param->hasInterfaceType())
+  TypeLoc TheTypeLoc;
+  if (auto *repr = param->getTypeRepr()) {
+    TheTypeLoc = TypeLoc(repr, param->getInterfaceType());
+  } else {
     TheTypeLoc = TypeLoc::withoutLoc(param->getInterfaceType());
+  }
 
   // If the parameter is variadic, we will print the "..." after it, but we have
   // to strip off the added array type.
diff --git a/lib/AST/ASTScopeCreation.cpp b/lib/AST/ASTScopeCreation.cpp
index be51ced..69822cc 100644
--- a/lib/AST/ASTScopeCreation.cpp
+++ b/lib/AST/ASTScopeCreation.cpp
@@ -23,6 +23,7 @@
 #include "swift/AST/Initializer.h"
 #include "swift/AST/LazyResolver.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/NameLookupRequests.h"
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/Pattern.h"
 #include "swift/AST/SourceFile.h"
@@ -358,7 +359,8 @@
       if (auto *ip = child->insertionPointForDeferredExpansion().getPtrOrNull())
         return ip;
     }
-    ASTScopeImpl *insertionPoint = child->expandAndBeCurrent(*this);
+    ASTScopeImpl *insertionPoint =
+        child->expandAndBeCurrentDetectingRecursion(*this);
     ASTScopeAssert(child->verifyThatThisNodeComeAfterItsPriorSibling(),
                    "Ensure search will work");
     return insertionPoint;
@@ -399,7 +401,6 @@
 
   // A safe way to discover this, without creating a circular request.
   // Cannot call getAttachedPropertyWrappers.
-  // rdar://55263708
   static bool hasAttachedPropertyWrapper(VarDecl *vd) {
     return AttachedPropertyWrapperScope::getSourceRangeOfVarDecl(vd).isValid();
   }
@@ -448,7 +449,7 @@
       if (auto *specializeAttr = dyn_cast<SpecializeAttr>(attr))
         sortedSpecializeAttrs.push_back(specializeAttr);
     }
-    // Part of rdar://53921774 rm extra copy
+    // TODO: rm extra copy
     for (auto *specializeAttr : sortBySourceRange(sortedSpecializeAttrs))
       fn(specializeAttr);
   }
@@ -474,13 +475,14 @@
   std::vector<ASTNode> expandIfConfigClausesThenCullAndSortElementsOrMembers(
       ArrayRef<ASTNode> input) const {
     auto cleanedupNodes = sortBySourceRange(cull(expandIfConfigClauses(input)));
-    // TODO: uncomment when working on rdar://53627317
+    // TODO: uncomment when working on not creating two pattern binding decls at
+    // same location.
     //    findCollidingPatterns(cleanedupNodes);
     return cleanedupNodes;
   }
 
 public:
-  /// When ASTScopes are enabled for code completion, rdar://53321156
+  /// When ASTScopes are enabled for code completion,
   /// IfConfigs will pose a challenge because we may need to field lookups into
   /// the inactive clauses, but the AST contains redundancy: the active clause's
   /// elements are present in the members or elements of an IterableTypeDecl or
@@ -518,7 +520,7 @@
         if (auto *const cond = clause.Cond)
           expansion.push_back(cond);
         if (clause.isActive) {
-          // rdar://53922172
+          // TODO: Move this check into ASTVerifier
           ASTScopeAssert(isInAnActiveNode, "Clause should not be marked active "
                                            "unless it's context is active");
           // get inactive nodes that nest in active clauses
@@ -540,7 +542,8 @@
   /// because they overlap EnumElements and AST includes the elements in the
   /// members.
   std::vector<ASTNode> cull(ArrayRef<ASTNode> input) const {
-    // When working on rdar://53971116 may have to cull more.
+    // TODO: Investigate whether to move the real EndLoc tracking of
+    // SubscriptDecl up into AbstractStorageDecl. May have to cull more.
     std::vector<ASTNode> culled;
     llvm::copy_if(input, std::back_inserter(culled), [&](ASTNode n) {
       ASTScopeAssert(
@@ -553,7 +556,8 @@
   }
 
   /// TODO: The parser yields two decls at the same source loc with the same
-  /// kind. Call me when tackling rdar://53627317, then move this to
+  /// kind. TODO:  me when fixing parser's proclivity to create two
+  /// PatternBindingDecls at the same source location, then move this to
   /// ASTVerifier.
   ///
   /// In all cases the first pattern seems to carry the initializer, and the
@@ -618,7 +622,6 @@
     }
   }
 
-  /// See rdar://53921962
   /// Templated to work on either ASTNodes, Decl*'s, or whatnot.
   template <typename Rangeable>
   std::vector<Rangeable>
@@ -688,9 +691,8 @@
   bool containsAllDeclContextsFromAST() {
     auto allDeclContexts = findLocalizableDeclContextsInAST();
     llvm::DenseMap<const DeclContext *, const ASTScopeImpl *> bogusDCs;
-    bool rebuilt = false;
     sourceFileScope->preOrderDo([&](ASTScopeImpl *scope) {
-      rebuilt |= scope->reexpandIfObsolete(*this);
+      scope->expandAndBeCurrentDetectingRecursion(*this);
     });
     sourceFileScope->postOrderDo([&](ASTScopeImpl *scope) {
       if (auto *dc = scope->getDeclContext().getPtrOrNull()) {
@@ -707,8 +709,6 @@
       d->getSourceRange().dump(ctx.SourceMgr);
       llvm::errs() << " : ";
       d->dump(llvm::errs());
-      if (rebuilt)
-        llvm::errs() << " (rebuilt)";
       llvm::errs() << "\n";
     };
     bool foundOmission = false;
@@ -784,35 +784,17 @@
 }
 
 void ASTSourceFileScope::buildFullyExpandedTree() {
-  addNewDeclsToScopeTree();
-  preOrderChildrenDo(
-      [&](ASTScopeImpl *s) { s->reexpandIfObsolete(*scopeCreator); });
+  expandAndBeCurrentDetectingRecursion(*scopeCreator);
+  preOrderChildrenDo([&](ASTScopeImpl *s) {
+    s->expandAndBeCurrentDetectingRecursion(*scopeCreator);
+  });
 }
 
 void ASTSourceFileScope::
     buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals() {
-  addNewDeclsToScopeTree();
+      expandAndBeCurrentDetectingRecursion(*scopeCreator);
 }
 
-void ASTSourceFileScope::addNewDeclsToScopeTree() {
-  ASTScopeAssert(SF && scopeCreator,
-                 "Must already have a SourceFile and a ScopeCreator.");
-  ArrayRef<Decl *> decls = SF->Decls;
-  // Assume that decls are only added at the end, in source order
-  ArrayRef<Decl *> newDecls = decls.slice(numberOfDeclsAlreadySeen);
-  std::vector<ASTNode> newNodes(newDecls.begin(), newDecls.end());
-  insertionPoint =
-      scopeCreator->addSiblingsToScopeTree(insertionPoint, this, newNodes);
-
-  // TODO: use regular expansion machinery for ASTSourceFileScope
-  // rdar://55562483
-  numberOfDeclsAlreadySeen = SF->Decls.size();
-  setWasExpanded();
-
-  // Too slow to perform all the time:
-  //    ASTScopeAssert(scopeCreator->containsAllDeclContextsFromAST(),
-  //           "ASTScope tree missed some DeclContexts or made some up");
-}
 
 ASTSourceFileScope::ASTSourceFileScope(SourceFile *SF,
                                        ScopeCreator *scopeCreator)
@@ -976,9 +958,10 @@
     auto *insertionPoint = parentScope;
     for (unsigned i = 0; i < patternBinding->getPatternList().size(); ++i) {
       // TODO: Won't need to do so much work to avoid creating one without
-      // a SourceRange once rdar://53627317 is done and
-      // getSourceRangeOfThisASTNode for PatternEntryDeclScope is simplified to
-      // use the PatternEntry's source range.
+      // a SourceRange once parser is fixed to not create two
+      // PatternBindingDecls with same locaiton and getSourceRangeOfThisASTNode
+      // for PatternEntryDeclScope is simplified to use the PatternEntry's
+      // source range.
       auto &patternEntry = patternBinding->getPatternList()[i];
       if (!patternEntry.getOriginalInit()) {
         bool found = false;
@@ -1091,7 +1074,6 @@
   // SWIFT_ENABLE_TENSORFLOW END
 
   // Sort in order to include synthesized ones, which are out of order.
-  // Part of rdar://53921774 rm extra copy
   for (auto *accessor : sortBySourceRange(accessorsToScope))
     addToScopeTree(accessor, parent);
 }
@@ -1128,7 +1110,42 @@
 
 #pragma mark implementations of expansion
 
+ASTScopeImpl *
+ASTScopeImpl::expandAndBeCurrentDetectingRecursion(ScopeCreator &scopeCreator) {
+  return evaluateOrDefault(scopeCreator.getASTContext().evaluator,
+                           ExpandASTScopeRequest{this, &scopeCreator}, nullptr);
+}
+
+llvm::Expected<ASTScopeImpl *>
+ExpandASTScopeRequest::evaluate(Evaluator &evaluator, ASTScopeImpl *parent,
+                                ScopeCreator *scopeCreator) const {
+  auto *insertionPoint = parent->expandAndBeCurrent(*scopeCreator);
+  ASTScopeAssert(insertionPoint,
+                 "Used to return a null pointer if the insertion point would "
+                 "not be used, but it breaks the request dependency hashing");
+  return insertionPoint;
+}
+
+bool ASTScopeImpl::doesExpansionOnlyAddNewDeclsAtEnd() const { return false; }
+bool ASTSourceFileScope::doesExpansionOnlyAddNewDeclsAtEnd() const {
+  return true;
+}
+
 ASTScopeImpl *ASTScopeImpl::expandAndBeCurrent(ScopeCreator &scopeCreator) {
+
+  // We might be reexpanding, so save any scopes that were inserted here from
+  // above it in the AST
+  auto astAncestorScopes = rescueASTAncestorScopesForReuseFromMeOrDescendants();
+  ASTScopeAssert(astAncestorScopes.empty() ||
+                     !doesExpansionOnlyAddNewDeclsAtEnd(),
+                 "ASTSourceFileScope has no ancestors to be rescued.");
+
+  // If reexpanding, we need to remove descendant decls from the duplication set
+  // in order to re-add them as sub-scopes. Since expansion only adds new Decls
+  // at end, don't bother with descendants
+  if (!doesExpansionOnlyAddNewDeclsAtEnd())
+    disownDescendants(scopeCreator);
+
   auto *insertionPoint = expandSpecifically(scopeCreator);
   if (scopeCreator.shouldBeLazy()) {
     ASTScopeAssert(!insertionPointForDeferredExpansion() ||
@@ -1138,6 +1155,7 @@
                    "accurate before expansion, the insertion point before "
                    "expansion must be the same as after expansion.");
   }
+  replaceASTAncestorScopes(astAncestorScopes);
   setWasExpanded();
   beCurrent();
   ASTScopeAssert(checkSourceRangeAfterExpansion(scopeCreator.getASTContext()),
@@ -1163,6 +1181,7 @@
 #define NO_EXPANSION(Scope)                                                    \
   ASTScopeImpl *Scope::expandSpecifically(ScopeCreator &) { return this; }
 
+CREATES_NEW_INSERTION_POINT(ASTSourceFileScope)
 CREATES_NEW_INSERTION_POINT(ParameterListScope)
 CREATES_NEW_INSERTION_POINT(ConditionalClauseScope)
 CREATES_NEW_INSERTION_POINT(GuardStmtScope)
@@ -1194,7 +1213,6 @@
 NO_NEW_INSERTION_POINT(WholeClosureScope)
 
 NO_EXPANSION(GenericParamScope)
-NO_EXPANSION(ASTSourceFileScope)
 NO_EXPANSION(ClosureParametersScope)
 NO_EXPANSION(SpecializeAttributeScope)
 // SWIFT_ENABLE_TENSORFLOW
@@ -1207,6 +1225,22 @@
 #undef NO_NEW_INSERTION_POINT
 
 AnnotatedInsertionPoint
+ASTSourceFileScope::expandAScopeThatCreatesANewInsertionPoint(
+    ScopeCreator &scopeCreator) {
+  ASTScopeAssert(SF, "Must already have a SourceFile.");
+  ArrayRef<Decl *> decls = SF->Decls;
+  // Assume that decls are only added at the end, in source order
+  ArrayRef<Decl *> newDecls = decls.slice(numberOfDeclsAlreadySeen);
+  std::vector<ASTNode> newNodes(newDecls.begin(), newDecls.end());
+  insertionPoint =
+      scopeCreator.addSiblingsToScopeTree(insertionPoint, this, newNodes);
+  // Too slow to perform all the time:
+  //    ASTScopeAssert(scopeCreator->containsAllDeclContextsFromAST(),
+  //           "ASTScope tree missed some DeclContexts or made some up");
+  return {insertionPoint, "Next time decls are added they go here."};
+}
+
+AnnotatedInsertionPoint
 ParameterListScope::expandAScopeThatCreatesANewInsertionPoint(
     ScopeCreator &scopeCreator) {
   // Each initializer for a function parameter is its own, sibling, scope.
@@ -1264,7 +1298,8 @@
                   "get its endpoint in order to push back start of "
                   "PatternEntryUseScope"};
 
-  return {nullptr, "Unused"};
+  // null pointer here blows up request printing
+  return {getParent().get(), "Unused"};
 }
 
 AnnotatedInsertionPoint
@@ -1316,7 +1351,8 @@
 AnnotatedInsertionPoint
 BraceStmtScope::expandAScopeThatCreatesANewInsertionPoint(
     ScopeCreator &scopeCreator) {
-  // TODO: remove the sort after performing rdar://53254395
+  // TODO: remove the sort after fixing parser to create brace statement
+  // elements in source order
   auto *insertionPoint =
       scopeCreator.addSiblingsToScopeTree(this, this, stmt->getElements());
   if (auto *s = scopeCreator.getASTContext().Stats)
@@ -1342,11 +1378,6 @@
 
 #pragma mark expandAScopeThatDoesNotCreateANewInsertionPoint
 
-void ASTSourceFileScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
-    ScopeCreator &scopeCreator) {
-  ASTScope_unreachable("expanded by addNewDeclsToScopeTree()");
-}
-
 // Create child scopes for every declaration in a body.
 
 void AbstractFunctionDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
@@ -1376,7 +1407,6 @@
     leaf = scopeCreator.addNestedGenericParamScopesToTree(
         decl, decl->getGenericParams(), leaf);
     if (isLocalizable(decl) && getParmsSourceLocOfAFD(decl).isValid()) {
-      // See rdar://54188611
       // swift::createDesignatedInitOverride just clones the parameters, so they
       // end up with a bogus SourceRange, maybe *before* the start of the
       // function.
@@ -1471,8 +1501,6 @@
   //    let v: C { for b : Int -> S((array: P { }
   // the body is implicit and it would overlap the source range of the expr
   // above.
-  //
-  // TODO: refer to rdar://53921962
   if (!stmt->getBody()->isImplicit()) {
     if (isLocalizable(stmt->getBody()))
       scopeCreator.constructExpandAndInsertUncheckable<ForEachPatternScope>(
@@ -1577,7 +1605,6 @@
   
   // Prevent circular request bugs caused by illegal input and
   // doing lookups that getExtendedNominal in the midst of getExtendedNominal.
-  // rdar://53972776
   if (scope->shouldHaveABody() && !scope->doesDeclHaveABody())
     return ip;
 
@@ -1803,27 +1830,6 @@
     ++s->getFrontendCounters().NumIterableTypeBodyASTScopeExpansions;
 }
 
-#pragma mark - reexpandIfObsolete
-
-bool ASTScopeImpl::reexpandIfObsolete(ScopeCreator &scopeCreator) {
-  if (isCurrent() &&
-      !scopeCreator.getASTContext().LangOpts.StressASTScopeLookup) {
-    ASTScopeAssert(getWasExpanded(), "Cannot be current if unexpanded.");
-    return false;
-  }
-  reexpand(scopeCreator);
-  return true;
-}
-
-void ASTScopeImpl::reexpand(ScopeCreator &scopeCreator) {
-  auto astAncestorScopes = rescueASTAncestorScopesForReuseFromMeOrDescendants();
-  disownDescendants(scopeCreator);
-  // If the expansion recurses back into the tree for lookup, the ASTAncestor
-  // scopes will have already been rescued and won't be found!
-  expandAndBeCurrent(scopeCreator);
-  replaceASTAncestorScopes(astAncestorScopes);
-}
-
 #pragma mark getScopeCreator
 ScopeCreator &ASTScopeImpl::getScopeCreator() {
   return getParent().get()->getScopeCreator();
@@ -1901,6 +1907,11 @@
   return s->getParent().get();
 }
 
+bool ASTScopeImpl::isExpansionNeeded(const ScopeCreator &scopeCreator) const {
+  return !isCurrent() ||
+         scopeCreator.getASTContext().LangOpts.StressASTScopeLookup;
+}
+
 bool ASTScopeImpl::isCurrent() const {
   return getWasExpanded() && isCurrentIfWasExpanded();
 }
@@ -1908,6 +1919,13 @@
 void ASTScopeImpl::beCurrent() {}
 bool ASTScopeImpl::isCurrentIfWasExpanded() const { return true; }
 
+void ASTSourceFileScope::beCurrent() {
+  numberOfDeclsAlreadySeen = SF->Decls.size();
+}
+bool ASTSourceFileScope::isCurrentIfWasExpanded() const {
+  return SF->Decls.size() == numberOfDeclsAlreadySeen;
+}
+
 void IterableTypeScope::beCurrent() { portion->beCurrent(this); }
 bool IterableTypeScope::isCurrentIfWasExpanded() const {
   return portion->isCurrentIfWasExpanded(this);
@@ -2141,3 +2159,22 @@
 bool ASTSourceFileScope::crossCheckWithAST() {
   return scopeCreator->containsAllDeclContextsFromAST();
 }
+
+void ast_scope::simple_display(llvm::raw_ostream &out,
+                               const ScopeCreator *scopeCreator) {
+  scopeCreator->print(out);
+}
+
+//----------------------------------------------------------------------------//
+// ExpandASTScopeRequest computation.
+//----------------------------------------------------------------------------//
+
+bool ExpandASTScopeRequest::isCached() const {
+  ASTScopeImpl *scope = std::get<0>(getStorage());
+  ScopeCreator *scopeCreator = std::get<1>(getStorage());
+  return !scope->isExpansionNeeded(*scopeCreator);
+}
+
+Optional<ASTScopeImpl *> ExpandASTScopeRequest::getCachedResult() const {
+  return std::get<0>(getStorage());
+}
diff --git a/lib/AST/ASTScopeLookup.cpp b/lib/AST/ASTScopeLookup.cpp
index 115542b..6a0ed26 100644
--- a/lib/AST/ASTScopeLookup.cpp
+++ b/lib/AST/ASTScopeLookup.cpp
@@ -40,7 +40,6 @@
     SourceFile *sourceFile, const DeclName name, const SourceLoc loc,
     const DeclContext *const startingContext, DeclConsumer consumer) {
   SmallVector<const ASTScopeImpl *, 0> history;
-
   const auto *start =
       findStartingScopeForLookup(sourceFile, name, loc, startingContext);
   if (start)
@@ -59,7 +58,6 @@
 
   auto *const fileScope = sourceFile->getScope().impl;
   // Parser may have added decls to source file, since previous lookup
-  fileScope->addNewDeclsToScopeTree();
   if (name.isOperator())
     return fileScope; // operators always at file scope
 
@@ -116,7 +114,7 @@
 const ASTScopeImpl *ASTScopeImpl::findInnermostEnclosingScopeImpl(
     SourceLoc loc, NullablePtr<raw_ostream> os, SourceManager &sourceMgr,
     ScopeCreator &scopeCreator) {
-  reexpandIfObsolete(scopeCreator);
+  expandAndBeCurrentDetectingRecursion(scopeCreator);
   auto child = findChildContaining(loc, sourceMgr);
   if (!child)
     return this;
diff --git a/lib/AST/ASTScopePrinting.cpp b/lib/AST/ASTScopePrinting.cpp
index 670b7de..b9c6e05 100644
--- a/lib/AST/ASTScopePrinting.cpp
+++ b/lib/AST/ASTScopePrinting.cpp
@@ -201,3 +201,12 @@
 bool IterableTypeScope::doesDeclHaveABody() const {
   return getBraces().Start != getBraces().End;
 }
+
+void ast_scope::simple_display(llvm::raw_ostream &out,
+                               const ASTScopeImpl *scope) {
+  // Cannot call scope->print(out) because printing an ASTFunctionBodyScope
+  // gets the source range which can cause a request to parse it.
+  // That in turn causes the request dependency printing code to blow up
+  // as the AnyRequest ends up with a null.
+  out << scope->getClassName() << "\n";
+}
diff --git a/lib/AST/ASTScopeSourceRange.cpp b/lib/AST/ASTScopeSourceRange.cpp
index 3742a4b..fff62ce 100644
--- a/lib/AST/ASTScopeSourceRange.cpp
+++ b/lib/AST/ASTScopeSourceRange.cpp
@@ -239,8 +239,8 @@
 
 SourceRange PatternEntryDeclScope::getSourceRangeOfThisASTNode(
     const bool omitAssertions) const {
-  // TODO: Once rdar://53627317 is accomplished, the following may be able to be
-  // simplified.
+  // TODO: Once the creation of two PatternBindingDecls at same location is
+  // eliminated, the following may be able to be simplified.
   if (!getChildren().empty()) { // why needed???
     bool hasOne = false;
     getPattern()->forEachVariable([&](VarDecl *) { hasOne = true; });
@@ -254,8 +254,8 @@
 
 SourceRange PatternEntryInitializerScope::getSourceRangeOfThisASTNode(
     const bool omitAssertions) const {
-  // See rdar://53921703
-  // Note: grep for "When the initializer is removed we don't actually clear the
+  // TODO: Don't remove the initializer in the rest of the compiler:
+  // Search for "When the initializer is removed we don't actually clear the
   // pointer" because we do!
   return initAsWrittenWhenCreated->getSourceRange();
 }
@@ -317,12 +317,14 @@
 
 SourceRange
 ExtensionScope::moveStartPastExtendedNominal(const SourceRange sr) const {
-  const auto start = getLocAfterExtendedNominal(decl);
+  const auto afterExtendedNominal = getLocAfterExtendedNominal(decl);
   // Illegal code can have an endLoc that is before the end of the
-  // ExtendedNominal, so push the end back, too, in that case.
-  const auto end =
-      getSourceManager().isBeforeInBuffer(sr.End, start) ? start : sr.End;
-  return SourceRange(start, end);
+  // ExtendedNominal
+  if (getSourceManager().isBeforeInBuffer(sr.End, afterExtendedNominal)) {
+    // Must not have the source range returned include the extended nominal
+    return SourceRange(sr.Start, sr.Start);
+  }
+  return SourceRange(afterExtendedNominal, sr.End);
 }
 
 SourceRange
@@ -763,3 +765,9 @@
   return Lexer::getCharSourceRangeFromSourceRange(SM, etr->getSourceRange())
       .getEnd();
 }
+
+SourceLoc ast_scope::extractNearestSourceLoc(
+    std::tuple<ASTScopeImpl *, ScopeCreator *> scopeAndCreator) {
+  const ASTScopeImpl *scope = std::get<0>(scopeAndCreator);
+  return scope->getSourceRangeOfThisASTNode().Start;
+}
diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp
index ebd2d70..ea1af7d 100644
--- a/lib/AST/ASTWalker.cpp
+++ b/lib/AST/ASTWalker.cpp
@@ -1187,9 +1187,13 @@
 
       // Don't walk into the type if the decl is implicit, or if the type is
       // implicit.
-      if (!P->isImplicit() && !P->isTypeLocImplicit() &&
-          doIt(P->getTypeLoc()))
-        return true;
+      if (!P->isImplicit()) {
+        if (auto *repr = P->getTypeRepr()) {
+          if (doIt(repr)) {
+            return true;
+          }
+        }
+      }
 
       if (auto *E = P->getDefaultValue()) {
         auto res = doIt(E);
diff --git a/lib/AST/AutoDiff.cpp b/lib/AST/AutoDiff.cpp
index 4ab264e..354379a 100644
--- a/lib/AST/AutoDiff.cpp
+++ b/lib/AST/AutoDiff.cpp
@@ -151,7 +151,7 @@
     paramLoweredSizes.push_back(paramLoweredSize);
     totalLoweredSize += paramLoweredSize;
   };
-  for (auto *curryLevel : reversed(curryLevels))
+  for (auto *curryLevel : llvm::reverse(curryLevels))
     for (auto &param : curryLevel->getParams())
       addLoweredParamInfo(param.getPlainType());
 
@@ -183,7 +183,7 @@
 
   SmallVector<unsigned, 2> curryLevelParameterIndexOffsets(curryLevels.size());
   unsigned currentOffset = 0;
-  for (unsigned curryLevelIndex : reversed(indices(curryLevels))) {
+  for (unsigned curryLevelIndex : llvm::reverse(indices(curryLevels))) {
     curryLevelParameterIndexOffsets[curryLevelIndex] = currentOffset;
     currentOffset += curryLevels[curryLevelIndex]->getNumParams();
   }
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 06d0669..10ee66e 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -159,9 +159,9 @@
 
   SmallVector<ParamDecl*, 4> params;
   for (Type argType : argTypes) {
-    auto PD = new (Context)
-        ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                  Identifier(), SourceLoc(), Identifier(), DC);
+    auto PD = new (Context) ParamDecl(SourceLoc(), SourceLoc(),
+                                      Identifier(), SourceLoc(), Identifier(), DC);
+    PD->setSpecifier(ParamSpecifier::Default);
     PD->setInterfaceType(argType);
     PD->setImplicit();
     params.push_back(PD);
@@ -205,10 +205,10 @@
     auto specifier =
       ParamDecl::getParameterSpecifierForValueOwnership(
         ArgParamTypes[i].getParameterFlags().getValueOwnership());
-    auto PD = new (Context) ParamDecl(specifier,
-                                      SourceLoc(), SourceLoc(),
+    auto PD = new (Context) ParamDecl(SourceLoc(), SourceLoc(),
                                       Identifier(), SourceLoc(),
                                       Identifier(), DC);
+    PD->setSpecifier(specifier);
     PD->setInterfaceType(paramIfaceType);
     PD->setImplicit();
     params.push_back(PD);
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 93ce939..777bdb8 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -31,6 +31,7 @@
   Attr.cpp
   # SWIFT_ENABLE_TENSORFLOW
   AutoDiff.cpp
+  IndexSubset.cpp
   Availability.cpp
   AvailabilitySpec.cpp
   Builtins.cpp
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 00113a4..c2ff440 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1191,7 +1191,7 @@
   });
 
   GenericParamList *toParams = nullptr;
-  for (auto *gpList : reversed(allGenericParams)) {
+  for (auto *gpList : llvm::reverse(allGenericParams)) {
     gpList->setOuterParameters(toParams);
     toParams = gpList;
   }
@@ -1362,14 +1362,15 @@
     auto DC = singleVar->getDeclContext();
     if (DC->isTypeContext()) {
       auto specifier = (DC->getDeclaredInterfaceType()->hasReferenceSemantics()
-                        ? ParamDecl::Specifier::Default
-                        : ParamDecl::Specifier::InOut);
+                        ? ParamSpecifier::Default
+                        : ParamSpecifier::InOut);
 
       ASTContext &C = DC->getASTContext();
-      SelfParam = new (C) ParamDecl(specifier, SourceLoc(), SourceLoc(),
+      SelfParam = new (C) ParamDecl(SourceLoc(), SourceLoc(),
                                     Identifier(), singleVar->getLoc(),
                                     C.Id_self, this);
       SelfParam->setImplicit();
+      SelfParam->setSpecifier(specifier);
       SelfParam->setInterfaceType(DC->getSelfInterfaceType());
     }
   }
@@ -2588,7 +2589,7 @@
 }
 
 OpaqueReturnTypeRepr *ValueDecl::getOpaqueResultTypeRepr() const {
-  TypeLoc returnLoc;
+  TypeRepr *returnRepr = nullptr;
   if (auto *VD = dyn_cast<VarDecl>(this)) {
     if (auto *P = VD->getParentPattern()) {
       while (auto *PP = dyn_cast<ParenPattern>(P))
@@ -2600,19 +2601,19 @@
           assert(NP->getDecl() == VD);
           (void) NP;
 
-          returnLoc = TP->getTypeLoc();
+          returnRepr = TP->getTypeLoc().getTypeRepr();
         }
       }
     } else {
-      returnLoc = VD->getTypeLoc();
+      returnRepr = VD->getTypeRepr();
     }
   } else if (auto *FD = dyn_cast<FuncDecl>(this)) {
-    returnLoc = FD->getBodyResultTypeLoc();
+    returnRepr = FD->getBodyResultTypeLoc().getTypeRepr();
   } else if (auto *SD = dyn_cast<SubscriptDecl>(this)) {
-    returnLoc = SD->getElementTypeLoc();
+    returnRepr = SD->getElementTypeLoc().getTypeRepr();
   }
 
-  return dyn_cast_or_null<OpaqueReturnTypeRepr>(returnLoc.getTypeRepr());
+  return dyn_cast_or_null<OpaqueReturnTypeRepr>(returnRepr);
 }
 
 OpaqueTypeDecl *ValueDecl::getOpaqueResultTypeDecl() const {
@@ -3377,16 +3378,6 @@
   llvm_unreachable("bad resilience expansion");
 }
 
-void NominalTypeDecl::computeType() {
-  assert(!hasInterfaceType());
-
-  Type declaredInterfaceTy = getDeclaredInterfaceType();
-  setInterfaceType(MetatypeType::get(declaredInterfaceTy, getASTContext()));
-
-  if (declaredInterfaceTy->hasError())
-    setInvalid();
-}
-
 enum class DeclTypeKind : unsigned {
   DeclaredType,
   DeclaredInterfaceType
@@ -3638,25 +3629,6 @@
   return { TypeAliasLoc, getNameLoc() };
 }
 
-void TypeAliasDecl::computeType() {
-  assert(!hasInterfaceType());
-      
-  // Set the interface type of this declaration.
-  ASTContext &ctx = getASTContext();
-
-  auto genericSig = getGenericSignature();
-  SubstitutionMap subs;
-  if (genericSig)
-    subs = genericSig->getIdentitySubstitutionMap();
-
-  Type parent;
-  auto parentDC = getDeclContext();
-  if (parentDC->isTypeContext())
-    parent = parentDC->getSelfInterfaceType();
-  auto sugaredType = TypeAliasType::get(this, parent, subs, getUnderlyingType());
-  setInterfaceType(MetatypeType::get(sugaredType, ctx));
-}
-
 Type TypeAliasDecl::getUnderlyingType() const {
   auto &ctx = getASTContext();
   return evaluateOrDefault(ctx.evaluator,
@@ -3766,14 +3738,6 @@
   assert(Resolver && "missing resolver");
 }
 
-void AssociatedTypeDecl::computeType() {
-  assert(!hasInterfaceType());
-
-  auto &ctx = getASTContext();
-  auto interfaceTy = getDeclaredInterfaceType();
-  setInterfaceType(MetatypeType::get(interfaceTy, ctx));
-}
-
 Type AssociatedTypeDecl::getDefaultDefinitionType() const {
   return evaluateOrDefault(getASTContext().evaluator,
            DefaultDefinitionTypeRequest{const_cast<AssociatedTypeDecl *>(this)},
@@ -3958,9 +3922,6 @@
   // Propagate access control and versioned-ness.
   DD->copyFormalAccessFrom(CD, /*sourceIsParentContext*/true);
 
-  // Wire up generic environment of DD.
-  DD->setGenericSignature(CD->getGenericSignatureOfContext());
-
   // Mark DD as ObjC, as all dtors are.
   DD->setIsObjC(ctx.LangOpts.EnableObjCInterop);
   if (ctx.LangOpts.EnableObjCInterop)
@@ -4265,14 +4226,6 @@
   return ::new (buf) EnumCaseDecl(CaseLoc, Elements, DC);
 }
 
-EnumElementDecl *EnumDecl::getElement(Identifier Name) const {
-  // FIXME: Linear search is not great for large enum decls.
-  for (EnumElementDecl *Elt : getAllElements())
-    if (Elt->getName() == Name)
-      return Elt;
-  return nullptr;
-}
-
 bool EnumDecl::hasPotentiallyUnavailableCaseValue() const {
   switch (static_cast<AssociatedValueCheck>(Bits.EnumDecl.HasAssociatedValues)) {
     case AssociatedValueCheck::Unchecked:
@@ -5267,7 +5220,7 @@
 SourceRange VarDecl::getTypeSourceRangeForDiagnostics() const {
   // For a parameter, map back to its parameter to get the TypeLoc.
   if (auto *PD = dyn_cast<ParamDecl>(this)) {
-    if (auto typeRepr = PD->getTypeLoc().getTypeRepr())
+    if (auto typeRepr = PD->getTypeRepr())
       return typeRepr->getSourceRange();
   }
   
@@ -5548,15 +5501,11 @@
 void ParamDecl::setSpecifier(Specifier specifier) {
   // FIXME: Revisit this; in particular shouldn't __owned parameters be
   // ::Let also?
-  setIntroducer(specifier == ParamDecl::Specifier::Default
+  setIntroducer(specifier == ParamSpecifier::Default
                 ? VarDecl::Introducer::Let
                 : VarDecl::Introducer::Var);
   Bits.ParamDecl.Specifier = static_cast<unsigned>(specifier);
-  setImplInfo(
-    StorageImplInfo::getSimpleStored(
-      isImmutableSpecifier(specifier)
-      ? StorageIsNotMutable
-      : StorageIsMutable));
+  Bits.ParamDecl.SpecifierComputed = true;
 }
 
 bool ParamDecl::isAnonClosureParam() const {
@@ -5571,6 +5520,15 @@
   return nameStr[0] == '$';
 }
 
+ParamDecl::Specifier ParamDecl::getSpecifier() const {
+  auto &ctx = getASTContext();
+
+  auto mutableThis = const_cast<ParamDecl *>(this);
+  return evaluateOrDefault(ctx.evaluator,
+                           ParamSpecifierRequest{mutableThis},
+                           ParamDecl::Specifier::Default);
+}
+
 StaticSpellingKind AbstractStorageDecl::getCorrectStaticSpelling() const {
   if (!isStatic())
     return StaticSpellingKind::None;
@@ -5765,18 +5723,12 @@
     if (FD && !FD->isMutating() && !FD->isImplicit() && FD->isInstanceMember()&&
         !FD->getDeclContext()->getDeclaredInterfaceType()
                  ->hasReferenceSemantics()) {
-      // Do not suggest the fix-it in implicit getters
+      // Do not suggest the fix it in implicit getters
       if (auto AD = dyn_cast<AccessorDecl>(FD)) {
         if (AD->isGetter() && !AD->getAccessorKeywordLoc().isValid())
           return;
-
-        auto accessorDC = AD->getDeclContext();
-        // Do not suggest the fix-it if `Self` is a class type.
-        if (accessorDC->isTypeContext() && !accessorDC->hasValueSemantics()) {
-          return;
-        }
       }
-
+                   
       auto &d = getASTContext().Diags;
       d.diagnose(FD->getFuncLoc(), diag::change_to_mutating,
                  isa<AccessorDecl>(FD))
@@ -5807,51 +5759,38 @@
   }
 }
 
-ParamDecl::ParamDecl(Specifier specifier, SourceLoc specifierLoc,
+ParamDecl::ParamDecl(SourceLoc specifierLoc,
                      SourceLoc argumentNameLoc, Identifier argumentName,
                      SourceLoc parameterNameLoc, Identifier parameterName,
                      DeclContext *dc)
     : VarDecl(DeclKind::Param,
               /*IsStatic*/ false,
-              specifier == ParamDecl::Specifier::Default
-                  ? VarDecl::Introducer::Let
-                  : VarDecl::Introducer::Var,
+              VarDecl::Introducer::Let,
               /*IsCaptureList*/ false, parameterNameLoc, parameterName, dc,
-              StorageIsMutable_t(!isImmutableSpecifier(specifier))),
+              StorageIsNotMutable),
       ArgumentName(argumentName), ParameterNameLoc(parameterNameLoc),
       ArgumentNameLoc(argumentNameLoc), SpecifierLoc(specifierLoc) {
-
-  Bits.ParamDecl.Specifier = static_cast<unsigned>(specifier);
-  Bits.ParamDecl.IsTypeLocImplicit = false;
+  Bits.ParamDecl.SpecifierComputed = false;
   Bits.ParamDecl.defaultArgumentKind =
     static_cast<unsigned>(DefaultArgumentKind::None);
 }
 
-/// Clone constructor, allocates a new ParamDecl identical to the first.
-/// Intentionally not defined as a copy constructor to avoid accidental copies.
-ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
-  : VarDecl(DeclKind::Param, /*IsStatic*/false, PD->getIntroducer(),
-            /*IsCaptureList*/false, PD->getNameLoc(), PD->getName(),
-            PD->getDeclContext(),
-            StorageIsMutable_t(!isImmutableSpecifier(PD->getSpecifier()))),
-    ArgumentName(PD->getArgumentName()),
-    ArgumentNameLoc(PD->getArgumentNameLoc()),
-    SpecifierLoc(PD->getSpecifierLoc()),
-    DefaultValueAndFlags(nullptr, PD->DefaultValueAndFlags.getInt()) {
-  Bits.ParamDecl.Specifier = static_cast<unsigned>(PD->getSpecifier());
-  Bits.ParamDecl.IsTypeLocImplicit = PD->Bits.ParamDecl.IsTypeLocImplicit;
-  Bits.ParamDecl.defaultArgumentKind = PD->Bits.ParamDecl.defaultArgumentKind;
-  typeLoc = PD->getTypeLoc().clone(PD->getASTContext());
-  if (!withTypes && typeLoc.getTypeRepr())
-    typeLoc.setType(Type());
+ParamDecl *ParamDecl::cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD) {
+  auto *Clone = new (Ctx) ParamDecl(
+      PD->getSpecifierLoc(), PD->getArgumentNameLoc(), PD->getArgumentName(),
+      PD->getArgumentNameLoc(), PD->getParameterName(), PD->getDeclContext());
+  Clone->DefaultValueAndFlags.setPointerAndInt(
+      nullptr, PD->DefaultValueAndFlags.getInt());
+  Clone->Bits.ParamDecl.defaultArgumentKind =
+      PD->Bits.ParamDecl.defaultArgumentKind;
+  if (auto *repr = PD->getTypeRepr())
+    Clone->setTypeRepr(repr->clone(Ctx));
 
-  if (withTypes && PD->hasInterfaceType())
-    setInterfaceType(PD->getInterfaceType());
-
-  setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
+  Clone->setSpecifier(PD->getSpecifier());
+  Clone->setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
+  return Clone;
 }
 
-
 /// Retrieve the type of 'self' for the given context.
 Type DeclContext::getSelfTypeInContext() const {
   assert(isTypeContext());
@@ -5890,9 +5829,9 @@
     startLoc = APINameLoc;
   else if (nameLoc.isValid())
     startLoc = nameLoc;
-  else {
-    startLoc = getTypeLoc().getSourceRange().Start;
-  }
+  else if (auto *repr = getTypeRepr())
+    startLoc = repr->getStartLoc();
+
   if (startLoc.isInvalid())
     return SourceRange();
 
@@ -5906,9 +5845,9 @@
   }
   
   // If the typeloc has a valid location, use it to end the range.
-  if (auto typeRepr = getTypeLoc().getTypeRepr()) {
+  if (auto typeRepr = getTypeRepr()) {
     auto endLoc = typeRepr->getEndLoc();
-    if (endLoc.isValid() && !isTypeLocImplicit())
+    if (endLoc.isValid())
       return SourceRange(startLoc, endLoc);
   }
 
@@ -6276,30 +6215,11 @@
 }
 
 Type SubscriptDecl::getElementInterfaceType() const {
-  auto elementTy = getInterfaceType();
-  if (elementTy->is<ErrorType>())
-    return elementTy;
-  return elementTy->castTo<AnyFunctionType>()->getResult();
-}
-
-void SubscriptDecl::computeType() {
-  auto elementTy = getElementTypeLoc().getType();
-
-  SmallVector<AnyFunctionType::Param, 2> argTy;
-  getIndices()->getParams(argTy);
-
-  Type funcTy;
-  if (auto sig = getGenericSignature())
-    funcTy = GenericFunctionType::get(sig, argTy, elementTy);
-  else
-    funcTy = FunctionType::get(argTy, elementTy);
-
-  // Record the interface type.
-  setInterfaceType(funcTy);
-      
-  // Make sure that there are no unresolved dependent types in the
-  // generic signature.
-  assert(!funcTy->findUnresolvedDependentMemberType());
+  auto &ctx = getASTContext();
+  auto mutableThis = const_cast<SubscriptDecl *>(this);
+  return evaluateOrDefault(ctx.evaluator,
+                           ResultTypeRequest{mutableThis},
+                           ErrorType::get(ctx));
 }
 
 ObjCSubscriptKind SubscriptDecl::getObjCSubscriptKind() const {
@@ -6433,7 +6353,9 @@
   }
 
   auto mutableThis = const_cast<AbstractFunctionDecl *>(this);
-  return evaluateOrDefault(ctx.evaluator, ParseAbstractFunctionBodyRequest{mutableThis}, nullptr);
+  return evaluateOrDefault(ctx.evaluator,
+                           ParseAbstractFunctionBodyRequest{mutableThis},
+                           nullptr);
 }
 
 SourceRange AbstractFunctionDecl::getBodySourceRange() const {
@@ -6648,41 +6570,13 @@
 
   // Create and save our 'self' parameter.
   auto &ctx = getASTContext();
-  *selfDecl = new (ctx) ParamDecl(ParamDecl::Specifier::Default,
-                                  SourceLoc(), SourceLoc(), Identifier(),
+  *selfDecl = new (ctx) ParamDecl(SourceLoc(), SourceLoc(), Identifier(),
                                   getLoc(), ctx.Id_self, this);
   (*selfDecl)->setImplicit();
 
-  // If we already have an interface type, compute the 'self' parameter type.
-  // Otherwise, we'll do it later.
-  if (hasInterfaceType())
-    computeSelfDeclType();
-
   return *selfDecl;
 }
 
-void AbstractFunctionDecl::computeSelfDeclType() {
-  assert(hasImplicitSelfDecl());
-  assert(hasInterfaceType());
-
-  auto *selfDecl = getImplicitSelfDecl(/*createIfNeeded=*/false);
-
-  // If we haven't created a 'self' parameter yet, do nothing, we'll compute
-  // the type later.
-  if (selfDecl == nullptr)
-    return;
-
-  auto selfParam = computeSelfParam(this,
-                                    /*isInitializingCtor*/true,
-                                    /*wantDynamicSelf*/true);
-  selfDecl->setInterfaceType(selfParam.getPlainType());
-
-  auto specifier = selfParam.getParameterFlags().isInOut()
-                       ? ParamDecl::Specifier::InOut
-                       : ParamDecl::Specifier::Default;
-  selfDecl->setSpecifier(specifier);
-}
-
 void AbstractFunctionDecl::setParameters(ParameterList *BodyParams) {
 #ifndef NDEBUG
   auto Name = getFullName();
@@ -6742,34 +6636,18 @@
 }
 
 void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
-  auto &ctx = getASTContext();
   auto sig = getGenericSignature();
   bool hasSelf = hasImplicitSelfDecl();
 
   // Result
   Type resultTy;
   if (auto fn = dyn_cast<FuncDecl>(this)) {
-    resultTy = fn->getBodyResultTypeLoc().getType();
-    if (!resultTy) {
-      resultTy = TupleType::getEmpty(ctx);
-    }
-
+    resultTy = fn->getResultInterfaceType();
   } else if (auto ctor = dyn_cast<ConstructorDecl>(this)) {
-    auto *dc = ctor->getDeclContext();
-
-    if (hasSelf) {
-      if (!dc->isTypeContext())
-        resultTy = ErrorType::get(ctx);
-      else
-        resultTy = dc->getSelfInterfaceType();
-    }
-
-    // Adjust result type for failability.
-    if (ctor->isFailable())
-      resultTy = OptionalType::get(resultTy);
+    resultTy = ctor->getResultInterfaceType();
   } else {
     assert(isa<DestructorDecl>(this));
-    resultTy = TupleType::getEmpty(ctx);
+    resultTy = TupleType::getEmpty(getASTContext());
   }
 
   // (Args...) -> Result
@@ -6804,14 +6682,6 @@
 
   // Record the interface type.
   setInterfaceType(funcTy);
-
-  // Compute the type of the 'self' parameter if we're created one already.
-  if (hasSelf)
-    computeSelfDeclType();
-      
-  // Make sure that there are no unresolved dependent types in the
-  // generic signature.
-  assert(!funcTy->findUnresolvedDependentMemberType());
 }
 
 bool AbstractFunctionDecl::hasInlinableBodyText() const {
@@ -7027,14 +6897,11 @@
 }
 
 Type FuncDecl::getResultInterfaceType() const {
-  Type resultTy = getInterfaceType();
-  if (resultTy.isNull() || resultTy->is<ErrorType>())
-    return resultTy;
-
-  if (hasImplicitSelfDecl())
-    resultTy = resultTy->castTo<AnyFunctionType>()->getResult();
-
-  return resultTy->castTo<AnyFunctionType>()->getResult();
+  auto &ctx = getASTContext();
+  auto mutableThis = const_cast<FuncDecl *>(this);
+  return evaluateOrDefault(ctx.evaluator,
+                           ResultTypeRequest{mutableThis},
+                           ErrorType::get(ctx));
 }
 
 bool FuncDecl::isUnaryOperator() const {
@@ -7157,6 +7024,18 @@
   return StartLoc;
 }
 
+EnumElementDecl::EnumElementDecl(SourceLoc IdentifierLoc, DeclName Name,
+                                 ParameterList *Params,
+                                 SourceLoc EqualsLoc,
+                                 LiteralExpr *RawValueExpr,
+                                 DeclContext *DC)
+  : DeclContext(DeclContextKind::EnumElementDecl, DC),
+    ValueDecl(DeclKind::EnumElement, DC, Name, IdentifierLoc),
+    EqualsLoc(EqualsLoc),
+    RawValueExpr(RawValueExpr) {
+  setParameterList(Params);
+}
+
 SourceRange EnumElementDecl::getSourceRange() const {
   if (RawValueExpr && !RawValueExpr->isImplicit())
     return {getStartLoc(), RawValueExpr->getEndLoc()};
@@ -7165,34 +7044,6 @@
   return {getStartLoc(), getNameLoc()};
 }
 
-void EnumElementDecl::computeType() {
-  assert(!hasInterfaceType());
-
-  auto &ctx = getASTContext();
-  auto *ED = getParentEnum();
-
-  // The type of the enum element is either (Self.Type) -> Self
-  // or (Self.Type) -> (Args...) -> Self.
-  auto resultTy = ED->getDeclaredInterfaceType();
-
-  AnyFunctionType::Param selfTy(MetatypeType::get(resultTy, ctx));
-
-  if (auto *PL = getParameterList()) {
-    SmallVector<AnyFunctionType::Param, 4> argTy;
-    PL->getParams(argTy);
-
-    resultTy = FunctionType::get(argTy, resultTy);
-  }
-
-  if (auto genericSig = ED->getGenericSignature())
-    resultTy = GenericFunctionType::get(genericSig, {selfTy}, resultTy);
-  else
-    resultTy = FunctionType::get({selfTy}, resultTy);
-
-  // Record the interface type.
-  setInterfaceType(resultTy);
-}
-
 Type EnumElementDecl::getArgumentInterfaceType() const {
   if (!hasAssociatedValues())
     return nullptr;
@@ -7214,6 +7065,13 @@
   return TupleType::get(elements, ctx);
 }
 
+void EnumElementDecl::setParameterList(ParameterList *params) {
+  Params = params;
+
+  if (params)
+    params->setDeclContextOfParamDecls(this);
+}
+
 EnumCaseDecl *EnumElementDecl::getParentCase() const {
   for (EnumCaseDecl *EC : getParentEnum()->getAllCases()) {
     ArrayRef<EnumElementDecl *> CaseElements = EC->getElements();
@@ -7268,10 +7126,19 @@
 }
 
 Type ConstructorDecl::getResultInterfaceType() const {
-  Type ArgTy = getInterfaceType();
-  ArgTy = ArgTy->castTo<AnyFunctionType>()->getResult();
-  ArgTy = ArgTy->castTo<AnyFunctionType>()->getResult();
-  return ArgTy;
+  Type resultTy;
+
+  auto *dc = getDeclContext();
+  if (!dc->isTypeContext())
+    resultTy = ErrorType::get(getASTContext());
+  else
+    resultTy = dc->getSelfInterfaceType();
+
+  // Adjust result type for failability.
+  if (isFailable())
+    return OptionalType::get(resultTy);
+
+  return resultTy;
 }
 
 Type ConstructorDecl::getInitializerInterfaceType() {
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 02ea49c..f8860e5 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -1035,14 +1035,6 @@
   llvm_unreachable("Unhandled DeclContext ASTHierarchy");
 }
 
-bool DeclContext::hasValueSemantics() const {
-  if (auto contextTy = getSelfTypeInContext()) {
-    return !contextTy->hasReferenceSemantics();
-  }
-
-  return false;
-}
-
 SourceLoc swift::extractNearestSourceLoc(const DeclContext *dc) {
   switch (dc->getContextKind()) {
   case DeclContextKind::AbstractFunctionDecl:
diff --git a/lib/AST/Evaluator.cpp b/lib/AST/Evaluator.cpp
index 959a46c..c73ed3e 100644
--- a/lib/AST/Evaluator.cpp
+++ b/lib/AST/Evaluator.cpp
@@ -99,7 +99,7 @@
 
 void Evaluator::diagnoseCycle(const AnyRequest &request) {
   request.diagnoseCycle(diags);
-  for (const auto &step : reversed(activeRequests)) {
+  for (const auto &step : llvm::reverse(activeRequests)) {
     if (step == request) return;
 
     step.noteCycleStep(diags);
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index aadf403..acddaff 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1322,7 +1322,7 @@
       return { SourceLoc(), SourceLoc() };
     } else {
       // Scan backwards for a valid source loc.
-      for (Expr *expr : reversed(getElements())) {
+      for (Expr *expr : llvm::reverse(getElements())) {
         end = expr->getEndLoc();
         if (end.isValid()) {
           break;
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index d6bcaaa..3ecd0c8 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -5133,9 +5133,8 @@
                                           ModuleDecl &module,
                                           ParameterList *params) {
   for (auto P : *params) {
-    inferRequirements(module, P->getTypeLoc().getType(),
-                      FloatingRequirementSource::forInferred(
-                          P->getTypeLoc().getTypeRepr()));
+    inferRequirements(module, P->getInterfaceType(),
+                      FloatingRequirementSource::forInferred(P->getTypeRepr()));
   }
 }
 
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index a6c6358..15c3bc9 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -103,7 +103,6 @@
                                           const_cast<BuiltinUnit*>(&M));
       TAD->setUnderlyingType(Ty);
       TAD->setAccess(AccessLevel::Public);
-      TAD->computeType();
       Entry = TAD;
     }
   }
@@ -686,6 +685,32 @@
   return nullptr;
 }
 
+Optional<BasicDeclLocs>
+SourceFile::getBasicLocsForDecl(const Decl *D) const {
+  auto *FileCtx = D->getDeclContext()->getModuleScopeContext();
+  assert(FileCtx == this && "D doesn't belong to this source file");
+  if (FileCtx != this) {
+    // D doesn't belong to this file. This shouldn't happen in practice.
+    return None;
+  }
+  if (D->getLoc().isInvalid())
+    return None;
+  SourceManager &SM = getASTContext().SourceMgr;
+  BasicDeclLocs Result;
+  Result.SourceFilePath = SM.getDisplayNameForLoc(D->getLoc());
+  auto setLineColumn = [&SM](LineColumn &Home, SourceLoc Loc) {
+    if (Loc.isValid()) {
+      std::tie(Home.Line, Home.Column) = SM.getLineAndColumn(Loc);
+    }
+  };
+#define SET(X) setLineColumn(Result.X, D->get##X());
+  SET(Loc)
+  SET(StartLoc)
+  SET(EndLoc)
+#undef SET
+  return Result;
+}
+
 void ModuleDecl::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
   // FIXME: Should this do extra access control filtering?
   FORWARD(getDisplayDecls, (Results));
@@ -1205,7 +1230,7 @@
 ModuleDecl::ReverseFullNameIterator::printForward(raw_ostream &out,
                                                   StringRef delim) const {
   SmallVector<StringRef, 8> elements(*this, {});
-  swift::interleave(swift::reversed(elements),
+  swift::interleave(llvm::reverse(elements),
                     [&out](StringRef next) { out << next; },
                     [&out, delim] { out << delim; });
 }
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index a66c80f..d49f281 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -648,6 +648,13 @@
   nameTracker->addTopLevelName(name.getBaseName(), isCascading);
 }
 
+namespace {
+  /// Whether we're looking up outer results or not.
+  enum class LookupOuterResults {
+    Excluded,
+    Included
+  };
+}
 
 /// Retrieve the set of type declarations that are directly referenced from
 /// the given parsed type representation.
@@ -1878,11 +1885,15 @@
 /// Perform unqualified name lookup for types at the given location.
 static DirectlyReferencedTypeDecls
 directReferencesForUnqualifiedTypeLookup(DeclName name,
-                                         SourceLoc loc, DeclContext *dc) {
+                                         SourceLoc loc, DeclContext *dc,
+                                         LookupOuterResults lookupOuter) {
   DirectlyReferencedTypeDecls results;
   UnqualifiedLookup::Options options =
       UnqualifiedLookup::Flags::TypeLookup |
       UnqualifiedLookup::Flags::AllowProtocolMembers;
+  if (lookupOuter == LookupOuterResults::Included)
+    options |= UnqualifiedLookup::Flags::IncludeOuterResults;
+
   UnqualifiedLookup lookup(name, dc, loc, options);
   for (const auto &result : lookup.Results) {
     if (auto typeDecl = dyn_cast<TypeDecl>(result.getValueDecl()))
@@ -1957,7 +1968,8 @@
       current =
         directReferencesForUnqualifiedTypeLookup(component->getIdentifier(),
                                                  component->getIdLoc(),
-                                                 dc);
+                                                 dc,
+                                                 LookupOuterResults::Excluded);
 
       // If we didn't find anything, fail now.
       if (current.empty())
@@ -2195,6 +2207,19 @@
   return nominalTypes.empty() ? nullptr : nominalTypes[0];
 }
 
+/// Whether there are only associated types in the set of declarations.
+static bool declsAreAssociatedTypes(ArrayRef<TypeDecl *> decls) {
+  if (decls.empty())
+    return false;
+
+  for (auto decl : decls) {
+    if (!isa<AssociatedTypeDecl>(decl))
+      return false;
+  }
+
+  return true;
+}
+
 llvm::Expected<NominalTypeDecl *>
 CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
                                    CustomAttr *attr, DeclContext *dc) const {
@@ -2217,6 +2242,48 @@
   if (nominals.size() == 1 && !isa<ProtocolDecl>(nominals.front()))
     return nominals.front();
 
+  // If we found declarations that are associated types, look outside of
+  // the current context to see if we can recover.
+  if (declsAreAssociatedTypes(decls)) {
+    if (auto typeRepr = typeLoc.getTypeRepr()) {
+      if (auto identTypeRepr = dyn_cast<SimpleIdentTypeRepr>(typeRepr)) {
+        auto assocType = cast<AssociatedTypeDecl>(decls.front());
+
+        modulesFound.clear();
+        anyObject = false;
+        decls = directReferencesForUnqualifiedTypeLookup(
+            identTypeRepr->getIdentifier(), identTypeRepr->getIdLoc(), dc,
+            LookupOuterResults::Included);
+        nominals = resolveTypeDeclsToNominal(evaluator, ctx, decls,
+                                             modulesFound, anyObject);
+        if (nominals.size() == 1 && !isa<ProtocolDecl>(nominals.front())) {
+          auto nominal = nominals.front();
+          if (nominal->getDeclContext()->isModuleScopeContext()) {
+            // Complain, producing module qualification in a Fix-It.
+            auto moduleName = nominal->getParentModule()->getName();
+            ctx.Diags.diagnose(typeRepr->getLoc(),
+                               diag::warn_property_wrapper_module_scope,
+                               identTypeRepr->getIdentifier(),
+                               moduleName)
+              .fixItInsert(typeRepr->getLoc(),
+                           moduleName.str().str() + ".");
+            ctx.Diags.diagnose(assocType, diag::kind_declname_declared_here,
+                               assocType->getDescriptiveKind(),
+                               assocType->getFullName());
+
+            ComponentIdentTypeRepr *components[2] = {
+              new (ctx) SimpleIdentTypeRepr(typeRepr->getLoc(), moduleName),
+              identTypeRepr
+            };
+
+            typeLoc = TypeLoc(IdentTypeRepr::create(ctx, components));
+            return nominal;
+          }
+        }
+      }
+    }
+  }
+
   return nullptr;
 }
 
diff --git a/lib/AST/Parameter.cpp b/lib/AST/Parameter.cpp
index db6cd08..f645d0c 100644
--- a/lib/AST/Parameter.cpp
+++ b/lib/AST/Parameter.cpp
@@ -59,12 +59,11 @@
   SmallVector<ParamDecl*, 8> params(begin(), end());
 
   // Remap the ParamDecls inside of the ParameterList.
-  bool withTypes = !options.contains(ParameterList::WithoutTypes);
   for (auto &decl : params) {
     bool hadDefaultArgument =
         decl->getDefaultArgumentKind() == DefaultArgumentKind::Normal;
 
-    decl = new (C) ParamDecl(decl, withTypes);
+    decl = ParamDecl::cloneWithoutType(C, decl);
     if (options & Implicit)
       decl->setImplicit();
 
diff --git a/lib/AST/SwiftNameTranslation.cpp b/lib/AST/SwiftNameTranslation.cpp
index 2a1d648..dc4db68 100644
--- a/lib/AST/SwiftNameTranslation.cpp
+++ b/lib/AST/SwiftNameTranslation.cpp
@@ -72,7 +72,7 @@
   }
 
   std::string buffer = ED->getParentModule()->getNameStr();
-  for (auto D : reversed(outerTypes)) {
+  for (auto D : llvm::reverse(outerTypes)) {
     buffer += ".";
     buffer += D->getNameStr();
   }
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 90d4f7c..875b4f5 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -4680,7 +4680,7 @@
   // Wrap the derivative function type in additional curry levels.
   auto curryLevelsWithoutLast =
       ArrayRef<AnyFunctionType *>(curryLevels).drop_back(1);
-  for (auto pair : enumerate(reversed(curryLevelsWithoutLast))) {
+  for (auto pair : enumerate(llvm::reverse(curryLevelsWithoutLast))) {
     unsigned i = pair.index();
     AnyFunctionType *curryLevel = pair.value();
     derivativeFunction = makeFunctionType(
@@ -4719,7 +4719,7 @@
   // Wrap the derivative function type in additional curry levels.
   auto curryLevelsWithoutLast =
       ArrayRef<AnyFunctionType *>(curryLevels).drop_back(1);
-  for (auto pair : enumerate(reversed(curryLevelsWithoutLast))) {
+  for (auto pair : enumerate(llvm::reverse(curryLevelsWithoutLast))) {
     unsigned i = pair.index();
     AnyFunctionType *curryLevel = pair.value();
     originalType = makeFunctionType(
diff --git a/lib/AST/TypeCheckRequests.cpp b/lib/AST/TypeCheckRequests.cpp
index 65b4582..7219a17 100644
--- a/lib/AST/TypeCheckRequests.cpp
+++ b/lib/AST/TypeCheckRequests.cpp
@@ -938,3 +938,40 @@
   decl->LazySemanticInfo.NeedsNewVTableEntryComputed = true;
   decl->LazySemanticInfo.NeedsNewVTableEntry = value;
 }
+
+//----------------------------------------------------------------------------//
+// ParamSpecifierRequest computation.
+//----------------------------------------------------------------------------//
+
+Optional<ParamSpecifier> ParamSpecifierRequest::getCachedResult() const {
+  auto *decl = std::get<0>(getStorage());
+  return decl->getCachedSpecifier();
+}
+
+void ParamSpecifierRequest::cacheResult(ParamSpecifier specifier) const {
+  auto *decl = std::get<0>(getStorage());
+  decl->setSpecifier(specifier);
+}
+
+//----------------------------------------------------------------------------//
+// ResultTypeRequest computation.
+//----------------------------------------------------------------------------//
+
+TypeLoc &ResultTypeRequest::getResultTypeLoc() const {
+  auto *decl = std::get<0>(getStorage());
+  if (auto *funcDecl = dyn_cast<FuncDecl>(decl))
+    return funcDecl->getBodyResultTypeLoc();
+  auto *subscriptDecl = cast<SubscriptDecl>(decl);
+  return subscriptDecl->getElementTypeLoc();
+}
+
+Optional<Type> ResultTypeRequest::getCachedResult() const {
+  if (auto type = getResultTypeLoc().getType())
+    return type;
+
+  return None;
+}
+
+void ResultTypeRequest::cacheResult(Type type) const {
+  getResultTypeLoc().setType(type);
+}
\ No newline at end of file
diff --git a/lib/AST/USRGeneration.cpp b/lib/AST/USRGeneration.cpp
index 23d722f..c9baacc 100644
--- a/lib/AST/USRGeneration.cpp
+++ b/lib/AST/USRGeneration.cpp
@@ -258,7 +258,7 @@
 llvm::Expected<std::string>
 swift::MangleLocalTypeDeclRequest::evaluate(Evaluator &evaluator,
                                             const TypeDecl *D) const {
-  if (!D->hasInterfaceType())
+  if (!D->getInterfaceType())
     return std::string();
 
   if (isa<ModuleDecl>(D))
@@ -279,7 +279,7 @@
   }
 }
 
-bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) {
+bool ide::printValueDeclUSR(const ValueDecl *D, raw_ostream &OS) {
   auto result = evaluateOrDefault(D->getASTContext().evaluator,
                                   USRGenerationRequest { D },
                                   std::string());
@@ -327,17 +327,33 @@
   for (auto D : ED->getMembers()) {
     if (auto VD = dyn_cast<ValueDecl>(D)) {
       OS << getUSRSpacePrefix() << "e:";
-      return printDeclUSR(VD, OS);
+      return printValueDeclUSR(VD, OS);
     }
   }
   OS << getUSRSpacePrefix() << "e:";
-  printDeclUSR(nominal, OS);
+  printValueDeclUSR(nominal, OS);
   for (auto Inherit : ED->getInherited()) {
     if (auto T = Inherit.getType()) {
       if (T->getAnyNominal())
-        return printDeclUSR(T->getAnyNominal(), OS);
+        return printValueDeclUSR(T->getAnyNominal(), OS);
     }
   }
   return true;
 }
 
+bool ide::printDeclUSR(const Decl *D, raw_ostream &OS) {
+  if (D->isImplicit())
+    return true;
+  if (auto *VD = dyn_cast<ValueDecl>(D)) {
+    if (ide::printValueDeclUSR(VD, OS)) {
+      return true;
+    }
+  } else if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
+    if (ide::printExtensionUSR(ED, OS)) {
+      return true;
+    }
+  } else {
+    return true;
+  }
+  return false;
+}
diff --git a/lib/AST/UnqualifiedLookup.cpp b/lib/AST/UnqualifiedLookup.cpp
index 4cfbcc4..17ddfd5 100644
--- a/lib/AST/UnqualifiedLookup.cpp
+++ b/lib/AST/UnqualifiedLookup.cpp
@@ -778,7 +778,8 @@
   assert(isa<TopLevelCodeDecl>(dc) ||
          isa<Initializer>(dc) ||
          isa<TypeAliasDecl>(dc) ||
-         isa<SubscriptDecl>(dc));
+         isa<SubscriptDecl>(dc) ||
+         isa<EnumElementDecl>(dc));
   finishLookingInContext(
     AddGenericParameters::Yes,
     dc,
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index 8e595c4..9a96749 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -156,7 +156,7 @@
 StringRef
 LangOptions::getPlatformConditionValue(PlatformConditionKind Kind) const {
   // Last one wins.
-  for (auto &Opt : reversed(PlatformConditionValues)) {
+  for (auto &Opt : llvm::reverse(PlatformConditionValues)) {
     if (Opt.first == Kind)
       return Opt.second;
   }
@@ -169,7 +169,7 @@
   if (Kind == PlatformConditionKind::OS && Value == "macOS")
     return checkPlatformCondition(Kind, "OSX");
 
-  for (auto &Opt : reversed(PlatformConditionValues)) {
+  for (auto &Opt : llvm::reverse(PlatformConditionValues)) {
     if (Opt.first == Kind)
       if (Opt.second == Value)
         return true;
diff --git a/lib/Basic/StringExtras.cpp b/lib/Basic/StringExtras.cpp
index d231bb0..cc8b173 100644
--- a/lib/Basic/StringExtras.cpp
+++ b/lib/Basic/StringExtras.cpp
@@ -437,10 +437,10 @@
 
   // Find the last instance of the first word in the name within
   // the words in the type name.
-  while (typeWordRevIter != typeWordRevIterEnd &&
-         !matchNameWordToTypeWord(*nameWordIter, *typeWordRevIter)) {
-    ++typeWordRevIter;
-  }
+  typeWordRevIter = std::find_if(typeWordRevIter, typeWordRevIterEnd,
+                                 [nameWordIter](StringRef word) {
+    return matchNameWordToTypeWord(*nameWordIter, word);
+  });
 
   // If we didn't find the first word in the name at all, we're
   // done.
@@ -451,6 +451,8 @@
   auto typeWordIter = typeWordRevIter.base(),
     typeWordIterEnd = typeWords.end();
   ++nameWordIter;
+
+  // FIXME: Use std::mismatch once we update to C++14.
   while (typeWordIter != typeWordIterEnd &&
          nameWordIter != nameWordIterEnd &&
          matchNameWordToTypeWord(*nameWordIter, *typeWordIter)) {
@@ -463,7 +465,7 @@
     return name;
 
   // Chop of the beginning of the name.
-  return name.substr(nameWordIter.getPosition());
+  return nameWordIter.getRestOfStr();
 }
 
 StringRef StringScratchSpace::copyString(StringRef string) {
@@ -574,14 +576,40 @@
   return false;
 }
 
-static StringRef omitNeedlessWords(StringRef name,
-                                   OmissionTypeName typeName,
-                                   NameRole role,
-                                   const InheritedNameSet *allPropertyNames,
-                                   StringScratchSpace &scratch) {
-  // If we have no name or no type name, there is nothing to do.
-  if (name.empty() || typeName.empty()) return name;
+namespace {
+/// Describes the role that a particular name has within a
+/// signature, which can affect how we omit needless words.
+enum class NameRole {
+  /// The base name of a function or method.
+  BaseName,
 
+  /// The first parameter of a function or method.
+  FirstParameter,
+
+  // Subsequent parameters in a function or method.
+  SubsequentParameter,
+
+  // The name of a property.
+  Property,
+
+  // A partial name; used internally.
+  Partial,
+};
+} // end anonymous namespace
+
+static StringRef
+omitTrailingTypeNameWithSpecialCases(StringRef name,
+                                     OmissionTypeName typeName,
+                                     NameRole role,
+                                     const InheritedNameSet *allPropertyNames);
+
+/// Returns the iterator pointing to the first word in \p name that starts the
+/// match for \p typeName (anchored at the end of \p name).
+///
+/// If there is no match, returns the end WordIterator for \p name.
+static Words::iterator matchTypeNameFromBackWithSpecialCases(
+    StringRef name, OmissionTypeName typeName,
+    const InheritedNameSet *allPropertyNames, bool canSkipTypeSuffix = true) {
   // Get the camel-case words in the name and type name.
   auto nameWords = camel_case::getWords(name);
   auto typeWords = camel_case::getWords(typeName.Name);
@@ -590,25 +618,15 @@
   // name.
   auto nameWordRevIter = nameWords.rbegin(),
     nameWordRevIterBegin = nameWordRevIter,
-    firstMatchingNameWordRevIter = nameWordRevIter,
     nameWordRevIterEnd = nameWords.rend();
   auto typeWordRevIter = typeWords.rbegin(),
     typeWordRevIterEnd = typeWords.rend();
 
-  bool anyMatches = false;
-  auto matched = [&] {
-    if (anyMatches) return;
-
-    anyMatches = true;
-    firstMatchingNameWordRevIter = nameWordRevIter;
-  };
-
   while (nameWordRevIter != nameWordRevIterEnd &&
          typeWordRevIter != typeWordRevIterEnd) {
     // If the names match, continue.
     auto nameWord = *nameWordRevIter;
     if (matchNameWordToTypeWord(nameWord, *typeWordRevIter)) {
-      matched();
       ++nameWordRevIter;
       ++typeWordRevIter;
       continue;
@@ -623,7 +641,6 @@
       ++nextTypeWordRevIter;
       if (nextTypeWordRevIter != typeWordRevIterEnd &&
           matchNameWordToTypeWord("Index", *nextTypeWordRevIter)) {
-        matched();
         ++nameWordRevIter;
         typeWordRevIter = nextTypeWordRevIter;
         ++typeWordRevIter;
@@ -635,7 +652,6 @@
     if (matchNameWordToTypeWord(nameWord, "Index") &&
         (matchNameWordToTypeWord("Int", *typeWordRevIter) ||
          matchNameWordToTypeWord("Integer", *typeWordRevIter))) {
-      matched();
       ++nameWordRevIter;
       ++typeWordRevIter;
       continue;
@@ -648,7 +664,6 @@
       auto nextNameWordRevIter = std::next(nameWordRevIter);
       if (nextNameWordRevIter != nameWordRevIterEnd &&
           matchNameWordToTypeWord(*nextNameWordRevIter, "Object")) {
-        matched();
         nameWordRevIter = nextNameWordRevIter;
         ++nameWordRevIter;
         ++typeWordRevIter;
@@ -659,32 +674,30 @@
     // Special case: if the word in the name ends in 's', and we have
     // a collection element type, see if this is a plural.
     if (!typeName.CollectionElement.empty() && nameWord.size() > 2 &&
-        nameWord.back() == 's' && role != NameRole::BaseNameSelf) {
+        nameWord.back() == 's') {
       // Check <element name>s.
-      auto shortenedNameWord
-        = name.substr(0, nameWordRevIter.base().getPosition()-1);
-      auto newShortenedNameWord
-        = omitNeedlessWords(shortenedNameWord, typeName.CollectionElement,
-                            NameRole::Partial, allPropertyNames, scratch);
-      if (shortenedNameWord == newShortenedNameWord &&
-          shortenedNameWord.back() == 'e') {
-        (void)shortenedNameWord.drop_back();
-        newShortenedNameWord =
-          omitNeedlessWords(shortenedNameWord, typeName.CollectionElement,
-                            NameRole::Partial, allPropertyNames, scratch);
-      }
+      auto shortenedNameWord = nameWordRevIter.base().getPriorStr().drop_back();
+      auto newShortenedNameWord = omitTrailingTypeNameWithSpecialCases(
+          shortenedNameWord, typeName.CollectionElement, NameRole::Partial,
+          allPropertyNames);
 
       if (shortenedNameWord != newShortenedNameWord) {
-        matched();
         unsigned targetSize = newShortenedNameWord.size();
+        auto newIter = llvm::make_reverse_iterator(WordIterator(name,
+                                                                targetSize));
+#ifndef NDEBUG
         while (nameWordRevIter.base().getPosition() > targetSize)
           ++nameWordRevIter;
+        assert(nameWordRevIter == newIter);
+#else
+        nameWordRevIter = newIter;
+#endif
         continue;
       }
     }
 
     // If this is a skippable suffix, skip it and keep looking.
-    if (nameWordRevIter == nameWordRevIterBegin) {
+    if (canSkipTypeSuffix && nameWordRevIter == nameWordRevIterBegin) {
       if (auto withoutSuffix = skipTypeSuffix(typeName.Name)) {
         typeName.Name = *withoutSuffix;
         typeWords = camel_case::getWords(typeName.Name);
@@ -694,125 +707,181 @@
       }
     }
 
-    // If we're matching the base name of a method against the type of
-    // 'Self', and we haven't matched anything yet, skip over words in
-    // the name.
-    if (role == NameRole::BaseNameSelf && !anyMatches) {
-      ++nameWordRevIter;
-      continue;
-    }
-
     break;
   }
 
+  return nameWordRevIter.base();
+}
+
+static StringRef
+omitSelfTypeFromBaseName(StringRef name, OmissionTypeName typeName,
+                         const InheritedNameSet *allPropertyNames,
+                         StringScratchSpace &scratch) {
+  // If we have no name or no type name, there is nothing to do.
+  if (name.empty() || typeName.empty()) return name;
+
+  // Deliberately drop the collection element from typeName.
+  typeName.CollectionElement = StringRef();
+
+  auto nameWords = camel_case::getWords(name);
+
+  bool canSkipTypeSuffix = true;
+  Optional<llvm::iterator_range<WordIterator>> matchingRange;
+
+  // Search backwards for the type name, whether anchored at the end or not.
+  for (auto nameReverseIter = nameWords.rbegin();
+       nameReverseIter != nameWords.rend();
+       ++nameReverseIter) {
+    StringRef matchName = nameReverseIter.base().getPriorStr();
+    auto matchIter = matchTypeNameFromBackWithSpecialCases(matchName, typeName,
+                                                           allPropertyNames,
+                                                           canSkipTypeSuffix);
+    auto matchIterInFullName = WordIterator(name, matchIter.getPosition());
+    if (matchIterInFullName != nameReverseIter.base()) {
+      matchingRange = llvm::make_range(matchIterInFullName,
+                                       nameReverseIter.base());
+      break;
+    }
+
+    // Note: This behavior fell out of a previous implementation of
+    // omit-needless-words, even though it probably wasn't intentional. At this
+    // point, though, it could be source-breaking to change it.
+    canSkipTypeSuffix = false;
+  }
+
+  // If we matched nothing, or if the type name was all the way at the start
+  // of the base name, don't strip anything.
+  if (!matchingRange || matchingRange->begin() == nameWords.begin())
+    return name;
+  assert(matchingRange->begin() != matchingRange->end() &&
+         "should not have been considered a match");
+
+  // Don't strip just "Error" at the end of a base name.
+  // FIXME: Is this still relevant?
+  if (matchingRange->end() == nameWords.end() &&
+      std::next(matchingRange->begin()) == nameWords.end() &&
+      *matchingRange->begin() == "Error") {
+    return name;
+  }
+
+  // Only strip a type name that follows a verb.
+  switch (getPartOfSpeech(*std::prev(matchingRange->begin()))) {
+  case PartOfSpeech::Verb:
+    break;
+  case PartOfSpeech::Preposition:
+  case PartOfSpeech::Gerund:
+  case PartOfSpeech::Unknown:
+    return name;
+  }
+
+  // Splice together the parts before and after the matched
+  // type. For example, if we matched "ViewController" in
+  // "dismissViewControllerAnimated", stitch together
+  // "dismissAnimated".
+
+  // Don't prune redundant type information from the base name if
+  // there is a corresponding property (either singular or plural).
+  StringRef removedText = name.substr(matchingRange->begin().getPosition(),
+                                      matchingRange->end().getPosition());
+  if (textMatchesPropertyName(removedText, allPropertyNames))
+    return name;
+
+  SmallString<16> newName = matchingRange->begin().getPriorStr();
+  newName += matchingRange->end().getRestOfStr();
+
+  // If we ended up with something that can't be a member name, do nothing.
+  if (!canBeMemberName(newName))
+    return name;
+
+  // If we ended up with a vacuous name like "get" or "set", do nothing.
+  if (isVacuousName(newName))
+    return name;
+
+  // We're done.
+  return scratch.copyString(newName);
+}
+
+static StringRef
+omitTrailingTypeNameWithSpecialCases(StringRef name, OmissionTypeName typeName,
+                                     NameRole role,
+                                     const InheritedNameSet *allPropertyNames) {
+  // If we have no name or no type name, there is nothing to do.
+  if (name.empty() || typeName.empty()) return name;
+
+  auto nameWords = camel_case::getWords(name);
+  Words::iterator matchIter =
+      matchTypeNameFromBackWithSpecialCases(name, typeName, allPropertyNames);
+
+  if (matchIter == nameWords.end())
+    return name;
+
   StringRef origName = name;
 
-  // If we matched anything above, update the name appropriately.
-  if (anyMatches) {
-    // Handle complete name matches.
-    if (nameWordRevIter == nameWordRevIterEnd) {
-      // If we're doing a partial match or we have an initial
-      // parameter, return the empty string.
-      if (role == NameRole::Partial || role == NameRole::FirstParameter)
-        return "";
+  // Handle complete name matches.
+  if (matchIter == nameWords.begin()) {
+    // If we're doing a partial match or we have an initial
+    // parameter, return the empty string.
+    if (role == NameRole::Partial || role == NameRole::FirstParameter)
+      return "";
 
-      // Leave the name alone.
-      return name;
-    }
+    // Leave the name alone.
+    return name;
+  }
 
-    // Don't strip just "Error".
-    if (nameWordRevIter != nameWordRevIterBegin) {
-      auto nameWordPrev = std::prev(nameWordRevIter);
-      if (nameWordPrev == nameWordRevIterBegin && *nameWordPrev == "Error")
-        return name;
-    }
+  // Don't strip just "Error".
+  if (std::next(matchIter) == nameWords.end() && *matchIter == "Error")
+    return name;
 
-    switch (role) {
-    case NameRole::Property:
-      // Always strip off type information.
-      name = name.substr(0, nameWordRevIter.base().getPosition());
-      break;
+  switch (role) {
+  case NameRole::Property:
+    // Always strip off type information.
+    name = matchIter.getPriorStr();
+    break;
 
-    case NameRole::BaseNameSelf:
-      switch (getPartOfSpeech(*nameWordRevIter)) {
-      case PartOfSpeech::Verb: {
-        // Splice together the parts before and after the matched
-        // type. For example, if we matched "ViewController" in
-        // "dismissViewControllerAnimated", stitch together
-        // "dismissAnimated".
-
-        // Don't prune redundant type information from the base name if
-        // there is a corresponding property (either singular or plural).
-        StringRef removedText =
-          name.substr(nameWordRevIter.base().getPosition(),
-                      firstMatchingNameWordRevIter.base().getPosition());
-        if (textMatchesPropertyName(removedText, allPropertyNames))
-          return name;
-
-        SmallString<16> newName =
-          name.substr(0, nameWordRevIter.base().getPosition());
-        newName
-          += name.substr(firstMatchingNameWordRevIter.base().getPosition());
-        name = scratch.copyString(newName);
-        break;
-      }
-
-      case PartOfSpeech::Preposition:
-      case PartOfSpeech::Gerund:
-      case PartOfSpeech::Unknown:
-        return name;
-      }
-      break;
-
-    case NameRole::BaseName:
-    case NameRole::FirstParameter:
-    case NameRole::Partial:
-    case NameRole::SubsequentParameter:
-      // Classify the part of speech of the word before the type
-      // information we would strip off.
-      switch (getPartOfSpeech(*nameWordRevIter)) {
-      case PartOfSpeech::Preposition:
-        if (role == NameRole::BaseName) {
-          // Strip off the part of the name that is redundant with
-          // type information, so long as there's something preceding the
-          // preposition.
-          if (std::next(nameWordRevIter) != nameWordRevIterEnd)
-            name = name.substr(0, nameWordRevIter.base().getPosition());
-          break;
-        }
-
-        LLVM_FALLTHROUGH;
-
-      case PartOfSpeech::Verb:
-      case PartOfSpeech::Gerund:
-        // Don't prune redundant type information from the base name if
-        // there is a corresponding property (either singular or plural).
-        if (role == NameRole::BaseName &&
-            textMatchesPropertyName(
-              name.substr(nameWordRevIter.base().getPosition()),
-              allPropertyNames))
-          return name;
-
+  case NameRole::BaseName:
+  case NameRole::FirstParameter:
+  case NameRole::Partial:
+  case NameRole::SubsequentParameter:
+    // Classify the part of speech of the word before the type
+    // information we would strip off.
+    auto previousWordIter = std::prev(matchIter);
+    switch (getPartOfSpeech(*previousWordIter)) {
+    case PartOfSpeech::Preposition:
+      if (role == NameRole::BaseName) {
         // Strip off the part of the name that is redundant with
-        // type information.
-        name = name.substr(0, nameWordRevIter.base().getPosition());
-        break;
-
-      case PartOfSpeech::Unknown:
-        // Assume it's a noun or adjective; don't strip anything.
+        // type information, so long as there's something preceding the
+        // preposition.
+        if (previousWordIter != nameWords.begin())
+          name = matchIter.getPriorStr();
         break;
       }
+
+      LLVM_FALLTHROUGH;
+
+    case PartOfSpeech::Verb:
+    case PartOfSpeech::Gerund:
+      // Don't prune redundant type information from the base name if
+      // there is a corresponding property (either singular or plural).
+      if (role == NameRole::BaseName &&
+          textMatchesPropertyName(matchIter.getRestOfStr(), allPropertyNames))
+        return name;
+
+      // Strip off the part of the name that is redundant with
+      // type information.
+      name = matchIter.getPriorStr();
+      break;
+
+    case PartOfSpeech::Unknown:
+      // Assume it's a noun or adjective; don't strip anything.
       break;
     }
-
+    break;
   }
 
   switch (role) {
   case NameRole::BaseName:
-  case NameRole::BaseNameSelf:
   case NameRole::Property:
     // If we ended up with something that can't be a member name, do nothing.
-    // do nothing.
     if (!canBeMemberName(name))
       return origName;
 
@@ -1154,7 +1223,7 @@
 bool swift::omitNeedlessWords(StringRef &baseName,
                               MutableArrayRef<StringRef> argNames,
                               StringRef firstParamName,
-                              OmissionTypeName resultType,
+                              OmissionTypeName givenResultType,
                               OmissionTypeName contextType,
                               ArrayRef<OmissionTypeName> paramTypes,
                               bool returnsSelf,
@@ -1162,6 +1231,7 @@
                               const InheritedNameSet *allPropertyNames,
                               StringScratchSpace &scratch) {
   bool anyChanges = false;
+  OmissionTypeName resultType = returnsSelf ? contextType : givenResultType;
 
   /// Local function that lowercases all of the base names and
   /// argument names before returning.
@@ -1185,7 +1255,7 @@
 
   // If the result type matches the context, remove the context type from the
   // prefix of the name.
-  bool resultTypeMatchesContext = returnsSelf || (resultType == contextType);
+  bool resultTypeMatchesContext = (resultType == contextType);
   if (resultTypeMatchesContext) {
     StringRef newBaseName = omitNeedlessWordsFromPrefix(baseName, contextType,
                                                         scratch);
@@ -1197,9 +1267,8 @@
 
   // Strip the context type from the base name of a method.
   if (!isProperty) {
-    StringRef newBaseName = ::omitNeedlessWords(baseName, contextType,
-                                                NameRole::BaseNameSelf,
-                                                allPropertyNames, scratch);
+    StringRef newBaseName = omitSelfTypeFromBaseName(baseName, contextType,
+                                                     allPropertyNames, scratch);
     if (newBaseName != baseName) {
       baseName = newBaseName;
       anyChanges = true;
@@ -1208,12 +1277,8 @@
 
   if (paramTypes.empty()) {
     if (resultTypeMatchesContext) {
-      StringRef newBaseName = ::omitNeedlessWords(
-                                baseName,
-                                returnsSelf ? contextType : resultType,
-                                NameRole::Property,
-                                allPropertyNames,
-                                scratch);
+      StringRef newBaseName = omitTrailingTypeNameWithSpecialCases(
+          baseName, resultType, NameRole::Property, allPropertyNames);
       if (newBaseName != baseName) {
         baseName = newBaseName;
         anyChanges = true;
@@ -1224,12 +1289,8 @@
   }
 
   if (camel_case::getFirstWord(baseName) == "set") {
-    StringRef newBaseName = ::omitNeedlessWords(
-                              baseName,
-                              contextType,
-                              NameRole::Property,
-                              allPropertyNames,
-                              scratch);
+    StringRef newBaseName = omitTrailingTypeNameWithSpecialCases(
+        baseName, contextType, NameRole::Property, allPropertyNames);
     if (newBaseName != baseName) {
       baseName = newBaseName;
       anyChanges = true;
@@ -1256,11 +1317,9 @@
 
     // Omit needless words from the name.
     StringRef name = role == NameRole::BaseName ? baseName : argNames[i];
-    StringRef newName = ::omitNeedlessWords(name, paramTypes[i], role,
-                                            role == NameRole::BaseName 
-                                              ? allPropertyNames
-                                              : nullptr,
-                                            scratch);
+    StringRef newName = omitTrailingTypeNameWithSpecialCases(
+        name, paramTypes[i], role,
+        role == NameRole::BaseName ? allPropertyNames : nullptr);
 
     if (name == newName) continue;
 
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index e86fd65..027237e 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -522,10 +522,11 @@
   ASTContext &C = Impl.SwiftContext;
   auto rawTy = enumDecl->getRawType();
 
-  auto param = new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(),
+  auto param = new (C) ParamDecl(SourceLoc(),
                                  SourceLoc(), C.Id_rawValue,
                                  SourceLoc(), C.Id_rawValue,
                                  enumDecl);
+  param->setSpecifier(ParamSpecifier::Default);
   param->setInterfaceType(rawTy);
 
   auto paramPL = ParameterList::createWithoutLoc(param);
@@ -738,10 +739,10 @@
                                          VarDecl *importedFieldDecl,
                                          ClangNode clangNode = ClangNode()) {
   auto &C = Impl.SwiftContext;
-  auto newValueDecl = new (C) ParamDecl(ParamDecl::Specifier::Default,
-                                        SourceLoc(), SourceLoc(),
+  auto newValueDecl = new (C) ParamDecl(SourceLoc(), SourceLoc(),
                                         Identifier(), SourceLoc(), C.Id_value,
                                         importedDecl);
+  newValueDecl->setSpecifier(ParamSpecifier::Default);
   newValueDecl->setInterfaceType(importedFieldDecl->getInterfaceType());
 
   auto *params = ParameterList::createWithoutLoc(newValueDecl);
@@ -1418,8 +1419,9 @@
 
     Identifier argName = generateParamName ? var->getName() : Identifier();
     auto param = new (context)
-        ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), argName,
+        ParamDecl(SourceLoc(), SourceLoc(), argName,
                   SourceLoc(), var->getName(), structDecl);
+    param->setSpecifier(ParamSpecifier::Default);
     param->setInterfaceType(var->getInterfaceType());
     Impl.recordImplicitUnwrapForDecl(param, var->isImplicitlyUnwrappedOptional());
     valueParameters.push_back(param);
@@ -1479,7 +1481,6 @@
   typealias->setUnderlyingType(underlyingType);
   typealias->setAccess(AccessLevel::Public);
   typealias->setImplicit();
-  typealias->computeType();
 
   nominal->addMember(typealias);
 }
@@ -1713,7 +1714,6 @@
                      TypeLoc::withoutLoc(elementTy), dc,
                      getter->getClangNode());
 
-  thunk->setGenericSignature(dc->getGenericSignatureOfContext());
   thunk->computeType();
 
   thunk->setAccess(getOverridableAccessLevel(dc));
@@ -1746,8 +1746,9 @@
   auto valueIndex = setter->getParameters();
 
   auto paramVarDecl =
-      new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+      new (C) ParamDecl(SourceLoc(), SourceLoc(),
                         Identifier(), loc, valueIndex->get(0)->getName(), dc);
+  paramVarDecl->setSpecifier(ParamSpecifier::Default);
   paramVarDecl->setInterfaceType(elementInterfaceTy);
 
   auto valueIndicesPL = ParameterList::create(C, {paramVarDecl, index});
@@ -1766,7 +1767,6 @@
                      valueIndicesPL,
                      TypeLoc::withoutLoc(TupleType::getEmpty(C)), dc,
                      setter->getClangNode());
-  thunk->setGenericSignature(dc->getGenericSignatureOfContext());
   thunk->computeType();
 
   thunk->setAccess(getOverridableAccessLevel(dc));
@@ -1952,7 +1952,6 @@
                      /*GenericParams=*/nullptr,
                      params,
                      TypeLoc::withoutLoc(stringTy), swiftDecl);
-  getterDecl->setStatic(isStatic);
   getterDecl->computeType();
   getterDecl->setIsObjC(false);
   getterDecl->setIsDynamic(false);
@@ -1962,7 +1961,6 @@
   makeComputed(errorDomainPropertyDecl, getterDecl, nullptr);
 
   getterDecl->setImplicit();
-  getterDecl->setStatic(isStatic);
   getterDecl->setAccess(AccessLevel::Public);
 
   llvm::PointerIntPair<ValueDecl *, 1, bool> contextData(swiftValueDecl,
@@ -2365,7 +2363,6 @@
           decl, AccessLevel::Public, loc,
           importedName.getDeclName().getBaseIdentifier(),
           Impl.importSourceLoc(decl->getLocation()), None, nullptr, dc);
-      enumDecl->computeType();
       enumDecl->setMemberLoader(&Impl, 0);
       return enumDecl;
     }
@@ -2544,7 +2541,6 @@
                             /*genericparams*/nullptr, DC);
               typealias->setUnderlyingType(
                   underlying->getDeclaredInterfaceType());
-              typealias->computeType();
 
               Impl.SpecialTypedefNames[Decl->getCanonicalDecl()] =
                 MappedTypeNameKind::DefineAndUse;
@@ -2564,7 +2560,6 @@
                             /*genericparams*/nullptr, DC);
               typealias->setUnderlyingType(
                 Impl.SwiftContext.getAnyObjectType());
-              typealias->computeType();
 
               Impl.SpecialTypedefNames[Decl->getCanonicalDecl()] =
                 MappedTypeNameKind::DefineAndUse;
@@ -2632,7 +2627,6 @@
                                       Loc,
                                       /*genericparams*/nullptr, DC);
       Result->setUnderlyingType(SwiftType);
-      Result->computeType();
       
       // Make Objective-C's 'id' unavailable.
       if (Impl.SwiftContext.LangOpts.EnableObjCInterop && isObjCId(Decl)) {
@@ -2734,7 +2728,6 @@
         auto Loc = Impl.importSourceLoc(decl->getLocation());
         auto structDecl = Impl.createDeclWithClangNode<StructDecl>(decl,
           AccessLevel::Public, Loc, name, Loc, None, nullptr, dc);
-        structDecl->computeType();
         structDecl->setAddedImplicitInitializers();
 
         auto options = getDefaultMakeStructRawValuedOptions();
@@ -2784,7 +2777,6 @@
                C.getProtocol(KnownProtocolKind::ErrorCodeProtocol))) {
           // Create the wrapper struct.
           errorWrapper = new (C) StructDecl(loc, name, loc, None, nullptr, dc);
-          errorWrapper->computeType();
           errorWrapper->setAddedImplicitInitializers();
           errorWrapper->setAccess(AccessLevel::Public);
           errorWrapper->getAttrs().add(
@@ -2853,7 +2845,7 @@
         auto enumDecl = Impl.createDeclWithClangNode<EnumDecl>(
             decl, AccessLevel::Public, loc, enumName,
             Impl.importSourceLoc(decl->getLocation()), None, nullptr, enumDC);
-        enumDecl->computeType();
+        enumDecl->setHasFixedRawValues();
 
         // Annotate as 'frozen' if appropriate.
         if (enumKind == EnumKind::FrozenEnum)
@@ -2924,7 +2916,6 @@
                          C.Id_ErrorType, loc,
                          /*genericparams=*/nullptr, enumDecl);
           alias->setUnderlyingType(errorWrapper->getDeclaredInterfaceType());
-          alias->computeType();
           enumDecl->addMember(alias);
 
           // Add the 'Code' enum to the error wrapper.
@@ -3220,7 +3211,6 @@
                                  name,
                                  Impl.importSourceLoc(decl->getLocation()),
                                  None, nullptr, dc);
-      result->computeType();
       result->setAddedImplicitInitializers();
       Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
 
@@ -3739,8 +3729,6 @@
                                     nameLoc, bodyParams, resultTy,
                                     /*throws*/ false, dc, decl);
 
-      result->setGenericSignature(dc->getGenericSignatureOfContext());
-
       if (!dc->isModuleScopeContext()) {
         if (selfIsInOut)
           result->setSelfAccessKind(SelfAccessKind::Mutating);
@@ -4014,7 +4002,6 @@
           Loc,
           /*genericparams*/nullptr, DC);
       Result->setUnderlyingType(SwiftTypeDecl->getDeclaredInterfaceType());
-      Result->computeType();
 
       return Result;
     }
@@ -4328,8 +4315,6 @@
       // Record the return type.
       result->getBodyResultTypeLoc().setType(resultTy);
 
-      result->setGenericSignature(dc->getGenericSignatureOfContext());
-
       // Optional methods in protocols.
       if (decl->getImplementationControl() == clang::ObjCMethodDecl::Optional &&
           isa<ProtocolDecl>(dc))
@@ -4670,7 +4655,6 @@
           Impl.importSourceLoc(decl->getBeginLoc()),
           Impl.importSourceLoc(decl->getLocation()), name, None,
           /*TrailingWhere=*/nullptr);
-      result->computeType();
 
       addObjCAttribute(result, Impl.importIdentifier(decl->getIdentifier()));
 
@@ -4715,7 +4699,6 @@
                                                         SourceLoc(), name,
                                                         SourceLoc(), None,
                                                         nullptr, dc);
-        result->computeType();
         Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
         result->setCircularityCheck(CircularityCheck::Checked);
         result->setSuperclass(Type());
@@ -4820,8 +4803,6 @@
         return nullptr;
       }
 
-      result->computeType();
-
       Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
       result->setCircularityCheck(CircularityCheck::Checked);
       addObjCAttribute(result, Impl.importIdentifier(decl->getIdentifier()));
@@ -5147,7 +5128,6 @@
       }
 
       typealias->setUnderlyingType(typeDecl->getDeclaredInterfaceType());
-      typealias->computeType();
       return typealias;
     }
 
@@ -5301,7 +5281,6 @@
   auto theClass = Impl.createDeclWithClangNode<ClassDecl>(
       decl, AccessLevel::Public, SourceLoc(), className, SourceLoc(), None,
       nullptr, dc);
-  theClass->computeType();
   theClass->setCircularityCheck(CircularityCheck::Checked);
   theClass->setSuperclass(superclass);
   theClass->setAddedImplicitInitializers(); // suppress all initializers
@@ -5383,7 +5362,6 @@
   }
 
   alias->setUnderlyingType(typeDecl->getDeclaredInterfaceType());
-  alias->computeType();
   
   // Record that this is the official version of this declaration.
   Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = alias;
@@ -5468,7 +5446,6 @@
 
   auto structDecl = Impl.createDeclWithClangNode<StructDecl>(
       decl, AccessLevel::Public, Loc, name, Loc, None, nullptr, dc);
-  structDecl->computeType();
   structDecl->setAddedImplicitInitializers();
 
   // Import the type of the underlying storage
@@ -5652,9 +5629,6 @@
       decl, AccessLevel::Public, SourceLoc(), name, nullptr,
       SourceLoc(), rawValueExpr, theEnum);
 
-  // Give the enum element the appropriate type.
-  element->computeType();
-
   Impl.importAttributes(decl, element);
 
   return element;
@@ -5748,7 +5722,6 @@
   // Create a struct with the underlying type as a field.
   auto structDecl = Impl.createDeclWithClangNode<StructDecl>(
       decl, AccessLevel::Public, Loc, name, Loc, None, nullptr, dc);
-  structDecl->computeType();
   structDecl->setAddedImplicitInitializers();
 
   makeStructRawValued(Impl, structDecl, underlyingType,
@@ -5789,8 +5762,9 @@
     // argument label
     auto *paramDecl =
         new (Impl.SwiftContext) ParamDecl(
-            ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), argNames.front(),
+            SourceLoc(), SourceLoc(), argNames.front(),
             SourceLoc(), argNames.front(), dc);
+    paramDecl->setSpecifier(ParamSpecifier::Default);
     paramDecl->setInterfaceType(Impl.SwiftContext.TheEmptyTupleType);
 
     parameterList = ParameterList::createWithoutLoc(paramDecl);
@@ -6334,7 +6308,6 @@
   addObjCAttribute(result, selector);
 
   // Calculate the function type of the result.
-  result->setGenericSignature(dc->getGenericSignatureOfContext());
   result->computeType();
 
   Impl.recordImplicitUnwrapForDecl(result,
@@ -6765,11 +6738,8 @@
   if (setterObjCMethod)
     Impl.importAttributes(setterObjCMethod, setterThunk);
 
-  subscript->setGenericSignature(dc->getGenericSignatureOfContext());
-
   subscript->setIsSetterMutating(false);
   makeComputed(subscript, getterThunk, setterThunk);
-  subscript->computeType();
 
   Impl.recordImplicitUnwrapForDecl(subscript, isIUO);
 
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index 57fc37b..92df022 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -1720,11 +1720,10 @@
     // It doesn't actually matter which DeclContext we use, so just use the
     // imported header unit.
     auto paramInfo = createDeclWithClangNode<ParamDecl>(
-        param, AccessLevel::Private,
-        ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), name,
+        param, AccessLevel::Private, SourceLoc(), SourceLoc(), name,
         importSourceLoc(param->getLocation()), bodyName,
         ImportedHeaderUnit);
-
+    paramInfo->setSpecifier(ParamSpecifier::Default);
     paramInfo->setInterfaceType(swiftParamTy);
     recordImplicitUnwrapForDecl(paramInfo,
                                 importedType.isImplicitlyUnwrapped());
@@ -1738,11 +1737,11 @@
         BoundGenericType::get(SwiftContext.getArrayDecl(), Type(),
                               {SwiftContext.TheAnyType});
     auto name = SwiftContext.getIdentifier("varargs");
-    auto param = new (SwiftContext) ParamDecl(ParamDecl::Specifier::Default,
-                                              SourceLoc(), SourceLoc(),
+    auto param = new (SwiftContext) ParamDecl(SourceLoc(), SourceLoc(),
                                               Identifier(), SourceLoc(),
                                               name,
                                               ImportedHeaderUnit);
+    param->setSpecifier(ParamSpecifier::Default);
     param->setInterfaceType(paramTy);
 
     param->setVariadic();
@@ -1799,7 +1798,7 @@
     const clang::EnumDecl *enumDef = enumTy->getDecl()->getDefinition();
     if (enumDef && nameImporter.getEnumKind(enumDef) == EnumKind::Options) {
       auto enumName = enumDef->getName();
-      for (auto word : reversed(camel_case::getWords(enumName))) {
+      for (auto word : llvm::reverse(camel_case::getWords(enumName))) {
         if (camel_case::sameWordIgnoreFirstCase(word, "options"))
           return DefaultArgumentKind::EmptyArray;
       }
@@ -1821,7 +1820,7 @@
           emptyDictionaryKind = DefaultArgumentKind::NilLiteral;
 
         bool sawInfo = false;
-        for (auto word : reversed(camel_case::getWords(searchStr))) {
+        for (auto word : llvm::reverse(camel_case::getWords(searchStr))) {
           if (camel_case::sameWordIgnoreFirstCase(word, "options"))
             return emptyDictionaryKind;
 
@@ -2038,10 +2037,11 @@
     // 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(ParamDecl::Specifier::Default, SourceLoc(),
+    auto var = new (SwiftContext) ParamDecl(SourceLoc(),
                                             SourceLoc(), argName,
                                             SourceLoc(), argName,
                                             ImportedHeaderUnit);
+    var->setSpecifier(ParamSpecifier::Default);
     var->setInterfaceType(type);
     swiftParams.push_back(var);
   };
@@ -2157,11 +2157,11 @@
     // Set up the parameter info.
     auto paramInfo
       = createDeclWithClangNode<ParamDecl>(param, AccessLevel::Private,
-                                           ParamDecl::Specifier::Default,
                                            SourceLoc(), SourceLoc(), name,
                                            importSourceLoc(param->getLocation()),
                                            bodyName,
                                            ImportedHeaderUnit);
+    paramInfo->setSpecifier(ParamSpecifier::Default);
     paramInfo->setInterfaceType(swiftParamTy);
     recordImplicitUnwrapForDecl(paramInfo, paramIsIUO);
 
@@ -2269,11 +2269,11 @@
     Identifier argLabel = functionName.getDeclName().getArgumentNames().front();
     auto paramInfo
       = createDeclWithClangNode<ParamDecl>(param, AccessLevel::Private,
-                                           ParamDecl::Specifier::Default,
                                            /*let loc*/SourceLoc(),
                                            /*label loc*/SourceLoc(),
                                            argLabel, nameLoc, bodyName,
                                            /*dummy DC*/ImportedHeaderUnit);
+    paramInfo->setSpecifier(ParamSpecifier::Default);
     paramInfo->setInterfaceType(propertyTy);
 
     *params = ParameterList::create(SwiftContext, paramInfo);
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 4d53646..c696ac2 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -2793,7 +2793,7 @@
                                                 StringRef workingDirectory,
                                                 CommandOutput *Output,
                                                 file_types::ID fileID,
-                                                bool isPrivate,
+                                                bool shouldUseProjectFolder = false,
                                                 Optional<options::ID> optId = llvm::None) {
   if (hasExistingAdditionalOutput(*Output, fileID))
     return;
@@ -2819,9 +2819,9 @@
     bool isTempFile = C.isTemporaryFile(ModulePath);
     auto ModuleName = llvm::sys::path::filename(ModulePath);
     llvm::SmallString<128> Path(llvm::sys::path::parent_path(ModulePath));
-    if (isPrivate) {
-      llvm::sys::path::append(Path, "Private");
-      // If the build system has created a Private dir for us to include the file, use it.
+    if (shouldUseProjectFolder) {
+      llvm::sys::path::append(Path, "Project");
+      // If the build system has created a Project dir for us to include the file, use it.
       if (!llvm::sys::fs::exists(Path)) {
         llvm::sys::path::remove_filename(Path);
       }
@@ -2840,7 +2840,8 @@
                                              CommandOutput *Output) const {
   chooseModuleAuxiliaryOutputFilePath(C, OutputMap, workingDirectory, Output,
                                       file_types::TY_SwiftSourceInfoFile,
-                                      /*isPrivate*/true, options::OPT_emit_module_source_info_path);
+                                      /*shouldUseProjectFolder*/true,
+                                      options::OPT_emit_module_source_info_path);
 }
 
 void Driver::chooseSwiftModuleDocOutputPath(Compilation &C,
@@ -2848,7 +2849,7 @@
                                             StringRef workingDirectory,
                                             CommandOutput *Output) const {
   chooseModuleAuxiliaryOutputFilePath(C, OutputMap, workingDirectory, Output,
-                                      file_types::TY_SwiftModuleDocFile, /*isPrivate*/false);
+                                      file_types::TY_SwiftModuleDocFile);
 }
 
 void Driver::chooseRemappingOutputPath(Compilation &C,
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index df6b3de..6d8bb64 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -208,6 +208,7 @@
   if (setUpModuleLoaders())
     return true;
 
+  createTypeChecker(*Context);
   return false;
 }
 
@@ -468,38 +469,35 @@
       return existingBufferID;
     }
   }
-  std::pair<std::unique_ptr<llvm::MemoryBuffer>,
-            std::unique_ptr<llvm::MemoryBuffer>>
-      buffers = getInputBufferAndModuleDocBufferIfPresent(input);
+  auto buffers = getInputBuffersIfPresent(input);
 
-  if (!buffers.first) {
+  if (!buffers.hasValue()) {
     failed = true;
     return None;
   }
 
   // FIXME: The fact that this test happens twice, for some cases,
   // suggests that setupInputs could use another round of refactoring.
-  if (serialization::isSerializedAST(buffers.first->getBuffer())) {
+  if (serialization::isSerializedAST(buffers->ModuleBuffer->getBuffer())) {
     PartialModules.push_back(
-        {std::move(buffers.first), std::move(buffers.second)});
+        {std::move(buffers->ModuleBuffer), std::move(buffers->ModuleDocBuffer),
+         std::move(buffers->ModuleSourceInfoBuffer)});
     return None;
   }
-  assert(buffers.second.get() == nullptr);
+  assert(buffers->ModuleDocBuffer.get() == nullptr);
+  assert(buffers->ModuleSourceInfoBuffer.get() == nullptr);
   // Transfer ownership of the MemoryBuffer to the SourceMgr.
-  unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers.first));
+  unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers->ModuleBuffer));
 
   InputSourceCodeBufferIDs.push_back(bufferID);
   return bufferID;
 }
 
-std::pair<std::unique_ptr<llvm::MemoryBuffer>,
-          std::unique_ptr<llvm::MemoryBuffer>>
-CompilerInstance::getInputBufferAndModuleDocBufferIfPresent(
+Optional<CompilerInstance::ModuleBuffers> CompilerInstance::getInputBuffersIfPresent(
     const InputFile &input) {
   if (auto b = input.buffer()) {
-    return std::make_pair(llvm::MemoryBuffer::getMemBufferCopy(
-                              b->getBuffer(), b->getBufferIdentifier()),
-                          nullptr);
+    return ModuleBuffers(llvm::MemoryBuffer::getMemBufferCopy(b->getBuffer(),
+                                                              b->getBufferIdentifier()));
   }
   // FIXME: Working with filenames is fragile, maybe use the real path
   // or have some kind of FileManager.
@@ -509,17 +507,35 @@
   if (!inputFileOrErr) {
     Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file, input.file(),
                          inputFileOrErr.getError().message());
-    return std::make_pair(nullptr, nullptr);
+    return None;
   }
   if (!serialization::isSerializedAST((*inputFileOrErr)->getBuffer()))
-    return std::make_pair(std::move(*inputFileOrErr), nullptr);
+    return ModuleBuffers(std::move(*inputFileOrErr));
 
-  if (Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleDocBuffer =
-          openModuleDoc(input)) {
-    return std::make_pair(std::move(*inputFileOrErr),
-                          std::move(*moduleDocBuffer));
-  }
-  return std::make_pair(nullptr, nullptr);
+  auto swiftdoc = openModuleDoc(input);
+  auto sourceinfo = openModuleSourceInfo(input);
+  return ModuleBuffers(std::move(*inputFileOrErr),
+                       swiftdoc.hasValue() ? std::move(swiftdoc.getValue()) : nullptr,
+                       sourceinfo.hasValue() ? std::move(sourceinfo.getValue()) : nullptr);
+}
+
+Optional<std::unique_ptr<llvm::MemoryBuffer>>
+CompilerInstance::openModuleSourceInfo(const InputFile &input) {
+  llvm::SmallString<128> pathWithoutProjectDir(input.file());
+  llvm::sys::path::replace_extension(pathWithoutProjectDir,
+                  file_types::getExtension(file_types::TY_SwiftSourceInfoFile));
+  llvm::SmallString<128> pathWithProjectDir = pathWithoutProjectDir.str();
+  StringRef fileName = llvm::sys::path::filename(pathWithoutProjectDir);
+  llvm::sys::path::remove_filename(pathWithProjectDir);
+  llvm::sys::path::append(pathWithProjectDir, "Project");
+  llvm::sys::path::append(pathWithProjectDir, fileName);
+  if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(),
+                                                            pathWithProjectDir))
+    return std::move(*sourceInfoFileOrErr);
+  if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(),
+                                                            pathWithoutProjectDir))
+    return std::move(*sourceInfoFileOrErr);
+  return None;
 }
 
 Optional<std::unique_ptr<llvm::MemoryBuffer>>
@@ -896,7 +912,8 @@
   for (auto &PM : PartialModules) {
     assert(PM.ModuleBuffer);
     if (!SML->loadAST(*MainModule, SourceLoc(), std::move(PM.ModuleBuffer),
-                      std::move(PM.ModuleDocBuffer), /*isFramework*/false,
+                      std::move(PM.ModuleDocBuffer),
+                      std::move(PM.ModuleSourceInfoBuffer), /*isFramework*/false,
                       /*treatAsPartialModule*/true))
       hadLoadError = true;
   }
diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp
index d77111a..e734a51 100644
--- a/lib/Frontend/ModuleInterfaceLoader.cpp
+++ b/lib/Frontend/ModuleInterfaceLoader.cpp
@@ -988,8 +988,10 @@
 std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
   AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
   StringRef ModuleDocFilename,
+  StringRef ModuleSourceInfoFilename,
   std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-  std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
+  std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+  std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
 
   // If running in OnlySerialized mode, ModuleInterfaceLoader
   // should not have been constructed at all.
@@ -1034,7 +1036,11 @@
   if (ModuleBuffer) {
     *ModuleBuffer = std::move(*ModuleBufferOrErr);
   }
-
+  // Open .swiftsourceinfo file if it's present.
+  SerializedModuleLoaderBase::openModuleSourceInfoFileIfPresent(ModuleID,
+                                                                ModPath,
+                                                       ModuleSourceInfoFilename,
+                                                       ModuleSourceInfoBuffer);
   // Delegate back to the serialized module loader to load the module doc.
   llvm::SmallString<256> DocPath{DirPath};
   path::append(DocPath, ModuleDocFilename);
diff --git a/lib/FrontendTool/ImportedModules.cpp b/lib/FrontendTool/ImportedModules.cpp
index 82e3e7d..5b9837f 100644
--- a/lib/FrontendTool/ImportedModules.cpp
+++ b/lib/FrontendTool/ImportedModules.cpp
@@ -37,8 +37,7 @@
     modules.insert(getTopLevelName(imported));
   }
 
-  for (auto sub :
-       makeIteratorRange(module->submodule_begin(), module->submodule_end())) {
+  for (auto sub : module->submodules()) {
     findAllClangImports(sub, modules);
   }
 }
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 2129062..09560b4 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -817,7 +817,7 @@
     if (auto *OVD = OD.dyn_cast<const ValueDecl*>()) {
       if (shouldCopyAssociatedUSRForDecl(OVD)) {
         llvm::raw_svector_ostream OS(SS);
-        Ignored = printDeclUSR(OVD, OS);
+        Ignored = printValueDeclUSR(OVD, OS);
       }
     } else if (auto *OND = OD.dyn_cast<const clang::NamedDecl*>()) {
       Ignored = clang::index::generateUSRForDecl(OND, SS);
diff --git a/lib/IDE/CommentConversion.cpp b/lib/IDE/CommentConversion.cpp
index 8b5c6f3..c5aabcd 100644
--- a/lib/IDE/CommentConversion.cpp
+++ b/lib/IDE/CommentConversion.cpp
@@ -346,7 +346,7 @@
     bool Failed;
     {
       llvm::raw_svector_ostream OS(SS);
-      Failed = ide::printDeclUSR(VD, OS);
+      Failed = ide::printValueDeclUSR(VD, OS);
     }
     if (!Failed && !SS.empty()) {
       OS << "<USR>" << SS << "</USR>";
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index d529944..978a405 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -545,7 +545,7 @@
   RenameRangeCollector(const ValueDecl *D, StringRef newName)
       : newName(newName.str()) {
     llvm::raw_string_ostream OS(USR);
-    printDeclUSR(D, OS);
+    printValueDeclUSR(D, OS);
   }
 
   ArrayRef<RenameLoc> results() const { return locations; }
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index 8ac9f86..e86f378 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -139,8 +139,10 @@
   for (ParamDecl *Param: *PL) {
     if (Param->isImplicit())
       continue;
-    
-    SourceLoc LabelStart(Param->getTypeLoc().getLoc());
+
+    SourceLoc LabelStart;
+    if (auto *repr = Param->getTypeRepr())
+      LabelStart = repr->getLoc();
     SourceLoc LabelEnd(LabelStart);
     
     if (Param->getNameLoc().isValid()) {
diff --git a/lib/IDE/SyntaxModel.cpp b/lib/IDE/SyntaxModel.cpp
index 0588400..d1640d8 100644
--- a/lib/IDE/SyntaxModel.cpp
+++ b/lib/IDE/SyntaxModel.cpp
@@ -49,6 +49,72 @@
       SrcMgr(SrcFile.getASTContext().SourceMgr) {}
 };
 
+/// Matches the tokens in the argument of an image or file literal expression if
+/// its argument is itself a literal string, e.g:
+///   #imageLiteral(resourceName: "foo.png")
+///   #fileLiteral(resourceName: "foo.txt")
+/// If the given tokens start with the expected tokens and they all appear on
+///  the same line, the source location beyond the final matched token and
+///  number of matched tokens are returned. Otherwise None is returned.
+static Optional<std::pair<SourceLoc, unsigned>>
+matchImageOrFileLiteralArg(ArrayRef<Token> Tokens) {
+  const unsigned NUM_TOKENS = 5;
+  if (Tokens.size() < NUM_TOKENS)
+    return None;
+  const tok kinds[NUM_TOKENS] = {
+      tok::l_paren,
+      tok::identifier, tok::colon, tok::string_literal,
+      tok::r_paren
+  };
+  for (unsigned i = 0; i < NUM_TOKENS; ++i) {
+    // FIXME: some editors don't handle multi-line object literals very well,
+    // so don't report them as object literals for now.
+    if (Tokens[i].getKind() != kinds[i] || Tokens[i].isAtStartOfLine())
+      return None;
+  }
+  if (Tokens[1].getText() != "resourceName")
+    return None;
+  auto EndToken = Tokens[NUM_TOKENS-1];
+  return std::make_pair(EndToken.getLoc().getAdvancedLoc(EndToken.getLength()),
+                        NUM_TOKENS);
+}
+
+/// Matches the tokens in the argument of an image literal expression if its
+/// arguments are themselves number literals, e.g:
+///   #colorLiteral(red: 1.0, green: 1.0, blue: 0.5, alpha: 1.0)
+/// If the given tokens start with the expected tokens and they all appear on
+/// the same line, the source location beyond the final matched token and number
+/// of matched tokens are returned. Otherwise None is returned.
+static Optional<std::pair<SourceLoc, unsigned>>
+matchColorLiteralArg(ArrayRef<Token> Tokens) {
+  const unsigned NUM_TOKENS = 17;
+  if (Tokens.size() < NUM_TOKENS)
+    return None;
+  const tok kinds[NUM_TOKENS] = {
+    tok::l_paren,
+    tok::identifier, tok::colon, tok::floating_literal, tok::comma,
+    tok::identifier, tok::colon, tok::floating_literal, tok::comma,
+    tok::identifier, tok::colon, tok::floating_literal, tok::comma,
+    tok::identifier, tok::colon, tok::floating_literal,
+    tok::r_paren
+  };
+  for (unsigned i = 0; i < NUM_TOKENS; ++i) {
+    auto Kind = Tokens[i].getKind();
+    if (Kind == tok::integer_literal)
+        Kind = tok::floating_literal;
+    // FIXME: some editors don't handle multi-line object literals very well,
+    // so don't report them as object literals for now.
+    if (Kind != kinds[i] || Tokens[i].isAtStartOfLine())
+      return None;
+  }
+  if (Tokens[1].getText() != "red" || Tokens[5].getText() != "green" ||
+      Tokens[9].getText() != "blue" || Tokens[13].getText() != "alpha")
+    return None;
+  auto EndToken = Tokens[NUM_TOKENS-1];
+  return std::make_pair(EndToken.getLoc().getAdvancedLoc(EndToken.getLength()),
+                        NUM_TOKENS);
+}
+
 SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
   : Impl(*new Implementation(SrcFile)) {
   const bool IsPlayground = Impl.LangOpts.Playground;
@@ -89,13 +155,38 @@
 #define KEYWORD(X) case tok::kw_##X:
 #include "swift/Syntax/TokenKinds.def"
 #undef KEYWORD
-        case tok::contextual_keyword:
+      case tok::contextual_keyword:
         Kind = SyntaxNodeKind::Keyword;
         break;
 
-#define POUND_OBJECT_LITERAL(Name, Desc, Proto) case tok::pound_##Name:
-#include "swift/Syntax/TokenKinds.def"
-        Kind = SyntaxNodeKind::Keyword;
+      // Note: the below only handles object literals where each argument is a
+      // single literal. If the arguments are more complex than that we rely on
+      // there being an ObjectLiteralExpr in the AST and convert the individual
+      // tokens within its range into a single object literal in
+      // ModelASTWalker. We only bother with the below so that in the most
+      // common cases we still present object literals as object literals when
+      // the ObjectLiteralExpr doesn't appear in the AST (which can happen when
+      // they appear within an invalid expression).
+      case tok::pound_fileLiteral:
+      case tok::pound_imageLiteral:
+        if (auto Match = matchImageOrFileLiteralArg(Tokens.slice(I+1))) {
+          Kind = SyntaxNodeKind::ObjectLiteral;
+          Length = SM.getByteDistance(Loc, Match->first);
+          // skip over the extra matched tokens
+          I += Match->second - 1;
+        } else {
+          Kind = SyntaxNodeKind::Keyword;
+        }
+        break;
+      case tok::pound_colorLiteral:
+        if (auto Match = matchColorLiteralArg(Tokens.slice(I+1))) {
+          Kind = SyntaxNodeKind::ObjectLiteral;
+          Length = SM.getByteDistance(Loc, Match->first);
+          // skip over the matches tokens
+          I += Match->second - 1;
+        } else {
+          Kind = SyntaxNodeKind::Keyword;
+        }
         break;
 
 #define POUND_COND_DIRECTIVE_KEYWORD(Name) case tok::pound_##Name:
@@ -428,6 +519,15 @@
     passNode(TokNode);
 }
 
+static bool shouldTreatAsSingleToken(const SyntaxStructureNode &Node,
+                                     const SourceManager &SM) {
+  // Avoid passing the individual syntax tokens corresponding to single-line
+  // object literal expressions, as they will be reported as a single token.
+  return Node.Kind == SyntaxStructureKind::ObjectLiteralExpression &&
+    SM.getLineNumber(Node.Range.getStart()) ==
+    SM.getLineNumber(Node.Range.getEnd());
+}
+
 std::pair<bool, Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
   if (isVisitedBefore(E))
     return {false, E};
@@ -497,8 +597,10 @@
     SN.NameRange = CharSourceRange(SM, NRStart, NREnd);
     SN.BodyRange =
       innerCharSourceRangeFromSourceRange(SM, ObjectE->getSourceRange());
-    // Consider the object literal as a single syntax token for highlighting.
-    passNonTokenNode({SyntaxNodeKind::ObjectLiteral, SN.Range});
+    // Consider the object literal as a single syntax token for highlighting if
+    // it spans a single line.
+    if (shouldTreatAsSingleToken(SN, SM))
+      passNonTokenNode({SyntaxNodeKind::ObjectLiteral, SN.Range});
     pushStructureNode(SN, E);
   } else if (auto *ArrayE = dyn_cast<ArrayExpr>(E)) {
     SyntaxStructureNode SN;
@@ -1256,14 +1358,10 @@
   return Walker.walkToNodePost(Node);
 }
 
-static bool shouldAvoidPssingSyntaxToken(const SyntaxStructureNode &Node) {
-  return Node.Kind == SyntaxStructureKind::ObjectLiteralExpression;
-}
-
 bool ModelASTWalker::pushStructureNode(const SyntaxStructureNode &Node,
                                        const ASTNodeType& ASTNode) {
   SubStructureStack.emplace_back(Node, ASTNode);
-  if (shouldAvoidPssingSyntaxToken(Node))
+  if (shouldTreatAsSingleToken(Node, SM))
     AvoidPassingSyntaxToken ++;
 
   if (!passTokenNodesUntil(Node.Range.getStart(),
@@ -1279,7 +1377,7 @@
   assert(!SubStructureStack.empty());
   SyntaxStructureNode Node = SubStructureStack.back().StructureNode;
   SWIFT_DEFER {
-    if (shouldAvoidPssingSyntaxToken(Node)) {
+    if (shouldTreatAsSingleToken(Node, SM)) {
       assert(AvoidPassingSyntaxToken);
       AvoidPassingSyntaxToken --;
     }
diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp
index bdb04fc..a009224 100644
--- a/lib/IRGen/GenClangType.cpp
+++ b/lib/IRGen/GenClangType.cpp
@@ -64,8 +64,7 @@
   // that's a real thing.
   if (results.size() == 1) {
     if (auto typeDecl = dyn_cast<TypeDecl>(results[0]))
-      if (typeDecl->hasInterfaceType())
-        return typeDecl->getDeclaredInterfaceType()->getCanonicalType();
+      return typeDecl->getDeclaredInterfaceType()->getCanonicalType();
   }
   return CanType();
 }
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 7543269..4d4998e 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -2239,7 +2239,6 @@
                                            MutableArrayRef<TypeLoc>(),
                                            /*generics*/ nullptr,
                                            Context.TheBuiltinModule);
-  SwiftRootClass->computeType();
   SwiftRootClass->setIsObjC(Context.LangOpts.EnableObjCInterop);
   SwiftRootClass->getAttrs().add(ObjCAttr::createNullary(Context, objcName,
     /*isNameImplicit=*/true));
diff --git a/lib/IRGen/GenInit.cpp b/lib/IRGen/GenInit.cpp
index 72d5a66..a0f01da 100644
--- a/lib/IRGen/GenInit.cpp
+++ b/lib/IRGen/GenInit.cpp
@@ -89,7 +89,7 @@
   assert(!hasBeenCleared() && "destroying a set that's been cleared?");
 
   // Deallocate all the temporaries.
-  for (auto &temporary : reversed(Stack)) {
+  for (auto &temporary : llvm::reverse(Stack)) {
     temporary.destroy(IGF);
   }
 }
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index 91d40d3..8419da7 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -733,7 +733,6 @@
         NoLoc, NoLoc, IGM.Context.getIdentifier(ArchetypeName), NoLoc,
         /*genericparams*/ nullptr, IGM.Context.TheBuiltinModule);
     Entry->setUnderlyingType(IGM.Context.TheRawPointerType);
-    Entry->computeType();
     return Entry;
   }
 
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 6e6bbff..f2a780f 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -1376,10 +1376,11 @@
 
   auto &ctx = pass.F->getModule().getASTContext();
   auto var = new (ctx) ParamDecl(
-      ParamDecl::Specifier::InOut, SourceLoc(), SourceLoc(),
+      SourceLoc(), SourceLoc(),
       ctx.getIdentifier("$return_value"), SourceLoc(),
       ctx.getIdentifier("$return_value"),
       pass.F->getDeclContext());
+  var->setSpecifier(ParamSpecifier::InOut);
   pass.F->begin()->insertFunctionArgument(
       0, newResultStorageType.getAddressType(), ValueOwnershipKind::Any, var);
 }
@@ -1426,6 +1427,20 @@
   }
 }
 
+static bool containsFunctionType(CanType ty) {
+  if (auto tuple = dyn_cast<TupleType>(ty)) {
+    for (auto elt : tuple.getElementTypes()) {
+      if (containsFunctionType(elt))
+        return true;
+    }
+    return false;
+  }
+  if (auto optionalType = ty.getOptionalObjectType()) {
+    return containsFunctionType(optionalType);
+  }
+  return isa<SILFunctionType>(ty);
+}
+
 void LoadableStorageAllocation::convertApplyResults() {
   for (auto &BB : *pass.F) {
     for (auto &II : BB) {
@@ -1450,16 +1465,7 @@
         auto numFuncTy = llvm::count_if(origSILFunctionType->getResults(),
             [](const SILResultInfo &origResult) {
               auto resultStorageTy = origResult.getSILStorageType();
-              // Check if it is a function type
-              if (resultStorageTy.is<SILFunctionType>()) {
-                return true;
-              }
-              // Check if it is an optional function type
-              auto optionalType = resultStorageTy.getOptionalObjectType();
-              if (optionalType && optionalType.is<SILFunctionType>()) {
-                return true;
-              }
-              return false;
+              return containsFunctionType(resultStorageTy.getASTType());
             });
         assert(numFuncTy != 0 &&
                "Expected a SILFunctionType inside the result Type");
diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp
index f01b7e6..5d43692 100644
--- a/lib/Index/Index.cpp
+++ b/lib/Index/Index.cpp
@@ -183,7 +183,7 @@
           if (ide::printExtensionUSR(ExtD, OS))
             return true;
         } else {
-          if (ide::printDeclUSR(D, OS))
+          if (ide::printValueDeclUSR(D, OS))
             return true;
         }
         result.USR = stringStorage.copyString(OS.str());
diff --git a/lib/LLVMPasses/LLVMInlineTree.cpp b/lib/LLVMPasses/LLVMInlineTree.cpp
index 2854c72..79a3502 100644
--- a/lib/LLVMPasses/LLVMInlineTree.cpp
+++ b/lib/LLVMPasses/LLVMInlineTree.cpp
@@ -224,7 +224,7 @@
       }
       Node *Nd = nullptr;
       DILocation *PrevDL = nullptr;
-      for (DILocation *DL : reversed(InlineChain)) {
+      for (DILocation *DL : llvm::reverse(InlineChain)) {
         DILocalScope *Sc = DL->getScope();
         DISubprogram *SP = Sc->getSubprogram();
         assert(SP);
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index 3cbd8a5..38535f8 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -73,7 +73,7 @@
 
     for (auto *Param: *Parent->getParameters()) {
       if (!--NextIndex) {
-        return findChild(Param->getTypeLoc());
+        return findChild(Param->getTypeRepr());
       }
     }
     llvm_unreachable("child index out of bounds");
@@ -291,7 +291,7 @@
     auto addDiffItems = [&](ValueDecl *VD) {
       llvm::SmallString<64> Buffer;
       llvm::raw_svector_ostream OS(Buffer);
-      if (swift::ide::printDeclUSR(VD, OS))
+      if (swift::ide::printValueDeclUSR(VD, OS))
         return;
       auto Items = DiffStore.getDiffItems(Buffer.str());
       results.insert(results.end(), Items.begin(), Items.end());
@@ -1384,7 +1384,7 @@
     auto *OD = AFD->getOverriddenDecl();
     llvm::SmallString<64> Buffer;
     llvm::raw_svector_ostream OS(Buffer);
-    if (swift::ide::printDeclUSR(OD, OS))
+    if (swift::ide::printValueDeclUSR(OD, OS))
       return SourceLoc();
     return OverridingRemoveNames.find(OS.str()) == OverridingRemoveNames.end() ?
       SourceLoc() : OverrideLoc;
@@ -1406,7 +1406,7 @@
           llvm::SmallString<64> Buffer;
           llvm::raw_svector_ostream OS(Buffer);
           auto *RD = DSC->getFn()->getReferencedDecl().getDecl();
-          if (swift::ide::printDeclUSR(RD, OS))
+          if (swift::ide::printValueDeclUSR(RD, OS))
             return false;
           return USRs.find(OS.str()) != USRs.end();
         }
diff --git a/lib/Parse/ASTGen.cpp b/lib/Parse/ASTGen.cpp
index a045685..dc8c358 100644
--- a/lib/Parse/ASTGen.cpp
+++ b/lib/Parse/ASTGen.cpp
@@ -63,7 +63,7 @@
   if (auto firstTok = D.getFirstToken()) {
     auto declLoc = advanceLocBegin(Loc, *firstTok);
     if (hasDeclAttributes(declLoc))
-      return getDeclAttributes(declLoc);
+      return takeDeclAttributes(declLoc);
   }
   return DeclAttributes();
 }
@@ -232,12 +232,28 @@
 Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
   Expr *result = nullptr;
 
+  auto exprLoc = advanceLocBegin(Loc, E);
+  if (hasExpr(exprLoc))
+    return takeExpr(exprLoc);
+
   if (auto identifierExpr = E.getAs<IdentifierExprSyntax>())
     result = generate(*identifierExpr, Loc);
+  else if (auto superRefExpr = E.getAs<SuperRefExprSyntax>())
+    result = generate(*superRefExpr, Loc);
   else if (auto specializeExpr = E.getAs<SpecializeExprSyntax>())
     result = generate(*specializeExpr, Loc);
   else if (auto editorPlaceHolderExpr = E.getAs<EditorPlaceholderExprSyntax>())
     result = generate(*editorPlaceHolderExpr, Loc);
+  else if (auto arrayExpr = E.getAs<ArrayExprSyntax>())
+    result = generate(*arrayExpr, Loc);
+  else if (auto dictionaryExpr = E.getAs<DictionaryExprSyntax>())
+    result = generate(*dictionaryExpr, Loc);
+  else if (auto tupleExpr = E.getAs<TupleExprSyntax>())
+    result = generate(*tupleExpr, Loc);
+  else if (auto callExpr  = E.getAs<FunctionCallExprSyntax>())
+    result = generate(*callExpr, Loc);
+  else if (auto memberExpr  = E.getAs<MemberAccessExprSyntax>())
+    result = generate(*memberExpr, Loc);
   else if (auto integerLiteralExpr = E.getAs<IntegerLiteralExprSyntax>())
     result = generate(*integerLiteralExpr, Loc);
   else if (auto floatLiteralExpr = E.getAs<FloatLiteralExprSyntax>())
@@ -256,8 +272,20 @@
     result = generate(*poundFunctionExpr, Loc);
   else if (auto poundDsohandleExpr = E.getAs<PoundDsohandleExprSyntax>())
     result = generate(*poundDsohandleExpr, Loc);
-  else
+  else if (auto objcKeyPathExpr = E.getAs<ObjcKeyPathExprSyntax>())
+    result = generate(*objcKeyPathExpr, Loc);
+  else if (auto objectLiteralExpr = E.getAs<ObjectLiteralExprSyntax>())
+    result = generate(*objectLiteralExpr, Loc);
+  else if (auto completionExpr = E.getAs<CodeCompletionExprSyntax>())
+    result = generate(*completionExpr, Loc);
+  else if (auto unknownExpr = E.getAs<UnknownExprSyntax>())
+    result = generate(*unknownExpr, Loc);
+  else {
+#ifndef NDEBUG
+    E.dump();
     llvm_unreachable("unsupported expression");
+#endif
+  }
 
   return result;
 }
@@ -366,6 +394,39 @@
   return new (Context) DeclRefExpr(D, nameLoc, /*implicit=*/false);
 }
 
+static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
+                                                   DeclContext *DC,
+                                                   SourceLoc Loc) {
+  auto *methodContext = DC->getInnermostMethodContext();
+  if (!methodContext) {
+    P.diagnose(Loc, diag::super_not_in_class_method);
+    return nullptr;
+  }
+
+  // Do an actual lookup for 'self' in case it shows up in a capture list.
+  auto *methodSelf = methodContext->getImplicitSelfDecl();
+  auto *lookupSelf = P.lookupInScope(P.Context.Id_self);
+  if (lookupSelf && lookupSelf != methodSelf) {
+    // FIXME: This is the wrong diagnostic for if someone manually declares a
+    // variable named 'self' using backticks.
+    P.diagnose(Loc, diag::super_in_closure_with_capture);
+    P.diagnose(lookupSelf->getLoc(), diag::super_in_closure_with_capture_here);
+    return nullptr;
+  }
+
+  return methodSelf;
+}
+
+Expr *ASTGen::generate(const SuperRefExprSyntax &E, const SourceLoc Loc) {
+  auto superLoc = advanceLocBegin(Loc, E.getSuperKeyword());
+  VarDecl *selfDecl =
+      getImplicitSelfDeclForSuperContext(P, P.CurDeclContext, superLoc);
+  if (!selfDecl)
+    return new (Context) ErrorExpr(superLoc);
+
+  return new (Context) SuperRefExpr(selfDecl, superLoc, /*Implicit=*/false);
+}
+
 Expr *ASTGen::generate(const EditorPlaceholderExprSyntax &E, const SourceLoc Loc) {
   assert(!E.getIdentifier().isMissing());
 
@@ -389,6 +450,221 @@
                                           rAngleLoc);
 }
 
+/// validateCollectionElement - Check if a given collection element is valid.
+///
+/// At the moment, this checks whether a given collection element is a subscript
+/// expression and whether we're subscripting into an array. If we are, then it
+/// we emit a diagnostic in case it was not something that the user was
+/// expecting.
+///
+/// For example: `let array [ [0, 1] [42] ]`
+void ASTGen::validateCollectionElement(Expr *elementExpr) {
+  if (!elementExpr)
+    return;
+
+  if (!isa<SubscriptExpr>(elementExpr))
+    return;
+
+  auto subscriptExpr = cast<SubscriptExpr>(elementExpr);
+  if (!isa<ArrayExpr>(subscriptExpr->getBase()))
+    return;
+
+  auto arrayExpr = cast<ArrayExpr>(subscriptExpr->getBase());
+
+  auto startLocOfSubscript = subscriptExpr->getIndex()->getStartLoc();
+  auto endLocOfArray = arrayExpr->getEndLoc();
+
+  auto locForEndOfTokenArray =
+      Lexer::getLocForEndOfToken(Context.SourceMgr, endLocOfArray);
+
+  if (locForEndOfTokenArray != startLocOfSubscript) {
+    auto subscriptLoc = subscriptExpr->getLoc();
+    P.diagnose(subscriptLoc, diag::subscript_array_element)
+        .highlight(subscriptExpr->getSourceRange());
+    P.diagnose(subscriptLoc, diag::subscript_array_element_fix_it_add_comma)
+        .fixItInsertAfter(endLocOfArray, ",");
+    P.diagnose(subscriptLoc, diag::subscript_array_element_fix_it_remove_space)
+        .fixItRemoveChars(locForEndOfTokenArray, startLocOfSubscript);
+  }
+}
+
+Expr *ASTGen::generate(const ArrayExprSyntax &E, const SourceLoc Loc) {
+  SmallVector<Expr *, 8> elements;
+  SmallVector<SourceLoc, 8> commaLocs;
+  elements.reserve(E.getElements().size());
+  for (auto elemSyntax : E.getElements()) {
+    if (auto elemAST = generate(elemSyntax.getExpression(), Loc)) {
+      validateCollectionElement(elemAST);
+      elements.push_back(elemAST);
+    }
+    if (auto comma = elemSyntax.getTrailingComma())
+      commaLocs.push_back(advanceLocBegin(Loc, *comma));
+  }
+
+  // Don't bother to create expression if any expressions aren't parsed.
+  if (elements.empty() && !E.getElements().empty())
+    return nullptr;
+
+  auto LSquareLoc = advanceLocBegin(Loc, E);
+  auto RSquareLoc = advanceLocEnd(Loc, E);
+  return ArrayExpr::create(Context, LSquareLoc, elements, commaLocs,
+                           RSquareLoc);
+}
+
+Expr *ASTGen::generate(const DictionaryExprSyntax &E, const SourceLoc Loc) {
+  SmallVector<Expr *, 8> elements;
+  SmallVector<SourceLoc, 8> commaLocs;
+  if (auto contents = E.getContent().getAs<DictionaryElementListSyntax>()) {
+    elements.reserve(contents->size());
+    for (auto elemSyntax : *contents) {
+      if (auto key = generate(elemSyntax.getKeyExpression(), Loc)) {
+        auto val = generate(elemSyntax.getValueExpression(), Loc);
+        if (!val)
+          val = new (Context) ErrorExpr(advanceLocEnd(Loc, elemSyntax));
+        auto elemAST = TupleExpr::createImplicit(Context, {key, val}, {});
+        elements.push_back(elemAST);
+      }
+      if (auto comma = elemSyntax.getTrailingComma())
+        commaLocs.push_back(advanceLocBegin(Loc, *comma));
+    }
+    // Don't bother to create expression if any expressions aren't parsed.
+    if (elements.empty() && !contents->empty())
+      return nullptr;
+  }
+
+  auto LSquareLoc = advanceLocBegin(Loc, E);
+  auto RSquareLoc = advanceLocEnd(Loc, E);
+  return DictionaryExpr::create(Context, LSquareLoc, elements, commaLocs,
+                                RSquareLoc);
+}
+
+Expr *ASTGen::generate(const TupleExprSyntax &E, const SourceLoc Loc) {
+  SmallVector<Expr *, 2> exprs;
+  SmallVector<Identifier, 2> exprLabels;
+  SmallVector<SourceLoc, 2> exprLabelLocs;
+  generateExprTupleElementList(E.getElementList(), Loc,
+  /*isForCallArguments=*/false, exprs, exprLabels,
+                               exprLabelLocs);
+
+  SourceLoc leftLoc = advanceLocBegin(Loc, E.getLeftParen());
+  SourceLoc rightLoc = advanceLocEnd(Loc, E);
+
+  // A tuple with a single, unlabeled element is just parentheses.
+  if (exprs.size() == 1 && exprLabels.empty()) {
+    return new (Context) ParenExpr(leftLoc, exprs[0], rightLoc,
+                                   /*hasTrailingClosure=*/false);
+  }
+
+  return TupleExpr::create(Context, leftLoc, exprs, exprLabels, exprLabelLocs,
+                           rightLoc, /*HasTrailingClosure=*/false,
+                           /*Implicit=*/false);
+}
+
+void ASTGen::generateExprTupleElementList(const TupleExprElementListSyntax &elements,
+                                          const SourceLoc Loc, bool isForCallArguments,
+                                          SmallVectorImpl<Expr *> &exprs,
+                                  SmallVectorImpl<Identifier> &exprLabels,
+                                  SmallVectorImpl<SourceLoc> &exprLabelLocs) {
+  auto isFirst = true;
+  for (auto elem : elements) {
+    auto *subExpr = generate(elem.getExpression(), Loc);
+    if (!subExpr)
+      continue;
+
+    // Handle call arguments specially because it may need argument labels.
+    if (P.CodeCompletion && isForCallArguments && !elem.getLabel())
+      if (auto CCExpr = elem.getExpression().getAs<CodeCompletionExprSyntax>())
+        if (!CCExpr->getBase() && !CCExpr->getPeriodOrParen())
+          P.CodeCompletion->completeCallArg(cast<CodeCompletionExpr>(subExpr),
+                                              isFirst);
+    isFirst = false;
+
+    Identifier fieldName;
+    SourceLoc fieldNameLoc;
+    if (auto label = elem.getLabel()) {
+      fieldNameLoc = advanceLocBegin(Loc, *label);
+      if (label->getTokenKind() == tok::identifier)
+        fieldName = Context.getIdentifier(label->getIdentifierText());
+    }
+
+    // Don't populate label vectors unless we see at least one label.
+    if (!exprLabels.empty()) {
+      exprLabels.push_back(fieldName);
+      exprLabelLocs.push_back(fieldNameLoc);
+    } else if (fieldNameLoc.isValid()) {
+      exprLabels.resize(exprs.size());
+      exprLabelLocs.resize(exprs.size());
+      exprLabels.push_back(fieldName);
+      exprLabelLocs.push_back(fieldNameLoc);
+    }
+    exprs.push_back(subExpr);
+  }
+  assert((exprLabels.size() == 0 || exprs.size() == exprLabels.size()) &&
+         exprLabels.size() == exprLabelLocs.size());
+}
+
+Expr *ASTGen::generate(const FunctionCallExprSyntax &E, const SourceLoc Loc) {
+  auto callee = E.getCalledExpression();
+
+  SourceLoc LParenLoc, RParenLoc;
+  SmallVector<Expr *, 2> args;
+  SmallVector<Identifier, 2> argLabels;
+  SmallVector<SourceLoc, 2> argLabelLocs;
+  generateExprTupleElementList(E.getArgumentList(), Loc,
+                               /*isForCallArguments=*/true, args, argLabels,
+                               argLabelLocs);
+  Expr *trailingClosure = nullptr;
+  if (auto CE = E.getTrailingClosure())
+    trailingClosure = generate(*CE, Loc);
+  if (auto LParen = E.getLeftParen()) {
+    LParenLoc = advanceLocBegin(Loc, *LParen);
+    if (auto RParen = E.getRightParen())
+      RParenLoc = advanceLocBegin(Loc, *RParen);
+    else
+      RParenLoc = advanceLocEnd(Loc, E.getArgumentList());
+  }
+
+  if (auto memberAccess = callee.getAs<MemberAccessExprSyntax>()) {
+    if (!memberAccess->getBase()) {
+      // This is UnresolvedMemberExpr with call arguments.
+      if (memberAccess->getName().isMissing())
+        return nullptr;
+
+      SourceLoc dotLoc = advanceLocBegin(Loc, memberAccess->getDot());
+      DeclName name;
+      DeclNameLoc nameLoc;
+      std::tie(name, nameLoc) = generateUnqualifiedDeclName(
+          memberAccess->getName(), memberAccess->getDeclNameArguments(), Loc);
+
+      return UnresolvedMemberExpr::create(
+          Context, dotLoc, nameLoc, name, LParenLoc, args, argLabels,
+          argLabelLocs, RParenLoc, trailingClosure,
+          /*implicit=*/false);
+    }
+  }
+  llvm_unreachable("call expression not implemented");
+  return nullptr;
+}
+
+Expr *ASTGen::generate(const MemberAccessExprSyntax &E, const SourceLoc Loc) {
+  if (!E.getBase()) {
+    // This is an UnresolvedMemberExpr.
+    if (E.getName().isMissing())
+      return nullptr;
+
+    DeclName name;
+    DeclNameLoc nameLoc;
+    std::tie(name, nameLoc) =
+        generateUnqualifiedDeclName(E.getName(), E.getDeclNameArguments(), Loc);
+    SourceLoc dotLoc = advanceLocBegin(Loc, E.getDot());
+
+    return UnresolvedMemberExpr::create(Context, dotLoc, nameLoc, name,
+                                        /*implicit=*/false);
+  }
+  llvm_unreachable("member access expression not implemented");
+  return nullptr;
+}
+
 Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr,
                        const SourceLoc Loc) {
   auto Digits = Expr.getDigits();
@@ -442,6 +718,109 @@
                                                   Loc);
 }
 
+Expr *ASTGen::generate(const ObjcKeyPathExprSyntax &E, const SourceLoc Loc) {
+  SmallVector<KeyPathExpr::Component, 4> components;
+  if (E.getLeftParen().isMissing())
+    return nullptr;
+
+  for (auto piece : E.getName()) {
+    DeclName name;
+    DeclNameLoc nameLoc;
+    std::tie(name, nameLoc) =
+        generateUnqualifiedDeclName(piece.getName(),
+                                    piece.getDeclNameArguments(), Loc);
+    auto component = KeyPathExpr::Component::forUnresolvedProperty(name,
+                                                      nameLoc.getBaseNameLoc());
+    components.push_back(component);
+  }
+  auto keywordLoc = advanceLocBegin(Loc, E.getKeyPath());
+  auto LParenLoc = advanceLocBegin(Loc, E.getLeftParen());
+  auto RParenLoc = advanceLocEnd(Loc, E);
+
+  if (components.empty())
+    return new (Context) ErrorExpr(SourceRange(keywordLoc, RParenLoc));
+
+  return new (Context) KeyPathExpr(
+      Context, keywordLoc, LParenLoc, components, RParenLoc);
+}
+
+Expr *ASTGen::generate(const ObjectLiteralExprSyntax &E, const SourceLoc Loc) {
+  ObjectLiteralExpr::LiteralKind kind;
+  switch (E.getIdentifier().getTokenKind()) {
+#define POUND_OBJECT_LITERAL(Name, Desc, Proto)                                \
+  case tok::pound_##Name:                                                      \
+    kind = ObjectLiteralExpr::Name;                                            \
+    break;
+#include "swift/Syntax/TokenKinds.def"
+  default:
+    llvm_unreachable("unknown token kind for object literal expression");
+  }
+
+  SmallVector<Expr *, 2> args;
+  SmallVector<Identifier, 2> argLabels;
+  SmallVector<SourceLoc, 2> argLabelLocs;
+  generateExprTupleElementList(E.getArguments(), Loc, true, args, argLabels,
+                               argLabelLocs);
+
+  ClosureExpr *trailingClosure = nullptr;
+  if (auto CE = E.getTrailingClosure())
+    trailingClosure = dyn_cast_or_null<ClosureExpr>(generate(*CE, Loc));
+
+  if (E.getLeftParen().isMissing() || E.getRightParen().isMissing())
+    return nullptr;
+
+  SourceLoc poundLoc = advanceLocBegin(Loc, E.getIdentifier());
+  SourceLoc LParenLoc = advanceLocBegin(Loc, E.getLeftParen());
+  SourceLoc RParenLoc = advanceLocBegin(Loc, E.getRightParen());
+
+  return ObjectLiteralExpr::create(Context, poundLoc, kind, LParenLoc, args,
+                                   argLabels, argLabelLocs, RParenLoc,
+                                   trailingClosure, /*implicit=*/false);
+}
+
+Expr *ASTGen::generate(const CodeCompletionExprSyntax &E, const SourceLoc Loc) {
+  if (!E.getBase()) {
+    if (auto punctuator = E.getPeriodOrParen()) {
+      // '.' <cc-token>
+      if (punctuator->getTokenKind() == tok::period ||
+          punctuator->getTokenKind() == tok::period_prefix) {
+        auto ccLoc = advanceLocBegin(Loc, E.getCodeCompletionToken());
+        auto dotLoc = advanceLocBegin(Loc, *punctuator);
+        
+        auto CCE = new (Context) CodeCompletionExpr(ccLoc);
+        if (P.CodeCompletion)
+          P.CodeCompletion->completeUnresolvedMember(CCE, dotLoc);
+        return CCE;
+      }
+    } else {
+      llvm_unreachable("'(' <cc-token> is not suppported");
+    }
+  } else {
+    if (auto objcKeyPathExpr = E.getBase()->getAs<ObjcKeyPathExprSyntax>()) {
+      // #keyPath(<cc-token>
+      // #keyPath(some <cc-token>
+      // #keyPath(some.<cc-token>
+      auto expr = generate(*objcKeyPathExpr, Loc);
+      if (P.CodeCompletion) {
+        SourceLoc dotLoc;
+        if (!expr || isa<ErrorExpr>(expr)) {
+          P.CodeCompletion->completeExprKeyPath(nullptr, SourceLoc());
+        } else {
+          auto namePieces = objcKeyPathExpr->getName();
+          if (!namePieces.empty())
+            if (auto dot = namePieces[namePieces.getNumChildren() - 1].getDot())
+              dotLoc = advanceLocBegin(Loc, *dot);
+          P.CodeCompletion->completeExprKeyPath(cast<KeyPathExpr>(expr), dotLoc);
+        }
+      }
+      return expr;
+    }
+    // TODO: implement
+  }
+  llvm_unreachable("code completion expression not implemented");
+  return nullptr;
+}
+
 Expr *ASTGen::generate(const UnknownExprSyntax &Expr, const SourceLoc Loc) {
   if (Expr.getNumChildren() == 1 && Expr.getChild(0)->isToken()) {
     Syntax Token = *Expr.getChild(0);
@@ -547,17 +926,21 @@
                                      const TupleTypeElementListSyntax &Elements,
                                      const TokenSyntax &RParen,
                                      const SourceLoc Loc, bool IsFunction) {
-  auto LPLoc = generate(LParen, Loc);
-  auto RPLoc = generate(RParen, Loc);
+  auto LPLoc = advanceLocBegin(Loc, LParen);
+  auto RPLoc = advanceLocEnd(Loc, RParen);
 
   SmallVector<TupleTypeReprElement, 4> TupleElements;
 
   SourceLoc EllipsisLoc;
-  unsigned EllipsisIdx = Elements.size();
+  unsigned EllipsisIdx;
 
-  for (unsigned i = 0; i < Elements.getNumChildren(); i++) {
-    auto Element = Elements.getChild(i)->castTo<TupleTypeElementSyntax>();
+  for (unsigned i = 0; i < Elements.size(); i++) {
+    auto Element = Elements[i];
     TupleTypeReprElement ElementAST;
+    ElementAST.Type = generate(Element.getType(), Loc);
+    if (!ElementAST.Type)
+      continue;
+
     if (auto Name = Element.getName()) {
       ElementAST.NameLoc = generate(*Name, Loc);
       ElementAST.Name = Name->getText() == "_"
@@ -579,7 +962,7 @@
         ElementAST.NameLoc = ElementAST.SecondNameLoc;
       }
     }
-    ElementAST.Type = generate(Element.getType(), Loc);
+
     if (auto InOut = Element.getInOut()) {
       // don't apply multiple inout specifiers to a type: that's invalid and was
       // already reported in the parser, handle gracefully
@@ -591,13 +974,17 @@
     }
     if (auto Comma = Element.getTrailingComma())
       ElementAST.TrailingCommaLoc = generate(*Comma, Loc);
+
     if (auto Ellipsis = Element.getEllipsis()) {
-      EllipsisLoc = generate(*Ellipsis, Loc);
-      if (EllipsisIdx == Elements.size())
+      if (EllipsisLoc.isInvalid()) {
+        EllipsisLoc = generate(*Ellipsis, Loc);
         EllipsisIdx = i;
+      }
     }
     TupleElements.push_back(ElementAST);
   }
+  if (EllipsisLoc.isInvalid())
+    EllipsisIdx = TupleElements.size();
 
   return TupleTypeRepr::create(Context, TupleElements, {LPLoc, RPLoc},
                                EllipsisLoc, EllipsisIdx);
@@ -864,14 +1251,8 @@
   auto ColonLoc = advanceLocBegin(Loc, Type.getColon());
 
   SourceLoc LBracketLoc, RBracketLoc;
-  if (Type.getLeftSquareBracket().isPresent())
-    LBracketLoc = advanceLocBegin(Loc, Type.getLeftSquareBracket());
-  else
-    LBracketLoc = advanceLocBegin(Loc, *Type.getFirstToken());
-  if (Type.getRightSquareBracket().isPresent())
-    RBracketLoc = advanceLocBegin(Loc, Type.getRightSquareBracket());
-  else
-    RBracketLoc = advanceLocBegin(Loc, *Type.getLastToken());
+  LBracketLoc = advanceLocBegin(Loc, Type);
+  RBracketLoc = advanceLocEnd(Loc, Type);
   SourceRange Range{LBracketLoc, RBracketLoc};
   return new (Context) DictionaryTypeRepr(KeyType, ValueType, ColonLoc, Range);
 }
@@ -881,14 +1262,8 @@
   if (!ElementType)
     return nullptr;
   SourceLoc LBracketLoc, RBracketLoc;
-  if (Type.getLeftSquareBracket().isPresent())
-    LBracketLoc = advanceLocBegin(Loc, Type.getLeftSquareBracket());
-  else
-    LBracketLoc = advanceLocBegin(Loc, *Type.getFirstToken());
-  if (Type.getRightSquareBracket().isPresent())
-    RBracketLoc = advanceLocBegin(Loc, Type.getRightSquareBracket());
-  else
-    RBracketLoc = advanceLocBegin(Loc, *Type.getLastToken());
+  LBracketLoc = advanceLocBegin(Loc, Type);
+  RBracketLoc = advanceLocEnd(Loc, Type);
   return new (Context) ArrayTypeRepr(ElementType, {LBracketLoc, RBracketLoc});
 }
 
@@ -1054,24 +1429,6 @@
     }
   }
 
-  // Create empty TupleTypeRepr for types starting with `(`.
-  if (ChildrenCount >= 1) {
-    auto LParen = Type.getChild(0)->getAs<TokenSyntax>();
-    if (LParen && LParen->getTokenKind() == tok::l_paren) {
-      // generate child 'TypeSyntax' anyway to trigger the side effects e.g.
-      // code-completion.
-      for (size_t i = 1; i != ChildrenCount; ++i) {
-        auto elem = *Type.getChild(i);
-        if (auto ty = elem.getAs<TypeSyntax>())
-          (void)generate(*ty, Loc);
-      }
-      auto LParenLoc = advanceLocBegin(Loc, *LParen);
-      auto EndLoc =
-          advanceLocBegin(Loc, *Type.getChild(Type.getNumChildren() - 1));
-      return TupleTypeRepr::createEmpty(Context, {LParenLoc, EndLoc});
-    }
-  }
-
   // generate child 'TypeSyntax' anyway to trigger the side effects e.g.
   // code-completion.
   for (size_t i = 0; i != ChildrenCount; ++i) {
@@ -1088,8 +1445,8 @@
 ASTGen::generate(const GenericArgumentClauseSyntax &clause, const SourceLoc Loc,
                  SourceLoc &lAngleLoc, SourceLoc &rAngleLoc,
                  SmallVectorImpl<TypeRepr *> &args) {
-  lAngleLoc = advanceLocBegin(Loc, clause.getLeftAngleBracket());
-  rAngleLoc = advanceLocBegin(Loc, clause.getRightAngleBracket());
+  lAngleLoc = advanceLocBegin(Loc, clause);
+  rAngleLoc = advanceLocEnd(Loc, clause);
 
   assert(args.empty());
   for (auto Arg : clause.getArguments()) {
@@ -1185,8 +1542,8 @@
       whereLoc = advanceLocBegin(Loc, whereClause->getWhereKeyword());
   }
 
-  auto lAngleLoc = advanceLocBegin(Loc, clause.getLeftAngleBracket());
-  auto rAngleLoc = advanceLocBegin(Loc, clause.getRightAngleBracket());
+  auto lAngleLoc = advanceLocBegin(Loc, clause);
+  auto rAngleLoc = advanceLocEnd(Loc, clause);
   return GenericParamList::create(Context, lAngleLoc, params, whereLoc,
                                   requirements, rAngleLoc);
 }
@@ -1276,6 +1633,22 @@
   return Loc.getAdvancedLoc(Node.getAbsolutePosition().getOffset());
 }
 
+SourceLoc ASTGen::advanceLocEnd(const SourceLoc &Loc, const Syntax &Node) {
+  if (!Node.isMissing()) {
+    // NOTE: We cannot use 'getLastToken()' because it doesn't take string
+    // literal expressions into account.
+    if (Node.isToken() || Node.is<StringLiteralExprSyntax>())
+      return advanceLocBegin(Loc, Node);
+    for (size_t I = Node.getNumChildren(); I != 0; --I)
+      if (auto Child = Node.getChild(I - 1))
+        return advanceLocEnd(Loc, *Child);
+  }
+  if (auto Prev = Node.getPreviousNode())
+    return advanceLocEnd(Loc, *Prev);
+  assert(false && "No tokens in tree?");
+  return Loc;
+}
+
 StringRef ASTGen::copyAndStripUnderscores(StringRef Orig) {
   return copyAndStripUnderscores(Orig, Context);
 }
@@ -1329,14 +1702,36 @@
   return Found != TypeCache.end() ? Found->second : nullptr;
 }
 
+void ASTGen::addExpr(Expr *E, const SourceLoc Loc) {
+  assert(!hasExpr(Loc));
+  Exprs[Loc] = E;
+}
+
+bool ASTGen::hasExpr(const SourceLoc Loc) const {
+  return Exprs.find(Loc) != Exprs.end();
+}
+
+Expr *ASTGen::takeExpr(const SourceLoc Loc) {
+  auto I = Exprs.find(Loc);
+  assert(I != Exprs.end());
+  auto expr = I->second;
+  Exprs.erase(I);
+  return expr;
+}
+
 void ASTGen::addDeclAttributes(DeclAttributes attrs, SourceLoc Loc) {
-  ParsedDeclAttrs.insert({Loc, attrs});
+  assert(!hasDeclAttributes(Loc));
+  ParsedDeclAttrs[Loc] = attrs;
 }
 
 bool ASTGen::hasDeclAttributes(SourceLoc Loc) const {
   return ParsedDeclAttrs.find(Loc) != ParsedDeclAttrs.end();
 }
 
-DeclAttributes ASTGen::getDeclAttributes(SourceLoc Loc) const {
-  return ParsedDeclAttrs.find(Loc)->second;
+DeclAttributes ASTGen::takeDeclAttributes(SourceLoc Loc) {
+  auto I = ParsedDeclAttrs.find(Loc);
+  assert(I != ParsedDeclAttrs.end());
+  auto attrs = I->second;
+  ParsedDeclAttrs.erase(I);
+  return attrs;
 }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5fac7bd..b80618c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2372,8 +2372,7 @@
         status |= parseExprList(tok::l_paren, tok::r_paren,
                                 /*isPostfix=*/false, /*isExprBasic=*/true,
                                 lParenLoc, args, argLabels, argLabelLocs,
-                                rParenLoc, trailingClosure,
-                                SyntaxKind::TupleExprElementList);
+                                rParenLoc, trailingClosure);
         assert(!trailingClosure && "Cannot parse a trailing closure here");
         hasInitializer = true;
       }
@@ -4929,8 +4928,7 @@
         // Clone the parameter.  Do not clone the parameter type;
         // this will be filled in by the type-checker.
         auto accessorParam =
-          new (P->Context) ParamDecl(storageParam->getSpecifier(),
-                                     storageParam->getSpecifierLoc(),
+          new (P->Context) ParamDecl(storageParam->getSpecifierLoc(),
                                      storageParam->getArgumentNameLoc(),
                                      storageParam->getArgumentName(),
                                      storageParam->getNameLoc(),
@@ -4992,14 +4990,12 @@
   }
 
   auto result = new (P.Context)
-      ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+      ParamDecl(SourceLoc(), SourceLoc(),
                 Identifier(), nameLoc, name, P.CurDeclContext);
+
   if (isNameImplicit)
     result->setImplicit();
 
-  // AST Walker shouldn't go into the type recursively.
-  result->setIsTypeLocImplicit(true);
-
   return result;
 }
 
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 512a2fd..2211027 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -14,6 +14,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ParseList.h"
 #include "swift/Parse/Parser.h"
 #include "swift/AST/DiagnosticsParse.h"
 #include "swift/AST/TypeRepr.h"
@@ -35,6 +36,19 @@
 using namespace swift;
 using namespace swift::syntax;
 
+ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExpressionSyntax(Diag<> ID) {
+  SourceLoc ExprLoc = Tok.getLoc();
+  SyntaxParsingContext ExprParsingContext(SyntaxContext,
+                                          SyntaxContextKind::Expr);
+  ExprParsingContext.setTransparent();
+  ParserResult<Expr> Result = parseExpr(ID);
+  if (auto ParsedExpr = ExprParsingContext.popIf<ParsedExprSyntax>()) {
+    Generator.addExpr(Result.getPtrOrNull(), ExprLoc);
+    return makeParsedResult(std::move(*ParsedExpr), Result.getStatus());
+  }
+  return Result.getStatus();
+}
+
 /// parseExpr
 ///
 ///   expr:
@@ -613,97 +627,79 @@
 ///   expr-keypath-objc:
 ///     '#keyPath' '(' unqualified-name ('.' unqualified-name) * ')'
 ///
-ParserResult<Expr> Parser::parseExprKeyPathObjC() {
-  SyntaxParsingContext ObjcKPCtx(SyntaxContext, SyntaxKind::ObjcKeyPathExpr);
+ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExprObjcKeyPathSyntax() {
+  ParsedObjcKeyPathExprSyntaxBuilder builder(*SyntaxContext);
+  ParserStatus status;
+
   // Consume '#keyPath'.
-  SourceLoc keywordLoc = consumeToken(tok::pound_keyPath);
+  builder.useKeyPath(consumeTokenSyntax(tok::pound_keyPath));
 
   // Parse the leading '('.
   if (!Tok.is(tok::l_paren)) {
     diagnose(Tok, diag::expr_keypath_expected_lparen);
-    return makeParserError();
+    return makeParsedError(builder.build());
   }
-  SourceLoc lParenLoc = consumeToken(tok::l_paren);
-
-  SmallVector<KeyPathExpr::Component, 4> components;
-  /// Handler for code completion.
-  auto handleCodeCompletion = [&](SourceLoc DotLoc) -> ParserResult<Expr> {
-    KeyPathExpr *expr = nullptr;
-    if (!components.empty()) {
-      expr = new (Context)
-          KeyPathExpr(Context, keywordLoc, lParenLoc, components, Tok.getLoc());
-    }
-
-    if (CodeCompletion)
-      CodeCompletion->completeExprKeyPath(expr, DotLoc);
-
-    // Eat the code completion token because we handled it.
-    consumeToken(tok::code_complete);
-    return makeParserCodeCompletionResult(expr);
-  };
+  auto LParenLoc = Tok.getLoc();
+  builder.useLeftParen(consumeTokenSyntax(tok::l_paren));
 
   // Parse the sequence of unqualified-names.
-  ParserStatus status;
-  SourceLoc LastDotLoc;
-  while (true) {
-    SyntaxParsingContext NamePieceCtx(SyntaxContext, SyntaxKind::ObjcNamePiece);
-    // Handle code completion.
-    if (Tok.is(tok::code_complete))
-      return handleCodeCompletion(LastDotLoc);
-
-    // Parse the next name.
-    DeclNameLoc nameLoc;
-    bool afterDot = !components.empty();
-    auto name = parseUnqualifiedDeclName(
-                  afterDot, nameLoc, 
-                  diag::expr_keypath_expected_property_or_type);
-    if (!name) {
-      status.setIsParseError();
+  bool isFirst = true;
+  bool hasNext = true;
+  do {
+    // Parse the next name
+    Optional<ParsedTokenSyntax> identTok;
+    Optional<ParsedDeclNameArgumentsSyntax> declNameArgs;
+    status |= parseUnqualifiedDeclNameSyntax(
+        identTok, declNameArgs, /*afterDot=*/!isFirst,
+        diag::expr_keypath_expected_property_or_type);
+    isFirst = false;
+    if (status.isError())
       break;
-    }
 
-    // Record the name we parsed.
-    auto component = KeyPathExpr::Component::forUnresolvedProperty(name,
-                                                      nameLoc.getBaseNameLoc());
-    components.push_back(component);
+    ParsedObjcNamePieceSyntaxBuilder elemBuilder(*SyntaxContext);
 
-    // Handle code completion.
-    if (Tok.is(tok::code_complete))
-      return handleCodeCompletion(SourceLoc());
+    elemBuilder.useName(std::move(*identTok));
+    if (declNameArgs)
+      elemBuilder.useDeclNameArguments(std::move(*declNameArgs));
 
-    // Parse the next period to continue the path.
-    if (consumeIf(tok::period, LastDotLoc))
-      continue;
+    hasNext = Tok.is(tok::period);
+    if (hasNext)
+      elemBuilder.useDot(consumeTokenSyntax(tok::period));
+    builder.addNameMember(elemBuilder.build());
+  } while (hasNext);
 
-    break;
+  if (Tok.is(tok::code_complete)) {
+    return makeParsedCodeCompletion(
+        ParsedSyntaxRecorder::makeCodeCompletionExpr(
+            builder.build(), None, consumeTokenSyntax(tok::code_complete),
+            *SyntaxContext));
   }
 
-  // Collect all name pieces to an objc name.
-  SyntaxContext->collectNodesInPlace(SyntaxKind::ObjcName);
+  if (status.isError()) {
+    while (!Tok.isAny(tok::r_paren, tok::eof, tok::r_brace, tok::pound_endif,
+                      tok::pound_else, tok::pound_elseif) &&
+           !isStartOfDecl() && !isStartOfStmt())
+      ignoreSingle();
+  }
 
   // Parse the closing ')'.
-  SourceLoc rParenLoc;
-  if (status.isError()) {
-    skipUntilDeclStmtRBrace(tok::r_paren);
-    if (Tok.is(tok::r_paren))
-      rParenLoc = consumeToken();
-    else
-      rParenLoc = PreviousLoc;
-  } else {
-    parseMatchingToken(tok::r_paren, rParenLoc,
-                       diag::expr_keypath_expected_rparen, lParenLoc);
-  }
+  auto RParen =
+      parseMatchingTokenSyntax(tok::r_paren, diag::expr_keypath_expected_rparen,
+                               LParenLoc, /*silenceDiag=*/status.isError());
+  status |= RParen.getStatus();
+  if (!RParen.isNull())
+    builder.useRightParen(RParen.get());
 
-  // If we cannot build a useful expression, just return an error
-  // expression.
-  if (components.empty() || status.isError()) {
-    return makeParserResult<Expr>(
-             new (Context) ErrorExpr(SourceRange(keywordLoc, rParenLoc)));
-  }
+  return makeParsedResult(builder.build(), status);
+}
 
-  // We're done: create the key-path expression.
-  return makeParserResult<Expr>(new (Context) KeyPathExpr(
-      Context, keywordLoc, lParenLoc, components, rParenLoc));
+ParserResult<Expr> Parser::parseExprKeyPathObjC() {
+  auto leadingLoc = leadingTriviaLoc();
+  auto parsed = parseExprObjcKeyPathSyntax();
+  SyntaxContext->addSyntax(parsed.get());
+  auto syntax = SyntaxContext->topNode<ExprSyntax>();
+  auto expr = Generator.generate(syntax, leadingLoc);
+  return makeParserResult(parsed.getStatus(), expr);
 }
 
 /// parseExprSelector
@@ -813,29 +809,6 @@
   return new (Context) UnresolvedDeclRefExpr(name, refKind, DeclNameLoc(loc));
 }
 
-static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
-                                                   DeclContext *DC,
-                                                   SourceLoc Loc) {
-  auto *methodContext = DC->getInnermostMethodContext();
-  if (!methodContext) {
-    P.diagnose(Loc, diag::super_not_in_class_method);
-    return nullptr;
-  }
-
-  // Do an actual lookup for 'self' in case it shows up in a capture list.
-  auto *methodSelf = methodContext->getImplicitSelfDecl();
-  auto *lookupSelf = P.lookupInScope(P.Context.Id_self);
-  if (lookupSelf && lookupSelf != methodSelf) {
-    // FIXME: This is the wrong diagnostic for if someone manually declares a
-    // variable named 'self' using backticks.
-    P.diagnose(Loc, diag::super_in_closure_with_capture);
-    P.diagnose(lookupSelf->getLoc(), diag::super_in_closure_with_capture_here);
-    return nullptr;
-  }
-
-  return methodSelf;
-}
-
 /// parseExprSuper
 ///
 ///   expr-super:
@@ -848,28 +821,36 @@
 ///     'super' '.' 'init'
 ///   expr-super-subscript:
 ///     'super' '[' expr ']'
-ParserResult<Expr> Parser::parseExprSuper() {
-  SyntaxParsingContext SuperCtxt(SyntaxContext, SyntaxContextKind::Expr);
-  // Parse the 'super' reference.
-  SourceLoc superLoc = consumeToken(tok::kw_super);
-  SyntaxContext->createNodeInPlace(SyntaxKind::SuperRefExpr);
+ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExprSuperSyntax() {
+  auto superTok = consumeTokenSyntax(tok::kw_super);
 
   // 'super.' must be followed by a member ref, explicit initializer ref, or
   // subscript call.
   if (!Tok.isAny(tok::period, tok::period_prefix, tok::code_complete) &&
       !Tok.isFollowingLSquare()) {
-    if (!consumeIf(tok::unknown))
+    SmallVector<ParsedSyntax, 2> junk;
+    junk.emplace_back(std::move(superTok));
+    if (auto unknown = consumeTokenSyntaxIf(tok::unknown)) {
+      junk.emplace_back(std::move(*unknown));
+    } else {
       diagnose(Tok, diag::expected_dot_or_subscript_after_super);
-    return nullptr;
+    }
+
+    return makeParsedError(
+        ParsedSyntaxRecorder::makeUnknownExpr(junk, *SyntaxContext));
   }
 
-  VarDecl *selfDecl =
-      getImplicitSelfDeclForSuperContext(*this, CurDeclContext, superLoc);
-  if (!selfDecl)
-    return makeParserResult(new (Context) ErrorExpr(superLoc));
+  return makeParsedResult(ParsedSyntaxRecorder::makeSuperRefExpr(
+      std::move(superTok), *SyntaxContext));
+}
 
-  return makeParserResult(new (Context) SuperRefExpr(selfDecl, superLoc,
-                                                     /*Implicit=*/false));
+ParserResult<Expr> Parser::parseExprSuper() {
+  auto leadingLoc = leadingTriviaLoc();
+  auto parsed = parseExprSuperSyntax();
+  SyntaxContext->addSyntax(parsed.get());
+  auto syntax = SyntaxContext->topNode<ExprSyntax>();
+  auto expr = Generator.generate(syntax, leadingLoc);
+  return makeParserResult(parsed.getStatus(), expr);
 }
 
 StringRef Parser::copyAndStripUnderscores(StringRef orig) {
@@ -972,6 +953,96 @@
   return true;
 }
 
+ParsedSyntaxResult<ParsedExprSyntax>
+Parser::parseExprUnresolvedMemberSyntax(bool isExprBasic) {
+  assert(Tok.isAny(tok::period, tok::period_prefix));
+
+  // Parse '.'
+  Tok.setKind(tok::period_prefix);
+  auto dotTok = consumeTokenSyntax(tok::period_prefix);
+
+  // Handle code completion; '.' <cc-token>
+  if (Tok.is(tok::code_complete)) {
+    ParsedCodeCompletionExprSyntaxBuilder ccBuilder(*SyntaxContext);
+    ccBuilder.usePeriodOrParen(std::move(dotTok));
+    ccBuilder.useCodeCompletionToken(consumeTokenSyntax(tok::code_complete));
+    return makeParsedCodeCompletion(ccBuilder.build());
+  }
+
+  ParserStatus status;
+
+  // Parse the name.
+  Optional<ParsedTokenSyntax> identTok;
+  Optional<ParsedDeclNameArgumentsSyntax> declNameArgs;
+  status |=
+      parseUnqualifiedDeclNameSyntax(identTok, declNameArgs, /*afterDot=*/true,
+                                     diag::expected_identifier_after_dot_expr);
+  if (status.isError()) {
+    // If the name is missing. It makes no sense to construct a member access
+    // expression.
+    assert(!identTok && !declNameArgs);
+    return makeParsedError(
+        ParsedSyntaxRecorder::makeUnknownExpr({&dotTok, 1}, *SyntaxContext));
+  }
+
+  ParsedMemberAccessExprSyntaxBuilder builder(*SyntaxContext);
+  builder.useDot(std::move(dotTok));
+  builder.useName(std::move(*identTok));
+  if (declNameArgs)
+    builder.useDeclNameArguments(std::move(*declNameArgs));
+
+  // FIXME: These calling suffix parsings are not necessary for Syntax parsing.
+  // Remove this block after full expression parsing migration.
+
+  // Check for a () suffix, which indicates a call when constructing
+  // this member.  Note that this cannot be the start of a new line.
+  if (Tok.isFollowingLParen()) {
+    ParsedFunctionCallExprSyntaxBuilder callBuilder(*SyntaxContext);
+    callBuilder.useCalledExpression(builder.build());
+
+    status |= parseExprListSyntax(
+        tok::l_paren, tok::r_paren,
+        /*isPostfix=*/true, isExprBasic,
+        [&](ParsedTokenSyntax &&leftTok,
+            ParsedTupleExprElementListSyntax &&args,
+            Optional<ParsedTokenSyntax> &&rightTok,
+            Optional<ParsedClosureExprSyntax> &&closure) {
+          callBuilder.useLeftParen(std::move(leftTok));
+          callBuilder.useArgumentList(std::move(args));
+          if (rightTok)
+            callBuilder.useRightParen(std::move(*rightTok));
+          if (closure)
+            callBuilder.useTrailingClosure(std::move(*closure));
+        });
+    return makeParsedResult(callBuilder.build(), status);
+  }
+
+  // Check for a trailing closure, if allowed.
+  if (Tok.is(tok::l_brace) && isValidTrailingClosure(isExprBasic, *this)) {
+    ParsedFunctionCallExprSyntaxBuilder callBuilder(*SyntaxContext);
+    callBuilder.useCalledExpression(builder.build());
+
+    auto closure = parseTrailingClosureSyntax({PreviousLoc, PreviousLoc});
+    status |= closure.getStatus();
+    assert(!closure.isNull());
+    callBuilder.useTrailingClosure(closure.get());
+
+    return makeParsedResult(callBuilder.build(), status);
+  }
+
+  return makeParsedResult(builder.build(), status);
+}
+
+ParserResult<Expr>
+Parser::parseExprUnresolvedMember(bool isExprBasic) {
+  auto leadingLoc = leadingTriviaLoc();
+  auto parsed = parseExprUnresolvedMemberSyntax(isExprBasic);
+  SyntaxContext->addSyntax(parsed.get());
+  auto syntax = SyntaxContext->topNode<ExprSyntax>();
+  auto expr = Generator.generate(syntax, leadingLoc);
+  return makeParserResult(parsed.getStatus(), expr);
+}
+
 ParserResult<Expr>
 Parser::parseExprPostfixSuffix(ParserResult<Expr> Result, bool isExprBasic,
                                bool periodHasKeyPathBehavior,
@@ -1117,8 +1188,7 @@
       ParserStatus status = parseExprList(
           tok::l_square, tok::r_square,
           /*isPostfix=*/true, isExprBasic, lSquareLoc, indexArgs,
-          indexArgLabels, indexArgLabelLocs, rSquareLoc, trailingClosure,
-          SyntaxKind::TupleExprElementList);
+          indexArgLabels, indexArgLabelLocs, rSquareLoc, trailingClosure);
       Result = makeParserResult(
           status | Result,
           SubscriptExpr::create(Context, Result.get(), lSquareLoc, indexArgs,
@@ -1534,13 +1604,12 @@
 
   case tok::period:              //=.foo
   case tok::period_prefix: {     // .foo
-    Tok.setKind(tok::period_prefix);
-    SourceLoc DotLoc = consumeToken();
-    
     // Special case ".<integer_literal>" like ".4".  This isn't valid, but the
     // developer almost certainly meant to use "0.4".  Diagnose this, and
     // recover as if they wrote that.
-    if (Tok.is(tok::integer_literal) && !Tok.isAtStartOfLine()) {
+    if (peekToken().is(tok::integer_literal) &&
+        !peekToken().isAtStartOfLine()) {
+      SourceLoc DotLoc = consumeToken();
       diagnose(DotLoc, diag::invalid_float_literal_missing_leading_zero,
                Tok.getText())
         .fixItInsert(DotLoc, "0")
@@ -1556,77 +1625,8 @@
                                   FloatLiteralExpr(FltText, DotLoc,
                                                    /*Implicit=*/false));
     }
-    
-    DeclName Name;
-    DeclNameLoc NameLoc;
 
-    if (Tok.is(tok::code_complete)) {
-      auto CCE = new (Context) CodeCompletionExpr(Tok.getLoc());
-      auto Result = makeParserResult(CCE);
-      Result.setHasCodeCompletion();
-      if (CodeCompletion) {
-        CodeCompletion->completeUnresolvedMember(CCE, DotLoc);
-      }
-      consumeToken();
-      return Result;
-    }
-
-    Name = parseUnqualifiedDeclName(/*afterDot=*/true, NameLoc,
-                                    diag::expected_identifier_after_dot_expr);
-    if (!Name) return nullptr;
-    SyntaxContext->createNodeInPlace(SyntaxKind::MemberAccessExpr);
-
-    // Check for a () suffix, which indicates a call when constructing
-    // this member.  Note that this cannot be the start of a new line.
-    if (Tok.isFollowingLParen()) {
-      SourceLoc lParenLoc, rParenLoc;
-      SmallVector<Expr *, 2> args;
-      SmallVector<Identifier, 2> argLabels;
-      SmallVector<SourceLoc, 2> argLabelLocs;
-      Expr *trailingClosure;
-      
-      ParserStatus status = parseExprList(tok::l_paren, tok::r_paren,
-                                          /*isPostfix=*/true, isExprBasic,
-                                          lParenLoc, args, argLabels,
-                                          argLabelLocs,
-                                          rParenLoc,
-                                          trailingClosure,
-                                          SyntaxKind::TupleExprElementList);
-      SyntaxContext->createNodeInPlace(SyntaxKind::FunctionCallExpr);
-      return makeParserResult(
-                 status,
-                 UnresolvedMemberExpr::create(Context, DotLoc, NameLoc, Name,
-                                              lParenLoc, args, argLabels,
-                                              argLabelLocs, rParenLoc,
-                                              trailingClosure,
-                                              /*implicit=*/false));
-    }
-
-    // Check for a trailing closure, if allowed.
-    if (Tok.is(tok::l_brace) && isValidTrailingClosure(isExprBasic, *this)) {
-      // Add dummy blank argument list to the call expression syntax.
-      SyntaxContext->addSyntax(
-          ParsedSyntaxRecorder::makeBlankTupleExprElementList(
-              Tok.getLoc(), *SyntaxContext));
-
-      ParserResult<Expr> closure =
-        parseTrailingClosure(NameLoc.getSourceRange());
-      if (closure.isNull()) return nullptr;
-
-      SyntaxContext->createNodeInPlace(SyntaxKind::FunctionCallExpr);
-      // Handle .foo by just making an AST node.
-      return makeParserResult(
-                 ParserStatus(closure),
-                 UnresolvedMemberExpr::create(Context, DotLoc, NameLoc, Name,
-                                              SourceLoc(), { }, { }, { },
-                                              SourceLoc(), closure.get(),
-                                              /*implicit=*/false));
-    }
-
-    // Handle .foo by just making an AST node.
-    return makeParserResult(
-               UnresolvedMemberExpr::create(Context, DotLoc, NameLoc, Name,
-                                            /*implicit=*/false));
+    return parseExprUnresolvedMember(isExprBasic);
   }
       
   case tok::kw_super: // 'super'
@@ -1638,9 +1638,7 @@
     // only one element without label. However, libSyntax tree doesn't have this
     // differentiation. A tuple expression node in libSyntax can have a single
     // element without label.
-    ExprContext.setCreateSyntax(SyntaxKind::TupleExpr);
-    return parseExprList(tok::l_paren, tok::r_paren,
-                         SyntaxKind::TupleExprElementList);
+    return parseExprParenOrTuple();
 
   case tok::l_square:
     return parseExprCollection();
@@ -1665,9 +1663,9 @@
   }
 
 #define POUND_OBJECT_LITERAL(Name, Desc, Proto)                                \
-  case tok::pound_##Name:                                                      \
-    return parseExprObjectLiteral(ObjectLiteralExpr::Name, isExprBasic);
+  case tok::pound_##Name:
 #include "swift/Syntax/TokenKinds.def"
+    return parseExprObjectLiteral(isExprBasic);
 
   case tok::code_complete: {
     auto Result =
@@ -1683,6 +1681,7 @@
             cast<CodeCompletionExpr>(Result.get()));
       }
     }
+    ExprContext.setCreateSyntax(SyntaxKind::CodeCompletionExpr);
     consumeToken(tok::code_complete);
     return Result;
   }
@@ -2603,8 +2602,9 @@
           nameLoc = consumeToken(tok::kw__);
         }
         auto var = new (Context)
-            ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+            ParamDecl(SourceLoc(), SourceLoc(),
                       Identifier(), nameLoc, name, nullptr);
+        var->setSpecifier(ParamSpecifier::Default);
         elements.push_back(var);
 
         // Consume a comma to continue.
@@ -2682,8 +2682,7 @@
   auto isTupleDestructuring = [](ParamDecl *param) -> bool {
     if (!param->isInvalid())
       return false;
-    auto &typeLoc = param->getTypeLoc();
-    if (auto typeRepr = typeLoc.getTypeRepr())
+    if (auto *typeRepr = param->getTypeRepr())
       return !param->hasName() && isa<TupleTypeRepr>(typeRepr);
     return false;
   };
@@ -2694,7 +2693,6 @@
       continue;
 
     auto argName = "arg" + std::to_string(i);
-    auto typeLoc = param->getTypeLoc();
 
     SmallString<64> fixIt;
     llvm::raw_svector_ostream OS(fixIt);
@@ -2704,7 +2702,7 @@
       OS << '\n' << indent;
 
     OS << "let ";
-    printTupleNames(typeLoc.getTypeRepr(), OS);
+    printTupleNames(param->getTypeRepr(), OS);
     OS << " = " << argName << (isMultiLine ? "\n" + indent : "; ");
 
     diagnose(param->getStartLoc(), diag::anon_closure_tuple_param_destructuring)
@@ -2782,8 +2780,11 @@
 
   // Parse the closing '}'.
   SourceLoc rightBrace;
-  parseMatchingToken(tok::r_brace, rightBrace, diag::expected_closure_rbrace,
-                     leftBrace);
+  if (parseMatchingToken(tok::r_brace, rightBrace,
+                         diag::expected_closure_rbrace, leftBrace)) {
+    // Synthesize an r_brace syntax node if the token is absent
+    SyntaxContext->synthesize(tok::r_brace, rightBrace);
+  }
 
   // If we didn't have any parameters, create a parameter list from the
   // anonymous closure arguments.
@@ -2910,8 +2911,9 @@
     Identifier ident = Context.getIdentifier(varName);
     SourceLoc varLoc = leftBraceLoc;
     auto *var = new (Context)
-        ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+        ParamDecl(SourceLoc(), SourceLoc(),
                   Identifier(), varLoc, ident, closure);
+    var->setSpecifier(ParamSpecifier::Default);
     var->setImplicit();
     decls.push_back(var);
   }
@@ -2921,59 +2923,157 @@
 }
 
 
-/// parseExprList - Parse a list of expressions.
+/// Parse a tuple expression or a paren expression.
 ///
-///   expr-paren:
-///     lparen-any ')'
-///     lparen-any binary-op ')'
-///     lparen-any expr-paren-element (',' expr-paren-element)* ')'
-///
-///   expr-paren-element:
-///     (identifier ':')? expr
-///
-ParserResult<Expr>
-Parser::parseExprList(tok leftTok, tok rightTok, SyntaxKind Kind) {
-  SmallVector<Expr*, 8> subExprs;
-  SmallVector<Identifier, 8> subExprNames;
-  SmallVector<SourceLoc, 8> subExprNameLocs;
-  Expr *trailingClosure = nullptr;
+///   expr-tuple:
+///     '(' ')'
+///     '(' expr-tuple-element-list ')'
+ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExprTupleSyntax() {
+  ParsedTupleExprSyntaxBuilder builder(*SyntaxContext);
+  ParserStatus status;
 
-  SourceLoc leftLoc, rightLoc;
-  ParserStatus status = parseExprList(leftTok, rightTok, /*isPostfix=*/false,
-                                      /*isExprBasic=*/true,
-                                      leftLoc,
-                                      subExprs,
-                                      subExprNames,
-                                      subExprNameLocs,
-                                      rightLoc,
-                                      trailingClosure,
-                                      Kind);
+  StructureMarkerRAII ParsingExprList(*this, Tok);
+  if (ParsingExprList.isFailed())
+    return makeParserError();
 
-  // A tuple with a single, unlabeled element is just parentheses.
-  if (subExprs.size() == 1 &&
-      (subExprNames.empty() || subExprNames[0].empty())) {
-    return makeParserResult(
-        status, new (Context) ParenExpr(leftLoc, subExprs[0], rightLoc,
-                                        /*hasTrailingClosure=*/false));
+  // Parse '('.
+  auto LParenLoc = Tok.getLoc();
+  builder.useLeftParen(consumeTokenSyntax(tok::l_paren));
+
+  // Parse the elements.
+  SmallVector<ParsedTupleExprElementSyntax, 4> elements;
+  status |= parseExprTupleElementListSyntax(
+      elements, [&]() { return Tok.is(tok::r_paren); });
+  for (auto &elem : elements)
+    builder.addElementListMember(std::move(elem));
+
+  // Parse ')'.
+  auto RParen =
+      parseMatchingTokenSyntax(tok::r_paren, diag::expected_rparen_expr_list,
+                               LParenLoc, /*silenceDiag=*/status.isError());
+  status |= RParen.getStatus();
+  if (!RParen.isNull())
+    builder.useRightParen(RParen.get());
+
+  return makeParsedResult(builder.build(), status);
+}
+
+ParserResult<Expr> Parser::parseExprParenOrTuple() {
+  auto leadingLoc = leadingTriviaLoc();
+  auto parsed = parseExprTupleSyntax();
+  // NOTE: 'parsed' can be null if the nesting structure is too deep.
+  if (!parsed.isNull()) {
+    SyntaxContext->addSyntax(parsed.get());
+    auto syntax = SyntaxContext->topNode<ExprSyntax>();
+    return makeParserResult(parsed.getStatus(),
+                            Generator.generate(syntax, leadingLoc));
   }
-
-  return makeParserResult(
-      status,
-      TupleExpr::create(Context, leftLoc, subExprs, subExprNames,
-                        subExprNameLocs, rightLoc, /*HasTrailingClosure=*/false,
-                        /*Implicit=*/false));
+  return parsed.getStatus();
 }
 
 /// parseExprList - Parse a list of expressions.
 ///
-///   expr-paren:
-///     lparen-any ')'
-///     lparen-any binary-op ')'
-///     lparen-any expr-paren-element (',' expr-paren-element)* ')'
+///   expr-tuple-element-list:
+///     expr-tuple-element (',' expr-tuple-element)*
+///   expr-tuple-element:
+///     (identifier ':')? (expr | binary-operator)
 ///
-///   expr-paren-element:
-///     (identifier ':')? expr
+ParserStatus Parser::parseExprTupleElementListSyntax(
+    SmallVectorImpl<ParsedTupleExprElementSyntax> &elements,
+    llvm::function_ref<bool()> isAtCloseTok) {
+  return parseListSyntax(
+      elements, /*AllowEmpty=*/true, /*AllowSepAfterLast=*/false, isAtCloseTok,
+      [&](ParsedTupleExprElementSyntaxBuilder &elemBuilder) {
+        Optional<ParsedTokenSyntax> label;
+        Optional<ParsedTokenSyntax> colon;
+        if (parseOptionalArgumentLabelSyntax(label, colon)) {
+          elemBuilder.useLabel(std::move(*label));
+          elemBuilder.useColon(std::move(*colon));
+        }
+
+        // See if we have an operator decl ref '(<op>)'. The operator token in
+        // this case lexes as a binary operator because it neither leads nor
+        // follows a proper subexpression.
+        if (Tok.isBinaryOperator() &&
+            peekToken().isAny(tok::r_paren, tok::r_square, tok::eof,
+                              tok::comma)) {
+          elemBuilder.useExpression(ParsedSyntaxRecorder::makeIdentifierExpr(
+              consumeTokenSyntax(), None, *SyntaxContext));
+          return makeParserSuccess();
+        }
+
+        auto subExpr = parseExpressionSyntax(diag::expected_expr_in_expr_list);
+        if (!subExpr.isNull())
+          elemBuilder.useExpression(subExpr.get());
+        else
+          elemBuilder.useExpression(
+              ParsedSyntaxRecorder::makeUnknownExpr({}, *SyntaxContext));
+        return subExpr.getStatus();
+      });
+}
+
+/// Parse a parenthesized expression list for a call-like expressions including
+/// subscripts.
 ///
+///   expr-list(left, right):
+///     left right expr-closure?
+///     left expr-tuple-element-list right expr-closure?
+ParserStatus Parser::parseExprListSyntax(
+    tok leftK, tok rightK, bool isPostfix, bool isExprBasic,
+    llvm::function_ref<void(
+        ParsedTokenSyntax &&, ParsedTupleExprElementListSyntax &&,
+        Optional<ParsedTokenSyntax> &&, Optional<ParsedClosureExprSyntax> &&)>
+        callback) {
+  StructureMarkerRAII ParsingExprList(*this, Tok);
+  if (ParsingExprList.isFailed())
+    return makeParserError();
+
+  ParserStatus status;
+
+  auto TokIsStringInterpolationEOF = [&]() -> bool {
+    return Tok.is(tok::eof) && Tok.getText() == ")" && rightK == tok::r_paren;
+  };
+
+  // Parse '(' or '['.
+  auto leftLoc = Tok.getLoc();
+  auto leftTok = consumeTokenSyntax(tok::l_paren);
+
+  // Parse the elements.
+  SmallVector<ParsedTupleExprElementSyntax, 4> elements;
+  status |= parseExprTupleElementListSyntax(elements, [&] {
+    return Tok.is(rightK) || TokIsStringInterpolationEOF();
+  });
+  auto list =
+      ParsedSyntaxRecorder::makeTupleExprElementList(elements, *SyntaxContext);
+
+  if (TokIsStringInterpolationEOF()) {
+    callback(std::move(leftTok), std::move(list), None, None);
+    return status;
+  }
+
+  // Parse ')' or ']'.
+  auto rightTok =
+      parseMatchingTokenSyntax(rightK, rightK == tok::r_paren
+                                         ? diag::expected_rparen_expr_list
+                                         : diag::expected_rsquare_expr_list,
+                               leftLoc, /*silenceDiag=*/status.isError());
+  status |= rightTok.getStatus();
+  auto rightLoc = PreviousLoc;
+
+  // If we aren't interested in trailing closures, or there isn't a valid one,
+  // we're done.
+  if (rightTok.isNull() || !isPostfix || Tok.isNot(tok::l_brace) ||
+      !isValidTrailingClosure(isExprBasic, *this)) {
+    callback(std::move(leftTok), std::move(list), rightTok.getOrNull(), None);
+    return status;
+  }
+
+  auto closure = parseTrailingClosureSyntax({leftLoc, rightLoc});
+  status |= closure.getStatus();
+  callback(std::move(leftTok), std::move(list), rightTok.getOrNull(), closure.getOrNull());
+  return status;
+}
+
 ParserStatus Parser::parseExprList(tok leftTok, tok rightTok,
                                    bool isPostfix,
                                    bool isExprBasic,
@@ -2982,82 +3082,53 @@
                                    SmallVectorImpl<Identifier> &exprLabels,
                                    SmallVectorImpl<SourceLoc> &exprLabelLocs,
                                    SourceLoc &rightLoc,
-                                   Expr *&trailingClosure,
-                                   SyntaxKind Kind) {
+                                   Expr *&trailingClosure) {
   trailingClosure = nullptr;
 
   StructureMarkerRAII ParsingExprList(*this, Tok);
-  
-  if (ParsingExprList.isFailed()) {
+  if (ParsingExprList.isFailed())
     return makeParserError();
-  }
+
+  auto TokIsStringInterpolationEOF = [&]() -> bool {
+    return Tok.is(tok::eof) && Tok.getText() == ")" && rightTok == tok::r_paren;
+  };
 
   leftLoc = consumeToken(leftTok);
-  ParserStatus status = parseList(rightTok, leftLoc, rightLoc,
-                                  /*AllowSepAfterLast=*/false,
-                                  rightTok == tok::r_paren
+
+  ParserStatus status;
+  // Parse the parenthesized expression list.
+  {
+    auto leadingLoc = leadingTriviaLoc();
+    SmallVector<ParsedTupleExprElementSyntax, 4> parsedElements;
+    status |= parseExprTupleElementListSyntax(parsedElements, [&] {
+      return Tok.is(rightTok) || TokIsStringInterpolationEOF();
+    });
+
+    // Elements.
+    SyntaxContext->addSyntax(ParsedSyntaxRecorder::makeTupleExprElementList(
+        parsedElements, *SyntaxContext));
+    auto elements = SyntaxContext->topNode<TupleExprElementListSyntax>();
+    Generator.generateExprTupleElementList(elements, leadingLoc,
+                                           /*isForCallArguments=*/true, exprs,
+                                           exprLabels, exprLabelLocs);
+  }
+
+  if (TokIsStringInterpolationEOF()) {
+    rightLoc = Tok.getLoc();
+    return status;
+  }
+
+  if (status.isError()) {
+    // If we've already got errors, don't emit missing RightK diagnostics.
+    rightLoc =
+        Tok.is(rightTok) ? consumeToken() : getLocForMissingMatchingToken();
+  } else if (parseMatchingToken(rightTok, rightLoc,
+                                rightTok == tok::r_paren
                                     ? diag::expected_rparen_expr_list
                                     : diag::expected_rsquare_expr_list,
-                                  Kind,
-                                  [&] () -> ParserStatus {
-    Identifier FieldName;
-    SourceLoc FieldNameLoc;
-    if (Kind != SyntaxKind::YieldStmt)
-      parseOptionalArgumentLabel(FieldName, FieldNameLoc);
-
-    // See if we have an operator decl ref '(<op>)'. The operator token in
-    // this case lexes as a binary operator because it neither leads nor
-    // follows a proper subexpression.
-    ParserStatus Status;
-    Expr *SubExpr = nullptr;
-    if (Tok.isBinaryOperator() && peekToken().isAny(rightTok, tok::comma)) {
-      SyntaxParsingContext operatorContext(SyntaxContext,
-                                           SyntaxKind::IdentifierExpr);
-      SourceLoc Loc;
-      Identifier OperName;
-      if (parseAnyIdentifier(OperName, Loc, diag::expected_operator_ref)) {
-        return makeParserError();
-      }
-      // Bypass local lookup. Use an 'Ordinary' reference kind so that the
-      // reference may resolve to any unary or binary operator based on
-      // context.
-      SubExpr = new(Context) UnresolvedDeclRefExpr(OperName,
-                                                   DeclRefKind::Ordinary,
-                                                   DeclNameLoc(Loc));
-    } else if (isPostfix && Tok.is(tok::code_complete)) {
-      // Handle call arguments specially because it may need argument labels.
-      auto CCExpr = new (Context) CodeCompletionExpr(Tok.getLoc());
-      if (CodeCompletion)
-        CodeCompletion->completeCallArg(CCExpr, PreviousLoc == leftLoc);
-      consumeIf(tok::code_complete);
-      SubExpr = CCExpr;
-      Status.setHasCodeCompletion();
-    } else {
-      auto ParsedSubExpr = parseExpr(diag::expected_expr_in_expr_list);
-      SubExpr = ParsedSubExpr.getPtrOrNull();
-      Status = ParsedSubExpr;
-    }
-
-    // If we got a subexpression, add it.
-    if (SubExpr) {
-      // Update names and locations.
-      if (!exprLabels.empty()) {
-        exprLabels.push_back(FieldName);
-        exprLabelLocs.push_back(FieldNameLoc);
-      } else if (FieldNameLoc.isValid()) {
-        exprLabels.resize(exprs.size());
-        exprLabels.push_back(FieldName);
-
-        exprLabelLocs.resize(exprs.size());
-        exprLabelLocs.push_back(FieldNameLoc);
-      }
-
-      // Add the subexpression.
-      exprs.push_back(SubExpr);
-    }
-
-    return Status;
-  });
+                                leftLoc)) {
+    status.setIsParseError();
+  }
 
   // If we aren't interested in trailing closures, or there isn't a valid one,
   // we're done.
@@ -3109,46 +3180,63 @@
 
   return closure;
 }
+
+ParsedSyntaxResult<ParsedClosureExprSyntax>
+Parser::parseTrailingClosureSyntax(SourceRange calleeRange) {
+  SyntaxParsingContext TmpContext(SyntaxContext);
+  TmpContext.setTransparent();
+
+  SourceLoc ExprLoc = Tok.getLoc();
+  ParserResult<Expr> Result = parseTrailingClosure(calleeRange);
+  if (auto ParsedExpr = TmpContext.popIf<ParsedClosureExprSyntax>()) {
+    Generator.addExpr(Result.getPtrOrNull(), ExprLoc);
+    return makeParsedResult(std::move(*ParsedExpr), Result.getStatus());
+  }
+  return Result.getStatus();
+}
  
 /// Parse an object literal expression.
 ///
 /// expr-literal:
 ///   '#' identifier expr-paren
-ParserResult<Expr>
-Parser::parseExprObjectLiteral(ObjectLiteralExpr::LiteralKind LitKind,
-                               bool isExprBasic) {
-  SyntaxParsingContext ObjectLiteralContext(SyntaxContext,
-                                            SyntaxKind::ObjectLiteralExpr);
-  SourceLoc PoundLoc = consumeToken();
-  // Parse a tuple of args
+ParsedSyntaxResult<ParsedExprSyntax>
+Parser::parseExprObjectLiteralSyntax(bool isExprBasic) {
+  ParsedObjectLiteralExprSyntaxBuilder builder(*SyntaxContext);
+  ParserStatus status;
+
+  builder.useIdentifier(consumeTokenSyntax());
+
   if (!Tok.is(tok::l_paren)) {
     diagnose(Tok, diag::expected_arg_list_in_object_literal);
-    return makeParserError();
+    return makeParsedError(builder.build());
   }
 
-  // Parse the argument list.
-  SourceLoc lParenLoc, rParenLoc;
-  SmallVector<Expr *, 2> args;
-  SmallVector<Identifier, 2> argLabels;
-  SmallVector<SourceLoc, 2> argLabelLocs;
-  Expr *trailingClosure;
+  status |= parseExprListSyntax(
+      tok::l_paren, tok::r_paren,
+      /*isPostfix=*/true, isExprBasic,
+      [&](ParsedTokenSyntax &&leftTok, ParsedTupleExprElementListSyntax &&args,
+          Optional<ParsedTokenSyntax> &&rightTok,
+          Optional<ParsedClosureExprSyntax> &&closure) {
+        builder.useLeftParen(std::move(leftTok));
+        builder.useArguments(std::move(args));
+        if (rightTok)
+          builder.useRightParen(std::move(*rightTok));
+        if (closure)
+          builder.useTrailingClosure(std::move(*closure));
+      });
+  return makeParsedResult(builder.build(), status);
+}
 
-  ParserStatus status = parseExprList(tok::l_paren, tok::r_paren,
-                                      /*isPostfix=*/true, isExprBasic,
-                                      lParenLoc, args, argLabels,
-                                      argLabelLocs,
-                                      rParenLoc,
-                                      trailingClosure,
-                                      SyntaxKind::TupleExprElementList);
-  if (status.hasCodeCompletion())
-    return makeParserCodeCompletionResult<Expr>();
-  if (status.isError())
-    return makeParserError();
+ParserResult<Expr>
+Parser::parseExprObjectLiteral(bool isExprBasic) {
+  auto leadingLoc = leadingTriviaLoc();
+  auto parsed = parseExprObjectLiteralSyntax(isExprBasic);
+  assert(!parsed.isNull());
+  SyntaxContext->addSyntax(parsed.get());
 
-  return makeParserResult(
-    ObjectLiteralExpr::create(Context, PoundLoc, LitKind, lParenLoc, args,
-                              argLabels, argLabelLocs, rParenLoc,
-                              trailingClosure, /*implicit=*/false));
+  auto syntax = SyntaxContext->topNode<ExprSyntax>();
+  return makeParserResult(parsed.getStatus(),
+                          Generator.generate(syntax, leadingLoc));
 }
 
 /// Parse a quote literal expression.
@@ -3278,8 +3366,7 @@
     ParserStatus status =
         parseExprList(tok::l_paren, tok::r_paren,
                       /*isPostfix=*/true, /*isExprBasic*/ true, LParenLoc,
-                      args, argLabels, argLabelLocs, RParenLoc, trailingClosure,
-                      SyntaxKind::TupleExprElementList);
+                      args, argLabels, argLabelLocs, RParenLoc, trailingClosure);
     if (status.hasCodeCompletion())
       return makeParserCodeCompletionResult<Expr>();
     if (status.isError())
@@ -3332,6 +3419,26 @@
   return makeParserError();
 }
 
+ParsedSyntaxResult<ParsedExprSyntax>
+Parser::parseExprPoundUnknownSyntax(Optional<ParsedTokenSyntax> &&LSquare,
+                                    SourceLoc LSquareLoc) {
+  SourceLoc ExprLoc = Tok.getLoc();
+  if (LSquareLoc.isValid())
+    ExprLoc = LSquareLoc;
+  ParserStatus status;
+  {
+    SyntaxParsingContext ExprParsingContext(SyntaxContext,
+                                            SyntaxContextKind::Expr);
+    if (LSquare)
+      ExprParsingContext.addSyntax(std::move(*LSquare));
+    ParserResult<Expr> result = parseExprPoundUnknown(LSquareLoc);
+    status = result;
+    Generator.addExpr(result.getPtrOrNull(), ExprLoc);
+  }
+  auto parsed = SyntaxContext->popIf<ParsedExprSyntax>();
+  return makeParsedResult(std::move(*parsed), status);
+}
+
 /// Handle code completion after pound in expression position.
 ///
 /// In case it's in a stmt condition position, specify \p ParentKind to
@@ -3394,8 +3501,7 @@
                                       lParenLoc, args, argLabels,
                                       argLabelLocs,
                                       rParenLoc,
-                                      trailingClosure,
-                                      SyntaxKind::TupleExprElementList);
+                                      trailingClosure);
 
   // Form the call.
   return makeParserResult(
@@ -3415,205 +3521,163 @@
 ///   expr-dictionary:
 ///     '[' expr ':' expr (',' expr ':' expr)* ','? ']'
 ///     '[' ':' ']'
-ParserResult<Expr> Parser::parseExprCollection() {
-  SyntaxParsingContext ArrayOrDictContext(SyntaxContext,
-                                          SyntaxContextKind::Expr);
-  SourceLoc LSquareLoc = consumeToken(tok::l_square);
-  SourceLoc RSquareLoc;
+ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExprCollectionSyntax() {
+  auto LSquareLoc = Tok.getLoc();
+  auto LSquare = consumeTokenSyntax(tok::l_square);
 
   Parser::StructureMarkerRAII ParsingCollection(
-                                *this, LSquareLoc,
-                                StructureMarkerKind::OpenSquare);
+      *this, LSquareLoc, StructureMarkerKind::OpenSquare);
 
   // [] is always an array.
   if (Tok.is(tok::r_square)) {
-    SyntaxContext->addSyntax(
-        ParsedSyntaxRecorder::makeBlankArrayElementList(
-                              Tok.getLoc(), *SyntaxContext));
-    RSquareLoc = consumeToken(tok::r_square);
-    ArrayOrDictContext.setCreateSyntax(SyntaxKind::ArrayExpr);
-    return makeParserResult(
-                    ArrayExpr::create(Context, LSquareLoc, {}, {}, RSquareLoc));
+    ParsedArrayExprSyntaxBuilder builder(*SyntaxContext);
+    builder.useLeftSquare(std::move(LSquare));
+    builder.useRightSquare(consumeTokenSyntax(tok::r_square));
+    return makeParsedResult(builder.build());
   }
 
   // [:] is always an empty dictionary.
   if (Tok.is(tok::colon) && peekToken().is(tok::r_square)) {
-    consumeToken(tok::colon);
-    RSquareLoc = consumeToken(tok::r_square);
-    ArrayOrDictContext.setCreateSyntax(SyntaxKind::DictionaryExpr);
-    return makeParserResult(
-               DictionaryExpr::create(Context, LSquareLoc, {}, {}, RSquareLoc));
+    ParsedDictionaryExprSyntaxBuilder builder(*SyntaxContext);
+    builder.useLeftSquare(std::move(LSquare));
+    builder.useContent(consumeTokenSyntax(tok::colon));
+    builder.useRightSquare(consumeTokenSyntax(tok::r_square));
+    return makeParsedResult(builder.build());
   }
 
-  // [#identifier is likely to be a legacy object literal.
+  // '[#identifier' is likely to be a legacy object literal.
   if (Tok.is(tok::pound) && peekToken().is(tok::identifier) &&
       !peekToken().isEscapedIdentifier() &&
       LSquareLoc.getAdvancedLoc(1) == Tok.getLoc() &&
       Tok.getLoc().getAdvancedLoc(1) == peekToken().getLoc()) {
-    ArrayOrDictContext.setCoerceKind(SyntaxContextKind::Expr);
-    return parseExprPoundUnknown(LSquareLoc);
+     return parseExprPoundUnknownSyntax(std::move(LSquare), LSquareLoc);
   }
 
-  ParserStatus Status;
-  Optional<bool> isDictionary;
-  SmallVector<Expr *, 8> ElementExprs;
-  SmallVector<SourceLoc, 8> CommaLocs;
+  auto firstExpr =
+      parseExpressionSyntax(diag::expected_expr_in_collection_literal);
 
-  {
-    SyntaxParsingContext ListCtx(SyntaxContext, SyntaxContextKind::Expr);
-
-    while (true) {
-      SyntaxParsingContext ElementCtx(SyntaxContext);
-
-      auto Element = parseExprCollectionElement(isDictionary);
-      Status |= Element;
-      ElementCtx.setCreateSyntax(*isDictionary ? SyntaxKind::DictionaryElement
-                                               : SyntaxKind::ArrayElement);
-      if (Element.isNonNull())
-        ElementExprs.push_back(Element.get());
-
-      // Skip to ']' or ',' in case of error.
-      // NOTE: This checks 'Status' instead of 'Element' to silence excessive
-      // diagnostics.
-      if (Status.isError()) {
-        skipUntilDeclRBrace(tok::r_square, tok::comma);
-        if (Tok.isNot(tok::comma))
-          break;
-      }
-
-      // Parse the ',' if exists.
-      if (Tok.is(tok::comma)) {
-        CommaLocs.push_back(consumeToken());
-        if (!Tok.is(tok::r_square))
-          continue;
-      }
-
-      // Close square.
-      if (Tok.is(tok::r_square))
-        break;
-
-      // If we found EOF or such, bailout.
-      if (Tok.is(tok::eof)) {
-        IsInputIncomplete = true;
-        break;
-      }
-
-      // If The next token is at the beginning of a new line and can never start
-      // an element, break.
-      if (Tok.isAtStartOfLine() && (Tok.isAny(tok::r_brace, tok::pound_endif) ||
-                                    isStartOfDecl() || isStartOfStmt()))
-        break;
-
-      diagnose(Tok, diag::expected_separator, ",")
-          .fixItInsertAfter(PreviousLoc, ",");
-      Status.setIsParseError();
-    }
-
-    ListCtx.setCreateSyntax(*isDictionary ? SyntaxKind::DictionaryElementList
-                                          : SyntaxKind::ArrayElementList);
+  if (!Tok.is(tok::colon)) {
+    // Array.
+    return parseExprArraySyntax(std::move(LSquare), LSquareLoc,
+                                std::move(firstExpr));
+  } else {
+    // Dictionary.
+    return parseExprDictionarySyntax(std::move(LSquare), LSquareLoc,
+                                     std::move(firstExpr));
   }
-  ArrayOrDictContext.setCreateSyntax(*isDictionary ? SyntaxKind::DictionaryExpr
-                                                   : SyntaxKind::ArrayExpr);
-
-  if (Status.isError()) {
-    // If we've already got errors, don't emit missing RightK diagnostics.
-    RSquareLoc = Tok.is(tok::r_square) ? consumeToken()
-                                       : getLocForMissingMatchingToken();
-  } else if (parseMatchingToken(tok::r_square, RSquareLoc,
-                                diag::expected_rsquare_array_expr,
-                                LSquareLoc)) {
-    Status.setIsParseError();
-  }
-
-  // Don't bother to create expression if any expressions aren't parsed.
-  if (ElementExprs.empty())
-    return Status;
-
-  Expr *expr;
-  if (*isDictionary)
-    expr = DictionaryExpr::create(Context, LSquareLoc, ElementExprs, CommaLocs,
-                                  RSquareLoc);
-  else
-    expr = ArrayExpr::create(Context, LSquareLoc, ElementExprs, CommaLocs,
-                             RSquareLoc);
-
-  return makeParserResult(Status, expr);
 }
 
-/// parseExprCollectionElement - Parse an element for collection expr.
-///
-/// If \p isDictionary is \c None, it's set to \c true if the element is for
-/// dictionary literal, or \c false otherwise.
-ParserResult<Expr>
-Parser::parseExprCollectionElement(Optional<bool> &isDictionary) {
-  auto Element = parseExpr(isDictionary.hasValue() && *isDictionary
-                               ? diag::expected_key_in_dictionary_literal
-                               : diag::expected_expr_in_collection_literal);
+ParsedSyntaxResult<ParsedExprSyntax>
+Parser::parseExprArraySyntax(ParsedTokenSyntax &&LSquare, SourceLoc LSquareLoc,
+                             ParsedSyntaxResult<ParsedExprSyntax> &&firstExpr) {
+  ParserStatus status;
 
-  if (!isDictionary.hasValue())
-    isDictionary = Tok.is(tok::colon);
+  ParsedArrayExprSyntaxBuilder builder(*SyntaxContext);
+  builder.useLeftSquare(std::move(LSquare));
 
-  if (!*isDictionary) {
-    validateCollectionElement(Element);
-    return Element;
-  }
+  SmallVector<ParsedArrayElementSyntax, 8> elements;
 
-  if (Element.isNull())
-    return Element;
+  // Parse elements.
+  // NOTE: 'AllowEmpty=false' because we already have 'firstExpr'.
+  bool isFirst = true;
+  status |= parseListSyntax(
+      elements, /*AllowEmpty=*/false, /*AllowSepAfterLast=*/true,
+      [&]() { return Tok.is(tok::r_square); },
+      [&](ParsedArrayElementSyntaxBuilder &elemBuilder) {
+        auto expr = isFirst ? std::move(firstExpr)
+                            : parseExpressionSyntax(
+                                  diag::expected_expr_in_collection_literal);
+        isFirst = false;
+        elemBuilder.useExpression(
+            !expr.isNull()
+                ? expr.get()
+                : ParsedSyntaxRecorder::makeUnknownExpr({}, *SyntaxContext));
+        return expr.getStatus();
+      });
+  for (auto &elem : elements)
+    builder.addElementsMember(std::move(elem));
 
-  // Parse the ':'.
-  if (!consumeIf(tok::colon)) {
-    diagnose(Tok, diag::expected_colon_in_dictionary_literal);
-    return ParserStatus(Element) | makeParserError();
-  }
+  // Parse ']'.
+  auto RSquare =
+      parseMatchingTokenSyntax(tok::r_square, diag::expected_rsquare_array_expr,
+                               LSquareLoc, status.isError());
+  status |= RSquare.getStatus();
+  if (!RSquare.isNull())
+    builder.useRightSquare(RSquare.get());
 
-  // Parse the value.
-  auto Value = parseExpr(diag::expected_value_in_dictionary_literal);
-
-  if (Value.isNull())
-    Value = makeParserResult(Value, new (Context) ErrorExpr(PreviousLoc));
-
-  // Make a tuple of Key Value pair.
-  return makeParserResult(
-      ParserStatus(Element) | ParserStatus(Value),
-      TupleExpr::createImplicit(Context, {Element.get(), Value.get()}, {}));
+  return makeParsedResult(builder.build(), status);
 }
 
-/// validateCollectionElement - Check if a given collection element is valid.
-///
-/// At the moment, this checks whether a given collection element is a subscript
-/// expression and whether we're subscripting into an array. If we are, then it
-/// we emit a diagnostic in case it was not something that the user was
-/// expecting.
-///
-/// For example: `let array [ [0, 1] [42] ]`
-void Parser::validateCollectionElement(ParserResult<Expr> element) {
-  if (element.isNull())
-    return;
+ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExprDictionarySyntax(
+    ParsedTokenSyntax &&LSquare, SourceLoc LSquareLoc,
+    ParsedSyntaxResult<ParsedExprSyntax> &&firstExpr) {
+  ParserStatus status = firstExpr.getStatus();
 
-  auto elementExpr = element.get();
-  if (!isa<SubscriptExpr>(elementExpr))
-    return;
+  ParsedDictionaryExprSyntaxBuilder builder(*SyntaxContext);
+  builder.useLeftSquare(std::move(LSquare));
 
-  auto subscriptExpr = cast<SubscriptExpr>(elementExpr);
-  if (!isa<ArrayExpr>(subscriptExpr->getBase()))
-    return;
+  SmallVector<ParsedDictionaryElementSyntax, 8> elements;
 
-  auto arrayExpr = cast<ArrayExpr>(subscriptExpr->getBase());
+  // Parse other elements.
+  bool isFirst = true;
+  status |= parseListSyntax(
+      elements, /*AllowEmpty=*/false, /*AllowSepAfterLast=*/true,
+      [&]() { return Tok.is(tok::r_square); },
+      [&](ParsedDictionaryElementSyntaxBuilder &elemBuilder) {
+        // Parse the key expression.
+        auto key = isFirst ? std::move(firstExpr)
+                           : parseExpressionSyntax(
+                                 diag::expected_key_in_dictionary_literal);
+        isFirst = false;
+        elemBuilder.useKeyExpression(
+            !key.isNull()
+                ? key.get()
+                : ParsedSyntaxRecorder::makeUnknownExpr({}, *SyntaxContext));
 
-  auto startLocOfSubscript = subscriptExpr->getIndex()->getStartLoc();
-  auto endLocOfArray = arrayExpr->getEndLoc();
-  auto locForEndOfTokenArray = L->getLocForEndOfToken(SourceMgr, endLocOfArray);
+        // Parse ':'.
+        if (Tok.is(tok::colon)) {
+          elemBuilder.useColon(consumeTokenSyntax(tok::colon));
+        } else {
+          if (key.getStatus().isSuccess())
+            diagnose(Tok, diag::expected_colon_in_dictionary_literal);
+          elemBuilder.useValueExpression(
+               ParsedSyntaxRecorder::makeUnknownExpr({}, *SyntaxContext));
+          return key.getStatus() | makeParserError();
+        }
 
-  if (locForEndOfTokenArray != startLocOfSubscript) {
-    auto subscriptLoc = subscriptExpr->getLoc();
-    diagnose(subscriptLoc, diag::subscript_array_element)
-        .highlight(subscriptExpr->getSourceRange());
-    diagnose(subscriptLoc, diag::subscript_array_element_fix_it_add_comma)
-        .fixItInsertAfter(endLocOfArray, ",");
-    diagnose(subscriptLoc, diag::subscript_array_element_fix_it_remove_space)
-        .fixItRemoveChars(locForEndOfTokenArray, startLocOfSubscript);
-  }
+        // Parse the value expression.
+        auto value =
+            parseExpressionSyntax(diag::expected_value_in_dictionary_literal);
+        elemBuilder.useValueExpression(
+            !value.isNull()
+                ? value.get()
+                : ParsedSyntaxRecorder::makeUnknownExpr({}, *SyntaxContext));
+
+        return key.getStatus() | value.getStatus();
+      });
+  builder.useContent(ParsedSyntaxRecorder::makeDictionaryElementList(
+      elements, *SyntaxContext));
+
+  // Parse ']'.
+  auto RSquare =
+      parseMatchingTokenSyntax(tok::r_square, diag::expected_rsquare_array_expr,
+                               LSquareLoc, status.isError());
+  status |= RSquare.getStatus();
+  if (!RSquare.isNull())
+    builder.useRightSquare(RSquare.get());
+
+  return makeParsedResult(builder.build(), status);
+}
+
+ParserResult<Expr> Parser::parseExprCollection() {
+  auto leadingLoc = leadingTriviaLoc();
+  auto parsed = parseExprCollectionSyntax();
+  assert(!parsed.isNull());
+  SyntaxContext->addSyntax(parsed.get());
+
+  auto syntax = SyntaxContext->topNode<ExprSyntax>();
+  return makeParserResult(parsed.getStatus(),
+                          Generator.generate(syntax, leadingLoc));
 }
 
 void Parser::addPatternVariablesToScope(ArrayRef<Pattern *> Patterns) {
diff --git a/lib/Parse/ParseList.h b/lib/Parse/ParseList.h
new file mode 100644
index 0000000..7ed23eb
--- /dev/null
+++ b/lib/Parse/ParseList.h
@@ -0,0 +1,87 @@
+//===--- ParseList.h ------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2019 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_PARSE_PARSELIST_H
+#define SWIFT_PARSE_PARSELIST_H
+
+#include "swift/Parse/Parser.h"
+#include "swift/Parse/ParserResult.h"
+
+namespace swift {
+
+/// Parse a comma-separated list of something.
+template <typename ParsedNode>
+inline ParserStatus Parser::parseListSyntax(
+    SmallVectorImpl<ParsedNode> &elements, bool AllowEmpty,
+    bool AllowSepAfterLast, llvm::function_ref<bool()> isAtCloseTok,
+    llvm::function_ref<ParserStatus(typename ParsedNode::Builder &)> callback) {
+  ParserStatus status;
+
+  auto isAtTerminator = [&]() -> bool {
+    return Tok.isAny(tok::eof, tok::pound_endif, tok::pound_else,
+                     tok::pound_elseif) ||
+           (Tok.isAtStartOfLine() &&
+            (Tok.is(tok::r_brace) || isStartOfDecl() || isStartOfStmt()));
+  };
+
+  bool isTerminated = AllowEmpty && isAtCloseTok();
+
+  while (!isTerminated) {
+    typename ParsedNode::Builder elemBuilder(*SyntaxContext);
+
+    // Parse the element.
+    status |= callback(elemBuilder);
+
+    if (status.isError()) {
+      // Recover by skipping to ',' or close bracket.
+      while (!Tok.is(tok::comma) && !isAtCloseTok() && !isAtTerminator())
+        ignoreSingle();
+    }
+
+    // Parse ','.
+    auto hasComma = Tok.is(tok::comma);
+    if (hasComma)
+      elemBuilder.useTrailingComma(consumeTokenSyntax(tok::comma));
+
+    // Store the element to the list.
+    elements.emplace_back(elemBuilder.build());
+
+    // Check to see if there's close bracket.
+    isTerminated = isAtCloseTok();
+
+    // If we found EOF or such without seeing ',' or close bracket, terminate.
+    if (!isTerminated && !hasComma) {
+      if (isAtTerminator()) {
+        checkForInputIncomplete();
+        isTerminated = true;
+      }
+    }
+
+    if (isTerminated) {
+      // Complain about the trailing comma at the last element.
+      if (hasComma && !AllowSepAfterLast)
+        diagnose(Tok, diag::unexpected_separator, ",")
+            .fixItRemove(SourceRange(PreviousLoc));
+    } else {
+      // Complain about the missing ','.
+      if (!hasComma) {
+        diagnose(Tok, diag::expected_separator, ",")
+            .fixItInsertAfter(PreviousLoc, ",");
+        status.setIsParseError();
+      }
+    }
+  }
+  return status;
+}
+
+} // namespace swift
+#endif
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 6a50e1e..fa46412 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -472,8 +472,7 @@
                          Identifier argName, SourceLoc argNameLoc,
                          Identifier paramName, SourceLoc paramNameLoc)
   -> ParamDecl * {
-    auto param = new (ctx) ParamDecl(ParamDecl::Specifier::Default,
-                                     paramInfo.SpecifierLoc,
+    auto param = new (ctx) ParamDecl(paramInfo.SpecifierLoc,
                                      argNameLoc, argName,
                                      paramNameLoc, paramName,
                                      parser.CurDeclContext);
@@ -482,7 +481,6 @@
     auto setInvalid = [&]{
       if (param->isInvalid())
         return;
-      param->getTypeLoc().setInvalidType(ctx);
       param->setInvalid();
     };
 
@@ -513,7 +511,7 @@
                                                              "__owned",
                                                              parsingEnumElt);
       }
-      param->getTypeLoc() = TypeLoc(type);
+      param->setTypeRepr(type);
 
       // If there is `@autoclosure` attribute associated with the type
       // let's mark that in the declaration as well, because it
@@ -530,7 +528,8 @@
       // Non-closure parameters require a type.
       if (!param->isInvalid())
         parser.diagnose(param->getLoc(), diag::missing_parameter_type);
-      
+
+      param->setSpecifier(ParamSpecifier::Default);
       setInvalid();
     } else if (paramInfo.SpecifierLoc.isValid()) {
       StringRef specifier;
@@ -552,7 +551,12 @@
                       specifier);
       paramInfo.SpecifierLoc = SourceLoc();
       paramInfo.SpecifierKind = ParamDecl::Specifier::Default;
+
+      param->setSpecifier(ParamSpecifier::Default);
+    } else {
+      param->setSpecifier(ParamSpecifier::Default);
     }
+
     return param;
   };
 
@@ -624,7 +628,7 @@
           .fixItRemove(param.EllipsisLoc);
 
         param.EllipsisLoc = SourceLoc();
-      } else if (!result->getTypeLoc().getTypeRepr()) {
+      } else if (!result->getTypeRepr()) {
         parser.diagnose(param.EllipsisLoc, diag::untyped_pattern_ellipsis)
           .highlight(result->getSourceRange());
 
@@ -896,8 +900,7 @@
                                             /*isExprBasic=*/false,
                                             lParenLoc, args, argLabels,
                                             argLabelLocs, rParenLoc,
-                                            trailingClosure,
-                                            SyntaxKind::Unknown);
+                                            trailingClosure);
         if (status.isSuccess()) {
           backtrack.cancelBacktrack();
           
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index ad4811c..fe52ad6 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -879,11 +879,16 @@
                            lpLoc,
                            yields, yieldLabels, yieldLabelLocs,
                            rpLoc,
-                           trailingClosure,
-                           SyntaxKind::ExprList);
+                           trailingClosure);
     assert(trailingClosure == nullptr);
-    assert(yieldLabels.empty());
-    assert(yieldLabelLocs.empty());
+    if (!yieldLabelLocs.empty()) {
+      for (auto labelLoc : yieldLabelLocs) {
+        if (labelLoc.isValid()) {
+          diagnose(labelLoc, diag::unexpected_arg_label_yield);
+          break;
+        }
+      }
+    }
   } else {
     SourceLoc beginLoc = Tok.getLoc();
 
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index dea6dab..3c0c6d7 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -14,6 +14,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ParseList.h"
 #include "swift/Parse/Parser.h"
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/Attr.h"
@@ -945,9 +946,8 @@
       replacement = "Any";
     } else {
       auto extractText = [&](ParsedTypeSyntax &Type) -> StringRef {
-        auto SourceRange = Type.getRaw()
-          .getDeferredRange(/*includeTrivia=*/false);
-        return SourceMgr.extractText(SourceRange);
+        auto SourceRange = Type.getRaw().getDeferredRange();
+        return SourceMgr.extractText(SourceRange).trim();
       };
       auto Begin = Protocols.begin();
       replacement += extractText(*Begin);
@@ -1007,186 +1007,185 @@
   if (ParsingTypeTuple.isFailed())
     return makeParsedError<ParsedTypeSyntax>();
 
-  SmallVector<ParsedSyntax, 0> Junk;
+  ParsedTupleTypeSyntaxBuilder builder(*SyntaxContext);
 
+  // Parse '('.
   auto LParenLoc = Tok.getLoc();
-  auto LParen = consumeTokenSyntax(tok::l_paren);
+  builder.useLeftParen(consumeTokenSyntax(tok::l_paren));
 
-  Junk.push_back(LParen.copyDeferred());
-
+  // Parse the elements.
   SmallVector<ParsedTupleTypeElementSyntax, 4> Elements;
   SmallVector<std::tuple<SourceLoc, SourceLoc, SourceLoc>, 4> ElementsLoc;
   SourceLoc FirstEllipsisLoc;
+  auto Status = parseListSyntax(
+      Elements, /*AllowEmpty=*/true, /*AllowSepAfterLast=*/false,
+      [&] { return Tok.is(tok::r_paren); },
+      [&](ParsedTupleTypeElementSyntaxBuilder &elemBuilder) {
+        Optional<BacktrackingScope> Backtracking;
 
-  Optional<ParsedTokenSyntax> Comma;
-
-  Optional<ParsedTokenSyntax> RParen;
-
-  ParserStatus Status =
-      parseListSyntax(tok::r_paren, LParenLoc, Comma, RParen, Junk,
-                      false, diag::expected_rparen_tuple_type_list, [&]() {
-    Optional<BacktrackingScope> Backtracking;
-    SmallVector<ParsedSyntax, 0> LocalJunk;
-
-    // 'inout' here can be a obsoleted use of the marker in an argument list,
-    // consume it in backtracking context so we can determine it's really a
-    // deprecated use of it.
-    SourceLoc InOutLoc;
-    Optional<ParsedTokenSyntax> InOut;
-    bool IsInOutObsoleted = false;
-    if (Tok.is(tok::kw_inout)) {
-      InOutLoc = Tok.getLoc();
-      InOut = consumeTokenSyntax(tok::kw_inout);
-      IsInOutObsoleted = true;
-
-      LocalJunk.push_back(InOut->copyDeferred());
-    }
-
-    // If the label is "some", this could end up being an opaque type
-    // description if there's `some <identifier>` without a following colon,
-    // so we may need to backtrack as well.
-    if (Tok.getText().equals("some")) {
-      Backtracking.emplace(*this);
-    }
-
-    // If the tuple element starts with a potential argument label followed by a
-    // ':' or another potential argument label, then the identifier is an
-    // element tag, and it is followed by a type annotation.
-    Optional<ParsedTokenSyntax> Name;
-    Optional<ParsedTokenSyntax> SecondName;
-    Optional<ParsedTokenSyntax> Colon;
-    SourceLoc NameLoc;
-    SourceLoc SecondNameLoc;
-    if (Tok.canBeArgumentLabel() &&
-        (peekToken().is(tok::colon) || peekToken().canBeArgumentLabel())) {
-      // Consume a name.
-      NameLoc = Tok.getLoc();
-      Name = consumeArgumentLabelSyntax();
-
-      // If there is a second name, consume it as well.
-      if (Tok.canBeArgumentLabel()) {
-        SecondNameLoc = Tok.getLoc();
-        SecondName = consumeArgumentLabelSyntax();
-      }
-
-      // Consume the ':'.
-      if ((Colon = consumeTokenSyntaxIf(tok::colon))) {
-        // If we succeed, then we successfully parsed a label.
-        if (Backtracking)
-          Backtracking->cancelBacktrack();
-        // Otherwise, if we can't backtrack to parse this as a type,
-        // this is a syntax error.
-      } else {
-        if (!Backtracking)
-          diagnose(Tok, diag::expected_parameter_colon);
-        NameLoc = SourceLoc();
-        SecondNameLoc = SourceLoc();
-      }
-    } else if (InOut) {
-      // If we don't have labels, 'inout' is not a obsoleted use.
-      IsInOutObsoleted = false;
-    }
-
-    if (!Backtracking || !Backtracking->willBacktrack()) {
-      if (Name)
-        LocalJunk.push_back(Name->copyDeferred());
-      if (SecondName)
-        LocalJunk.push_back(SecondName->copyDeferred());
-      if (Colon)
-        LocalJunk.push_back(Colon->copyDeferred());
-    } else if (Backtracking && Backtracking->willBacktrack()) {
-      Name.reset();
-      SecondName.reset();
-      assert(!Colon.hasValue());
-    }
-    Backtracking.reset();
-
-    // Parse the type annotation.
-    auto TypeLoc = Tok.getLoc();
-    auto ty = parseTypeSyntax(diag::expected_type);
-    if (ty.isError()) {
-      std::move(LocalJunk.begin(), LocalJunk.end(), std::back_inserter(Junk));
-      if (!ty.isNull())
-        Junk.push_back(ty.get());
-      skipListUntilDeclRBraceSyntax(Junk, LParenLoc, tok::r_paren, tok::comma);
-      return ty.getStatus();
-    }
-
-    if (InOut) {
-      if (IsInOutObsoleted) {
-        bool IsTypeAlreadyAttributed = false;
-        if (auto AttributedType = ty.getAs<ParsedAttributedTypeSyntax>()) {
-          IsTypeAlreadyAttributed =
-              AttributedType->getDeferredSpecifier().hasValue();
-          ty = makeParsedResult(std::move(*AttributedType), ty.getStatus());
+        // 'inout' here can be a obsoleted use of the marker in an argument
+        // list, consume it in backtracking context so we can determine it's
+        // really a deprecated use of it.
+        SourceLoc InOutLoc;
+        Optional<ParsedTokenSyntax> InOut;
+        bool IsInOutObsoleted = false;
+        if (Tok.is(tok::kw_inout)) {
+          InOutLoc = Tok.getLoc();
+          InOut = consumeTokenSyntax(tok::kw_inout);
+          IsInOutObsoleted = true;
         }
-        if (IsTypeAlreadyAttributed) {
-          // If the parsed type is already attributed, suggest removing `inout`.
-          diagnose(Tok, diag::parameter_specifier_repeated)
-              .fixItRemove(InOutLoc);
-        } else {
-          diagnose(InOutLoc, diag::parameter_specifier_as_attr_disallowed, "inout")
-              .fixItRemove(InOutLoc)
-              .fixItInsert(TypeLoc, "inout ");
+
+        // If the label is "some", this could end up being an opaque type
+        // description if there's `some <identifier>` without a following colon,
+        // so we may need to backtrack as well.
+        if (Tok.getText().equals("some"))
+          Backtracking.emplace(*this);
+
+        // If the tuple element starts with a potential argument label followed
+        // by a ':' or another potential argument label, then the identifier is
+        // an element tag, and it is followed by a type annotation.
+        Optional<ParsedTokenSyntax> Name;
+        Optional<ParsedTokenSyntax> SecondName;
+        Optional<ParsedTokenSyntax> Colon;
+        SourceLoc NameLoc;
+        SourceLoc SecondNameLoc;
+        if (Tok.canBeArgumentLabel() &&
+            (peekToken().is(tok::colon) || peekToken().canBeArgumentLabel())) {
+          // Consume a name.
+          NameLoc = Tok.getLoc();
+          Name = consumeArgumentLabelSyntax();
+
+          // If there is a second name, consume it as well.
+          if (Tok.canBeArgumentLabel()) {
+            SecondNameLoc = Tok.getLoc();
+            SecondName = consumeArgumentLabelSyntax();
+          }
+
+          // Consume the ':'.
+          if ((Colon = consumeTokenSyntaxIf(tok::colon))) {
+            // If we succeed, then we successfully parsed a label.
+            if (Backtracking)
+              Backtracking->cancelBacktrack();
+            // Otherwise, if we can't backtrack to parse this as a type,
+            // this is a syntax error.
+          } else {
+            if (!Backtracking)
+              diagnose(Tok, diag::expected_parameter_colon);
+            NameLoc = SourceLoc();
+            SecondNameLoc = SourceLoc();
+          }
+        } else if (InOut) {
+          // If we don't have labels, 'inout' is not a obsoleted use.
+          IsInOutObsoleted = false;
         }
-      } else {
-        // Apply 'inout' to the parsed type.
-        ParsedAttributedTypeSyntaxBuilder builder(*SyntaxContext);
-        ty = applyAttributeToTypeSyntax(std::move(ty), std::move(InOut), None);
-        InOut.reset();
-      }
-    }
 
-    Optional<ParsedTokenSyntax> ElementEllipsis;
-    if (Tok.isEllipsis()) {
-      Tok.setKind(tok::ellipsis);
-      auto ElementEllipsisLoc = Tok.getLoc();
-      ElementEllipsis = consumeTokenSyntax();
-      if (!FirstEllipsisLoc.isValid()) {
-        FirstEllipsisLoc = ElementEllipsisLoc;
-      } else {
-        diagnose(ElementEllipsisLoc, diag::multiple_ellipsis_in_tuple)
-            .highlight(FirstEllipsisLoc)
-            .fixItRemove(ElementEllipsisLoc);
-      }
-    }
+        if (!Backtracking || !Backtracking->willBacktrack()) {
+          if (Name)
+            elemBuilder.useName(std::move(*Name));
+          if (SecondName)
+            elemBuilder.useSecondName(std::move(*SecondName));
+          if (Colon)
+            elemBuilder.useColon(std::move(*Colon));
+        } else if (Backtracking && Backtracking->willBacktrack()) {
+          NameLoc = SourceLoc();
+          SecondNameLoc = SourceLoc();
+          Name.reset();
+          SecondName.reset();
+          assert(!Colon.hasValue());
+        }
+        Backtracking.reset();
 
-    Optional<ParsedTokenSyntax> Equal;
-    Optional<ParsedInitializerClauseSyntax> Initializer;
-    if (Tok.is(tok::equal)) {
-      auto EqualLoc = Tok.getLoc();
-      Equal = consumeTokenSyntax(tok::equal);
-      auto Init = parseExpr(diag::expected_init_value);
-      auto InFlight = diagnose(EqualLoc, diag::tuple_type_init);
-      if (Init.isNonNull())
-        InFlight.fixItRemove(SourceRange(EqualLoc, Init.get()->getEndLoc()));
-      Initializer = ParsedSyntaxRecorder::makeInitializerClause(
-          std::move(*Equal),
-          std::move(*SyntaxContext->popIf<ParsedExprSyntax>()),
-          *SyntaxContext);
-    }
+        // Parse the type.
+        auto TypeLoc = Tok.getLoc();
+        auto ty = parseTypeSyntax(diag::expected_type);
+        if (ty.isNull()) {
+          ty = makeParsedResult(
+              ParsedSyntaxRecorder::makeUnknownType({}, *SyntaxContext),
+              ty.getStatus());
+        }
 
-    Comma = consumeTokenSyntaxIf(tok::comma);
+        // Handle pre-parsed 'inout'.
+        if (InOut) {
+          if (IsInOutObsoleted) {
+            elemBuilder.useInOut(std::move(*InOut));
+            bool IsTypeAlreadyAttributed = false;
+            if (!ty.isNull()) {
+              if (auto AttributedType =
+                      ty.getAs<ParsedAttributedTypeSyntax>()) {
+                IsTypeAlreadyAttributed =
+                    AttributedType->getDeferredSpecifier().hasValue();
+                ty = makeParsedResult(std::move(*AttributedType),
+                                      ty.getStatus());
+              }
+            }
+            if (IsTypeAlreadyAttributed) {
+              // If the parsed type is already attributed, suggest removing
+              // `inout`.
+              diagnose(Tok, diag::parameter_specifier_repeated)
+                  .fixItRemove(InOutLoc);
+            } else {
+              diagnose(InOutLoc, diag::parameter_specifier_as_attr_disallowed,
+                       "inout")
+                  .fixItRemove(InOutLoc)
+                  .fixItInsert(TypeLoc, "inout ");
+            }
+          } else {
+            // Apply 'inout' to the parsed type.
+            ParsedAttributedTypeSyntaxBuilder builder(*SyntaxContext);
+            ty = applyAttributeToTypeSyntax(std::move(ty), std::move(InOut),
+                                            None);
+            TypeLoc = InOutLoc;
+            InOutLoc = SourceLoc();
+            InOut.reset();
+          }
+        }
+        if (!ty.isNull())
+          elemBuilder.useType(ty.get());
+        ElementsLoc.emplace_back(NameLoc, SecondNameLoc, TypeLoc);
+        if (ty.isError())
+          return ty.getStatus();
 
-    auto Element = ParsedSyntaxRecorder::makeTupleTypeElement(
-        std::move(InOut), std::move(Name), std::move(SecondName),
-        std::move(Colon), ty.get(), std::move(ElementEllipsis),
-        std::move(Initializer), std::move(Comma), *SyntaxContext);
+        // Parse '...'.
+        if (Tok.isEllipsis()) {
+          auto ElementEllipsisLoc = Tok.getLoc();
+          Tok.setKind(tok::ellipsis);
+          elemBuilder.useEllipsis(consumeTokenSyntax(tok::ellipsis));
+          if (!FirstEllipsisLoc.isValid()) {
+            FirstEllipsisLoc = ElementEllipsisLoc;
+          } else {
+            diagnose(ElementEllipsisLoc, diag::multiple_ellipsis_in_tuple)
+                .highlight(FirstEllipsisLoc)
+                .fixItRemove(ElementEllipsisLoc);
+          }
+        }
 
-    Junk.push_back(Element.copyDeferred());
+        // Parse the initializer ('=' expr).
+        if (Tok.is(tok::equal)) {
+          ParsedInitializerClauseSyntaxBuilder initBuilder(*SyntaxContext);
+          auto EqualLoc = Tok.getLoc();
+          initBuilder.useEqual(consumeTokenSyntax(tok::equal));
+          SyntaxParsingContext tmpCtxt(SyntaxContext);
+          tmpCtxt.setTransparent();
+          auto Init = parseExpr(diag::expected_init_value);
+          auto InFlight = diagnose(EqualLoc, diag::tuple_type_init);
+          if (Init.isNonNull())
+            InFlight.fixItRemove(SourceRange(EqualLoc, PreviousLoc));
+          if (auto expr = SyntaxContext->popIf<ParsedExprSyntax>())
+            initBuilder.useValue(std::move(*expr));
+          else
+            initBuilder.useValue(
+                ParsedSyntaxRecorder::makeUnknownExpr({}, *SyntaxContext));
+          elemBuilder.useInitializer(initBuilder.build());
+        }
 
-    Elements.push_back(std::move(Element));
-    ElementsLoc.emplace_back(NameLoc, SecondNameLoc, TypeLoc);
+        return makeParserSuccess();
+      });
 
-    return makeParserSuccess();
-  });
-
-  if (!Status.isSuccess()) {
-    if (RParen)
-      Junk.push_back(std::move(*RParen));
-    auto ty = ParsedSyntaxRecorder::makeUnknownType(Junk, *SyntaxContext);
-    return makeParsedResult(std::move(ty), Status);
-  }
+  // Parse ')'.
+  auto RParen = parseMatchingTokenSyntax(
+      tok::r_paren, diag::expected_rparen_tuple_type_list, LParenLoc,
+      /*silenceDiag=*/Status.isError());
+  Status |= RParen.getStatus();
 
   bool IsFunctionType = Tok.isAny(tok::arrow, tok::kw_throws, tok::kw_rethrows);
 
@@ -1242,15 +1241,12 @@
       }
     }
   }
+  for (auto &elem : Elements)
+    builder.addElementsMember(std::move(elem));
+  if (!RParen.isNull())
+    builder.useRightParen(RParen.get());
 
-  auto ElementList =
-      ParsedSyntaxRecorder::makeTupleTypeElementList(Elements, *SyntaxContext);
-
-  auto TupleType = ParsedSyntaxRecorder::makeTupleType(
-      std::move(LParen), std::move(ElementList), std::move(*RParen),
-      *SyntaxContext);
-
-  return makeParsedResult(std::move(TupleType));
+  return makeParsedResult(builder.build(), Status);
 }
 
 /// parseTypeArray - Parse the type-array production, given that we
diff --git a/lib/Parse/ParsedRawSyntaxNode.cpp b/lib/Parse/ParsedRawSyntaxNode.cpp
index 608381d..778e331 100644
--- a/lib/Parse/ParsedRawSyntaxNode.cpp
+++ b/lib/Parse/ParsedRawSyntaxNode.cpp
@@ -21,18 +21,31 @@
 ParsedRawSyntaxNode::makeDeferred(SyntaxKind k,
                                   MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
                                   SyntaxParsingContext &ctx) {
+  CharSourceRange range;
   if (deferredNodes.empty()) {
-    return ParsedRawSyntaxNode(k, {});
+    return ParsedRawSyntaxNode(k, range, {});
   }
   ParsedRawSyntaxNode *newPtr =
     ctx.getScratchAlloc().Allocate<ParsedRawSyntaxNode>(deferredNodes.size());
 
-  // uninitialized move;
   auto ptr = newPtr;
-  for (auto &node : deferredNodes)
-    :: new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
+  for (auto &node : deferredNodes) {
+    // Cached range.
+    if (!node.isNull() && !node.isMissing()) {
+      auto nodeRange = node.getDeferredRange();
+      if (nodeRange.isValid()) {
+        if (range.isInvalid())
+          range = nodeRange;
+        else
+          range.widen(nodeRange);
+      }
+    }
 
-  return ParsedRawSyntaxNode(k, makeMutableArrayRef(newPtr, deferredNodes.size()));
+    // uninitialized move;
+    :: new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
+  }
+  return ParsedRawSyntaxNode(k, range,
+                             makeMutableArrayRef(newPtr, deferredNodes.size()));
 }
 
 ParsedRawSyntaxNode
diff --git a/lib/Parse/ParsedRawSyntaxRecorder.cpp b/lib/Parse/ParsedRawSyntaxRecorder.cpp
index 17ef251..51b6677 100644
--- a/lib/Parse/ParsedRawSyntaxRecorder.cpp
+++ b/lib/Parse/ParsedRawSyntaxRecorder.cpp
@@ -138,7 +138,7 @@
       continue;
     CharSourceRange range = elem.isRecorded()
       ? elem.getRecordedRange()
-      : elem.getDeferredRange(/*includeTrivia=*/true);
+      : elem.getDeferredRange();
     if (range.isValid()) {
       assert((prevEndLoc.isInvalid() || range.getStart() == prevEndLoc)
              && "Non-contiguous child ranges?");
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 2c07e46..3c14fd8 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -755,6 +755,7 @@
 }
 
 void Parser::ignoreToken() {
+  assert(!Tok.is(tok::eof) && "Lexing eof token");
   ParsedTriviaList Skipped;
   Skipped.reserve(LeadingTrivia.size() + TrailingTrivia.size() + 1 + 2);
   std::move(LeadingTrivia.begin(), LeadingTrivia.end(),
@@ -764,7 +765,7 @@
             std::back_inserter(Skipped));
 
   TokReceiver->receive(Tok);
-  consumeTokenWithoutFeedingReceiver();
+  L->lex(Tok, LeadingTrivia, TrailingTrivia);
 
   std::move(LeadingTrivia.begin(), LeadingTrivia.end(),
             std::back_inserter(Skipped));
@@ -1330,88 +1331,6 @@
 }
 
 ParserStatus
-Parser::parseListSyntax(tok RightK, SourceLoc LeftLoc,
-                        Optional<ParsedTokenSyntax> &LastComma,
-                        Optional<ParsedTokenSyntax> &Right,
-                        SmallVectorImpl<ParsedSyntax>& Junk,
-                        bool AllowSepAfterLast, Diag<> ErrorDiag,
-                        llvm::function_ref<ParserStatus()> callback) {
-  auto TokIsStringInterpolationEOF = [&]() -> bool {
-    return Tok.is(tok::eof) && Tok.getText() == ")" && RightK == tok::r_paren;
-  };
-
-  if (Tok.is(RightK)) {
-    Right = consumeTokenSyntax(RightK);
-    return makeParserSuccess();
-  }
-  if (TokIsStringInterpolationEOF()) {
-    Tok.setKind(RightK);
-    Right = consumeTokenSyntax();
-    return makeParserSuccess();
-  }
-
-  ParserStatus Status;
-  while (true) {
-    while (Tok.is(tok::comma)) {
-      diagnose(Tok, diag::unexpected_separator, ",")
-          .fixItRemove(SourceRange(Tok.getLoc()));
-      auto Comma = consumeTokenSyntax();
-      Junk.push_back(std::move(Comma));
-    }
-    SourceLoc StartLoc = Tok.getLoc();
-
-    Status |= callback();
-    if (Tok.is(RightK))
-      break;
-    // If the lexer stopped with an EOF token whose spelling is ")", then this
-    // is actually the tuple that is a string literal interpolation context.
-    // Just accept the ")" and build the tuple as we usually do.
-    if (TokIsStringInterpolationEOF()) {
-      Tok.setKind(RightK);
-      Right = consumeTokenSyntax();
-      return Status;
-    }
-    // If we haven't made progress, or seeing any error, skip ahead.
-    if (Tok.getLoc() == StartLoc || Status.isError()) {
-      assert(Status.isError() && "no progress without error");
-      skipListUntilDeclRBraceSyntax(Junk, LeftLoc, RightK, tok::comma);
-      if (Tok.is(RightK) || Tok.isNot(tok::comma))
-        break;
-    }
-    if (LastComma) {
-      if (Tok.isNot(RightK))
-        continue;
-      if (!AllowSepAfterLast) {
-        diagnose(Tok, diag::unexpected_separator, ",")
-            .fixItRemove(SourceRange(PreviousLoc));
-      }
-      break;
-    }
-    // If we're in a comma-separated list, the next token is at the
-    // beginning of a new line and can never start an element, break.
-    if (Tok.isAtStartOfLine() &&
-        (Tok.is(tok::r_brace) || isStartOfDecl() || isStartOfStmt())) {
-      break;
-    }
-    // If we found EOF or such, bailout.
-    if (Tok.isAny(tok::eof, tok::pound_endif)) {
-      IsInputIncomplete = true;
-      break;
-    }
-
-    diagnose(Tok, diag::expected_separator, ",")
-        .fixItInsertAfter(PreviousLoc, ",");
-    Status.setIsParseError();
-  }
-
-  auto RightResult = parseMatchingTokenSyntax(RightK, ErrorDiag, LeftLoc,
-                                              Status.isError());
-  Status |= RightResult.getStatus();
-  Right = RightResult.getOrNull();
-  return Status;
-}
-
-ParserStatus
 Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
                   bool AllowSepAfterLast, Diag<> ErrorDiag, SyntaxKind Kind,
                   llvm::function_ref<ParserStatus()> callback) {
diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.cpp b/lib/PrintAsObjC/DeclAndTypePrinter.cpp
index 64fd30b..c9a05d3 100644
--- a/lib/PrintAsObjC/DeclAndTypePrinter.cpp
+++ b/lib/PrintAsObjC/DeclAndTypePrinter.cpp
@@ -2034,7 +2034,7 @@
 }
 
 void DeclAndTypePrinter::printAdHocCategory(
-    llvm::iterator_range<const ValueDecl * const *> members) {
+    iterator_range<const ValueDecl * const *> members) {
   getImpl().printAdHocCategory(members);
 }
 
diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.h b/lib/PrintAsObjC/DeclAndTypePrinter.h
index fc7a51f..61d159a 100644
--- a/lib/PrintAsObjC/DeclAndTypePrinter.h
+++ b/lib/PrintAsObjC/DeclAndTypePrinter.h
@@ -74,7 +74,7 @@
   ///
   /// All members must have the same parent type. The list must not be empty.
   void
-  printAdHocCategory(llvm::iterator_range<const ValueDecl * const *> members);
+  printAdHocCategory(iterator_range<const ValueDecl * const *> members);
 
   /// Returns the name of an <os/object.h> type minus the leading "OS_",
   /// or an empty string if \p decl is not an <os/object.h> type.
diff --git a/lib/SIL/Projection.cpp b/lib/SIL/Projection.cpp
index f40d790..3e09018 100644
--- a/lib/SIL/Projection.cpp
+++ b/lib/SIL/Projection.cpp
@@ -1284,7 +1284,7 @@
 
     // If node is not a leaf, add its children to the worklist and continue.
     if (!Node->ChildProjections.empty()) {
-      for (unsigned ChildIdx : reversed(Node->ChildProjections)) {
+      for (unsigned ChildIdx : llvm::reverse(Node->ChildProjections)) {
         Worklist.push_back(getNode(ChildIdx));
       }
       continue;
@@ -1337,7 +1337,7 @@
 
       // Create projections for each one of them and the child node and
       // projection to the worklist for processing.
-      for (unsigned ChildIdx : reversed(Node->ChildProjections)) {
+      for (unsigned ChildIdx : llvm::reverse(Node->ChildProjections)) {
         const ProjectionTreeNode *ChildNode = getNode(ChildIdx);
         auto I = ChildNode->createProjection(B, Loc, V).get();
         LLVM_DEBUG(llvm::dbgs() << "    Adding Child: " << I->getType() << ": "
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 900eb40..deb21f5 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -2109,13 +2109,14 @@
         require(initConv.getNumDirectSILResults() == 1,
                 "wrong number of init function results");
         require(Dest->getType().getObjectType() ==
-                initConv.getDirectSILResultTypes().front(),
+                *initConv.getDirectSILResultTypes().begin(),
                 "wrong init function result type");
         break;
       case 1:
         require(initConv.getNumDirectSILResults() == 0,
                 "wrong number of init function results");
-        require(Dest->getType() == initConv.getIndirectSILResultTypes().front(),
+        require(Dest->getType() ==
+                *initConv.getIndirectSILResultTypes().begin(),
                 "wrong indirect init function result type");
         break;
       default:
diff --git a/lib/SILGen/ResultPlan.h b/lib/SILGen/ResultPlan.h
index 80a69db..93d0db8 100644
--- a/lib/SILGen/ResultPlan.h
+++ b/lib/SILGen/ResultPlan.h
@@ -68,7 +68,7 @@
                     const CalleeTypeInfo &calleeTypeInfo)
       : SGF(SGF), loc(loc), calleeTypeInfo(calleeTypeInfo),
         // We reverse the order so we can pop values off the back.
-        allResults(reversed(calleeTypeInfo.substFnType->getResults())) {}
+        allResults(llvm::reverse(calleeTypeInfo.substFnType->getResults())) {}
 
   ResultPlanPtr build(Initialization *emitInto, AbstractionPattern origType,
                       CanType substType);
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 05adcf8..748f2d8 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -4198,7 +4198,7 @@
   }
 
   // Uncurry the arguments in calling convention order.
-  for (auto &argSet : reversed(args))
+  for (auto &argSet : llvm::reverse(args))
     uncurriedArgs.append(argSet.begin(), argSet.end());
   args = {};
 
@@ -5006,6 +5006,44 @@
   return emission.apply(C);
 }
 
+RValue SILGenFunction::emitApplyOfPropertyWrapperBackingInitializer(
+    SILLocation loc,
+    VarDecl *var,
+    RValue &&originalValue,
+    SGFContext C) {
+  SILDeclRef constant(var, SILDeclRef::Kind::PropertyWrapperBackingInitializer);
+
+  SubstitutionMap subs;
+  auto varDC = var->getInnermostDeclContext();
+  if (auto genericSig = varDC->getGenericSignatureOfContext()) {
+    subs = SubstitutionMap::get(
+        genericSig,
+        [&](SubstitutableType *type) {
+          if (auto gp = type->getAs<GenericTypeParamType>()) {
+            return F.mapTypeIntoContext(gp);
+          }
+
+          return Type(type);
+        },
+        LookUpConformanceInModule(varDC->getParentModule()));
+  }
+
+  FormalEvaluationScope writebackScope(*this);
+
+  auto callee = Callee::forDirect(*this, constant, subs, loc);
+  auto substFnType = callee.getSubstFormalType();
+
+  CallEmission emission(*this, std::move(callee), std::move(writebackScope));
+
+  PreparedArguments args(substFnType->getAs<AnyFunctionType>()->getParams());
+  args.add(loc, std::move(originalValue));
+  emission.addCallSite(loc, std::move(args),
+                       substFnType->getResult()->getCanonicalType(),
+                       /*throws=*/false);
+  
+  return emission.apply(C);
+}
+
 /// Emit a literal that applies the various initializers.
 RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
   ConcreteDeclRef builtinInit;
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index 6c31bc3..69a2eb9 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -42,9 +42,10 @@
   auto *DC = ctor->getInnermostDeclContext();
   auto &AC = SGF.getASTContext();
   auto VD =
-      new (AC) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+      new (AC) ParamDecl(SourceLoc(), SourceLoc(),
                          AC.getIdentifier("$metatype"), SourceLoc(),
                          AC.getIdentifier("$metatype"), DC);
+  VD->setSpecifier(ParamSpecifier::Default);
   VD->setInterfaceType(metatype);
 
   SGF.AllocatorMetatype = SGF.F.begin()->createFunctionArgument(
@@ -69,11 +70,12 @@
   }
 
   auto &AC = SGF.getASTContext();
-  auto VD = new (AC) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+  auto VD = new (AC) ParamDecl(SourceLoc(), SourceLoc(),
                                AC.getIdentifier("$implicit_value"),
                                SourceLoc(),
                                AC.getIdentifier("$implicit_value"),
                                DC);
+  VD->setSpecifier(ParamSpecifier::Default);
   VD->setInterfaceType(interfaceType);
 
   auto argType = SGF.SGM.Types.getLoweredType(type,
@@ -133,12 +135,12 @@
   SILValue resultSlot;
   if (SILModuleConventions::isReturnedIndirectlyInSIL(selfTy, SGF.SGM.M)) {
     auto &AC = SGF.getASTContext();
-    auto VD = new (AC) ParamDecl(ParamDecl::Specifier::InOut,
-                                 SourceLoc(), SourceLoc(),
+    auto VD = new (AC) ParamDecl(SourceLoc(), SourceLoc(),
                                  AC.getIdentifier("$return_value"),
                                  SourceLoc(),
                                  AC.getIdentifier("$return_value"),
                                  ctor);
+    VD->setSpecifier(ParamSpecifier::InOut);
     VD->setInterfaceType(selfIfaceTy);
     resultSlot = SGF.F.begin()->createFunctionArgument(selfTy.getAddressType(), VD);
   }
@@ -425,12 +427,12 @@
   std::unique_ptr<Initialization> dest;
   if (enumTI.isAddressOnly() && silConv.useLoweredAddresses()) {
     auto &AC = getASTContext();
-    auto VD = new (AC) ParamDecl(ParamDecl::Specifier::InOut,
-                                 SourceLoc(), SourceLoc(),
+    auto VD = new (AC) ParamDecl(SourceLoc(), SourceLoc(),
                                  AC.getIdentifier("$return_value"),
                                  SourceLoc(),
                                  AC.getIdentifier("$return_value"),
-                                 element->getDeclContext());
+                                 element->getDeclContext());  
+    VD->setSpecifier(ParamSpecifier::InOut);
     VD->setInterfaceType(enumIfaceTy);
     auto resultSlot =
         F.begin()->createFunctionArgument(enumTI.getLoweredType(), VD);
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 1f91f7f..874ac50 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -2250,46 +2250,6 @@
                    subs, {}, calleeTypeInfo, ApplyOptions::None, C);
 }
 
-RValue SILGenFunction::emitApplyOfPropertyWrapperBackingInitializer(
-    SILLocation loc,
-    VarDecl *var,
-    RValue &&originalValue,
-    SGFContext C) {
-  SILDeclRef constant(var, SILDeclRef::Kind::PropertyWrapperBackingInitializer);
-  auto fnRef = ManagedValue::forUnmanaged(emitGlobalFunctionRef(loc, constant));
-  auto fnType = fnRef.getType().castTo<SILFunctionType>();
-
-  SubstitutionMap subs;
-  auto varDC = var->getInnermostDeclContext();
-  if (auto genericSig = varDC->getGenericSignatureOfContext()) {
-    subs = SubstitutionMap::get(
-        genericSig,
-        [&](SubstitutableType *type) {
-          if (auto gp = type->getAs<GenericTypeParamType>()) {
-            return F.mapTypeIntoContext(gp);
-          }
-
-          return Type(type);
-        },
-        LookUpConformanceInModule(varDC->getParentModule()));
-  }
-
-  auto substFnType = fnType->substGenericArgs(SGM.M, subs);
-
-  CanType resultType =
-      F.mapTypeIntoContext(var->getPropertyWrapperBackingPropertyType())
-        ->getCanonicalType();
-  AbstractionPattern origResultType(resultType);
-  CalleeTypeInfo calleeTypeInfo(substFnType, origResultType, resultType);
-  ResultPlanPtr resultPlan =
-      ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
-  ArgumentScope argScope(*this, loc);
-  SmallVector<ManagedValue, 2> args;
-  std::move(originalValue).getAll(args);
-  return emitApply(std::move(resultPlan), std::move(argScope), loc, fnRef, subs,
-                   args, calleeTypeInfo, ApplyOptions::None, C);
-}
-
 RValue RValueEmitter::visitDestructureTupleExpr(DestructureTupleExpr *E,
                                                 SGFContext C) {
   // Emit the sub-expression tuple and destructure it into elements.
@@ -5600,7 +5560,7 @@
           SGFContext::AllowImmediatePlusZero).getAsSingleValue(*this, LE);
     }
 
-    for (auto &FVE : reversed(forceValueExprs)) {
+    for (auto &FVE : llvm::reverse(forceValueExprs)) {
       const TypeLowering &optTL = getTypeLowering(FVE->getSubExpr()->getType());
       bool isImplicitUnwrap = FVE->isImplicit() &&
           FVE->isForceOfImplicitlyUnwrappedOptional();
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index 0083351..cfca3ce 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -692,12 +692,12 @@
   ParameterList *params = nullptr;
   if (function.kind == SILDeclRef::Kind::PropertyWrapperBackingInitializer) {
     auto &ctx = getASTContext();
-    auto param = new (ctx) ParamDecl(ParamDecl::Specifier::Owned,
-                                     SourceLoc(), SourceLoc(),
+    auto param = new (ctx) ParamDecl(SourceLoc(), SourceLoc(),
                                      ctx.getIdentifier("$input_value"),
                                      SourceLoc(),
                                      ctx.getIdentifier("$input_value"),
                                      dc);
+    param->setSpecifier(ParamSpecifier::Owned);
     param->setInterfaceType(function.getDecl()->getInterfaceType());
 
     params = ParameterList::create(ctx, SourceLoc(), {param}, SourceLoc());
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 4fe49d6..a601027 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -1366,19 +1366,30 @@
                                  std::move(value), isSelfParameter);
     }
 
+    /// Determine whether the backing variable for the given
+    /// property (that has a wrapper) is visible from the
+    /// current context.
+    static bool isBackingVarVisible(VarDecl *field,
+                                    DeclContext *fromDC){
+      VarDecl *backingVar = field->getPropertyWrapperBackingProperty();
+      return backingVar->isAccessibleFrom(fromDC);
+    }
+
     void set(SILGenFunction &SGF, SILLocation loc,
              ArgumentSource &&value, ManagedValue base) && override {
       assert(getAccessorDecl()->isSetter());
       SILDeclRef setter = Accessor;
 
-      if (hasPropertyWrapper() && IsOnSelfParameter) {
+      if (hasPropertyWrapper() && IsOnSelfParameter &&
+          isBackingVarVisible(cast<VarDecl>(Storage),
+                              SGF.FunctionDC)) {
         // This is wrapped property. Instead of emitting a setter, emit an
         // assign_by_wrapper with the allocating initializer function and the
         // setter function as arguments. DefiniteInitializtion will then decide
         // between the two functions, depending if it's an initialization or a
         // re-assignment.
         //
-        VarDecl *field = dyn_cast<VarDecl>(Storage);
+        VarDecl *field = cast<VarDecl>(Storage);
         VarDecl *backingVar = field->getPropertyWrapperBackingProperty();
         assert(backingVar);
         CanType ValType =
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 7978d11..0821883 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -3655,7 +3655,7 @@
       CleanupLocation::get(loc), NotForUnwind);
 
   // Deallocate local allocations.
-  for (auto *alloc : reversed(localAllocations))
+  for (auto *alloc : llvm::reverse(localAllocations))
     thunkSGF.B.createDeallocStack(loc, alloc);
 
   // Create return.
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index 9ac66bd..ee839f3 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -498,11 +498,11 @@
     return;
   }
   auto &ctx = SGF.getASTContext();
-  auto var = new (ctx) ParamDecl(ParamDecl::Specifier::InOut,
-                                 SourceLoc(), SourceLoc(),
+  auto var = new (ctx) ParamDecl(SourceLoc(), SourceLoc(),
                                  ctx.getIdentifier("$return_value"), SourceLoc(),
                                  ctx.getIdentifier("$return_value"),
                                  DC);
+  var->setSpecifier(ParamSpecifier::InOut);
   var->setInterfaceType(resultType);
 
   auto *arg =
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index c015135..b5ac3ff 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -174,7 +174,8 @@
   auto thunk = builder.createFunction(
       SILLinkage::Private, name, overrideInfo.SILFnType,
       cast<AbstractFunctionDecl>(derivedDecl)->getGenericEnvironment(), loc,
-      IsBare, IsNotTransparent, IsNotSerialized, IsNotDynamic);
+      IsBare, IsNotTransparent, IsNotSerialized, IsNotDynamic,
+      ProfileCounter(), IsThunk);
   thunk->setDebugScope(new (M) SILDebugScope(loc, thunk));
 
   PrettyStackTraceSILFunction trace("generating vtable thunk", thunk);
diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
index f600f0d..2948100 100644
--- a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
@@ -899,7 +899,7 @@
   // release.
   bool isTrackingInArgs = isOneOfConventions(SILArgumentConvention::Indirect_In,
                                              ArgumentConventions);
-  for (auto &inst : reversed(*block)) {
+  for (auto &inst : llvm::reverse(*block)) {
     if (isTrackingInArgs && isa<DestroyAddrInst>(inst)) {
       // It is probably a destroy addr for an @in argument.
       continue;
diff --git a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
index 61ceed8..9281061 100644
--- a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
@@ -564,7 +564,7 @@
   llvm::raw_string_ostream os(sbuf);
 
   SILType containingType = baseType;
-  for (unsigned index : reversed(reversedIndices)) {
+  for (unsigned index : llvm::reverse(reversedIndices)) {
     os << ".";
 
     if (StructDecl *D = containingType.getStructOrBoundGenericStruct()) {
diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp
index 37f1fba..a680bec 100644
--- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp
+++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp
@@ -109,7 +109,7 @@
     for (SILValue cleanupVal : CleanupValues)
       Builder.createDestroyAddr(loc, cleanupVal);
 
-    for (auto *ASI : reversed(AllocStackInsts))
+    for (auto *ASI : llvm::reverse(AllocStackInsts))
       Builder.createDeallocStack(loc, ASI);
   }
 }
@@ -545,7 +545,7 @@
     ReturnValue = Builder.createApply(Loc, FRI, SubMap, ApplyArgs);
   }
   auto cleanupLoc = RegularLocation::getAutoGeneratedLocation();
-  for (auto &Temp : reversed(Temps)) {
+  for (auto &Temp : llvm::reverse(Temps)) {
     // The original argument was copied into a temporary and consumed by the
     // callee as such:
     //   bb (%consumedExistential : $*Protocol)
diff --git a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
index 6e35172..ab574e1 100644
--- a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
@@ -143,7 +143,7 @@
 bool AccessMarkerElimination::stripMarkers() {
   // Iterating in reverse eliminates more begin_access users before they
   // need to be replaced.
-  for (auto &BB : reversed(*F)) {
+  for (auto &BB : llvm::reverse(*F)) {
     // Don't cache the begin iterator since we're reverse iterating.
     for (auto II = BB.end(); II != BB.begin();) {
       SILInstruction *inst = &*(--II);
diff --git a/lib/SILOptimizer/Mandatory/AddressLowering.cpp b/lib/SILOptimizer/Mandatory/AddressLowering.cpp
index 061bdab..580ebe2 100644
--- a/lib/SILOptimizer/Mandatory/AddressLowering.cpp
+++ b/lib/SILOptimizer/Mandatory/AddressLowering.cpp
@@ -408,7 +408,7 @@
 
   // Create an AllocStack for every opaque value defined in the function.  Visit
   // values in post-order to create storage for aggregates before subobjects.
-  for (auto &valueStorageI : reversed(pass.valueStorageMap))
+  for (auto &valueStorageI : llvm::reverse(pass.valueStorageMap))
     allocateForValue(valueStorageI.first, valueStorageI.second);
 }
 
@@ -460,10 +460,11 @@
   for (auto resultTy : pass.loweredFnConv.getIndirectSILResultTypes()) {
     auto bodyResultTy = pass.F->mapTypeIntoContext(resultTy);
     auto var = new (ctx)
-        ParamDecl(ParamDecl::Specifier::InOut, SourceLoc(), SourceLoc(),
+        ParamDecl(SourceLoc(), SourceLoc(),
                   ctx.getIdentifier("$return_value"), SourceLoc(),
                   ctx.getIdentifier("$return_value"),
                   pass.F->getDeclContext());
+    var->setSpecifier(ParamSpecifier::InOut);
 
     pass.F->begin()->insertFunctionArgument(argIdx,
                                             bodyResultTy.getAddressType(),
@@ -1507,7 +1508,7 @@
   //
   // Add the rest of the instructions to the dead list in post order.
   // FIXME: make sure we cleaned up address-only BB arguments.
-  for (auto &valueStorageI : reversed(pass.valueStorageMap)) {
+  for (auto &valueStorageI : llvm::reverse(pass.valueStorageMap)) {
     // TODO: MultiValueInstruction: ApplyInst
     auto *deadInst = dyn_cast<SingleValueInstruction>(valueStorageI.first);
     if (!deadInst)
diff --git a/lib/SILOptimizer/Mandatory/Differentiation.cpp b/lib/SILOptimizer/Mandatory/Differentiation.cpp
index 9de5260..166c21b 100644
--- a/lib/SILOptimizer/Mandatory/Differentiation.cpp
+++ b/lib/SILOptimizer/Mandatory/Differentiation.cpp
@@ -32,6 +32,7 @@
 #include "swift/AST/Expr.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/GenericSignatureBuilder.h"
+#include "swift/AST/LazyResolver.h"
 #include "swift/AST/SourceFile.h"
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/SubstitutionMap.h"
@@ -574,7 +575,7 @@
       branchingTraceDecl->setGenericSignature(genericSig);
     computeAccessLevel(branchingTraceDecl,
                        original->getEffectiveSymbolLinkage());
-    branchingTraceDecl->computeType();
+    branchingTraceDecl->getInterfaceType();
     assert(branchingTraceDecl->hasInterfaceType());
     file.addVisibleDecl(branchingTraceDecl);
     // Add basic block enum cases.
@@ -585,9 +586,9 @@
       auto linearMapStructTy =
           linearMapStruct->getDeclaredInterfaceType()->getCanonicalType();
       // Create dummy declaration representing enum case parameter.
-      auto *decl = new (astCtx)
-          ParamDecl(ParamDecl::Specifier::Default, loc, loc, Identifier(), loc,
-                    Identifier(), moduleDecl);
+      auto *decl = new (astCtx) ParamDecl(loc, loc, Identifier(), loc,
+                                          Identifier(), moduleDecl);
+      decl->setSpecifier(ParamDecl::Specifier::Default);
       if (linearMapStructTy->hasArchetype())
         decl->setInterfaceType(linearMapStructTy->mapTypeOutOfContext());
       else
@@ -598,7 +599,7 @@
           /*IdentifierLoc*/ loc, DeclName(astCtx.getIdentifier(bbId)),
           paramList, loc, /*RawValueExpr*/ nullptr, branchingTraceDecl);
       enumEltDecl->setImplicit();
-      enumEltDecl->computeType();
+      enumEltDecl->getInterfaceType();
       auto *enumCaseDecl = EnumCaseDecl::create(
           /*CaseLoc*/ loc, {enumEltDecl}, branchingTraceDecl);
       enumCaseDecl->setImplicit();
@@ -653,7 +654,7 @@
       linearMapStruct->setGenericSignature(genericSig);
     computeAccessLevel(
         linearMapStruct, original->getEffectiveSymbolLinkage());
-    linearMapStruct->computeType();
+    linearMapStruct->getInterfaceType();
     assert(linearMapStruct->hasInterfaceType());
     file.addVisibleDecl(linearMapStruct);
     return linearMapStruct;
@@ -2011,7 +2012,7 @@
   // Propagate usefulness through the function in post-dominance order.
   PostDominanceOrder postDomOrder(&*function.findReturnBB(), pdi);
   while (auto *bb = postDomOrder.getNext()) {
-    for (auto &inst : reversed(*bb)) {
+    for (auto &inst : llvm::reverse(*bb)) {
       for (auto i : indices(outputValues)) {
         // Handle indirect results in `apply`.
         if (auto *ai = dyn_cast<ApplyInst>(&inst)) {
@@ -3233,7 +3234,7 @@
   auto retVal = joinElements(results, builder, loc);
 
   // Deallocate local allocations.
-  for (auto *alloc : reversed(localAllocations))
+  for (auto *alloc : llvm::reverse(localAllocations))
     builder.createDeallocStack(loc, alloc);
 
   // Create return.
@@ -6604,7 +6605,7 @@
       auto &s = getADDebugStream()
           << "Original bb" + std::to_string(bb->getDebugID())
           << ": To differentiate or not to differentiate?\n";
-      for (auto &inst : reversed(*bb)) {
+      for (auto &inst : llvm::reverse(*bb)) {
         s << (getPullbackInfo().shouldDifferentiateInstruction(&inst)
                   ? "[∂] " : "[ ] ")
           << inst;
@@ -6612,7 +6613,7 @@
     });
 
     // Visit each instruction in reverse order.
-    for (auto &inst : reversed(*bb)) {
+    for (auto &inst : llvm::reverse(*bb)) {
       if (!getPullbackInfo().shouldDifferentiateInstruction(&inst))
         continue;
       // Differentiate instruction.
@@ -6975,7 +6976,7 @@
       }
     }
     // Destroy and deallocate pullback indirect results.
-    for (auto *alloc : reversed(pullbackIndirectResults)) {
+    for (auto *alloc : llvm::reverse(pullbackIndirectResults)) {
       builder.emitDestroyAddrAndFold(loc, alloc);
       builder.createDeallocStack(loc, alloc);
     }
@@ -8308,7 +8309,7 @@
   // If differential thunk, deallocate local allocations and directly return
   // `apply` result.
   if (kind == AutoDiffDerivativeFunctionKind::JVP) {
-    for (auto *alloc : reversed(localAllocations))
+    for (auto *alloc : llvm::reverse(localAllocations))
       builder.createDeallocStack(loc, alloc);
     builder.createReturn(loc, ai);
     return {thunk, interfaceSubs};
@@ -8341,7 +8342,7 @@
     }
   }
   // Deallocate local allocations and return final direct result.
-  for (auto *alloc : reversed(localAllocations))
+  for (auto *alloc : llvm::reverse(localAllocations))
     builder.createDeallocStack(loc, alloc);
   auto result = joinElements(results, builder, loc);
   builder.createReturn(loc, result);
@@ -8689,7 +8690,7 @@
     derivativeFns.push_back(derivativeFn);
   }
   // Deallocate temporary buffers used for creating derivative functions.
-  for (auto *buf : reversed(newBuffersToDealloc))
+  for (auto *buf : llvm::reverse(newBuffersToDealloc))
     builder.createDeallocStack(loc, buf);
 
   auto origFnCopy = builder.emitCopyValueOperation(loc, origFnOperand);
diff --git a/lib/SILOptimizer/Mandatory/Differentiation.h b/lib/SILOptimizer/Mandatory/Differentiation.h
index 00ef4be..c197896 100644
--- a/lib/SILOptimizer/Mandatory/Differentiation.h
+++ b/lib/SILOptimizer/Mandatory/Differentiation.h
@@ -100,9 +100,9 @@
     // Create a dummy parameter declaration.
     // Necessary to prevent crash during argument explosion optimization.
     auto loc = f->getLocation().getSourceLoc();
-    auto *decl = new (ctx)
-        ParamDecl(ParamDecl::Specifier::Default, loc, loc, Identifier(), loc,
-                  Identifier(), moduleDecl);
+    auto *decl = new (ctx) ParamDecl(loc, loc, Identifier(), loc,
+                                     Identifier(), moduleDecl);
+    decl->setSpecifier(ParamDecl::Specifier::Default);
     decl->setType(type.getASTType());
     entry->createFunctionArgument(type, decl);
   };
diff --git a/lib/SILOptimizer/Mandatory/MandatoryCombine.cpp b/lib/SILOptimizer/Mandatory/MandatoryCombine.cpp
index 3e0d256..172914a 100644
--- a/lib/SILOptimizer/Mandatory/MandatoryCombine.cpp
+++ b/lib/SILOptimizer/Mandatory/MandatoryCombine.cpp
@@ -127,20 +127,18 @@
 //===----------------------------------------------------------------------===//
 
 void MandatoryCombiner::addReachableCodeToWorklist(SILFunction &function) {
-  SmallBlotSetVector<SILBasicBlock *, 32> blockWorklist;
-  SmallBlotSetVector<SILBasicBlock *, 32> blocksVisited;
-  SmallVector<SILInstruction *, 128> instructions;
+  SmallVector<SILBasicBlock *, 32> blockWorklist;
+  SmallPtrSet<SILBasicBlock *, 32> blockAlreadyAddedToWorklist;
+  SmallVector<SILInstruction *, 128> initialInstructionWorklist;
 
-  blockWorklist.insert(&*function.begin());
+  {
+    auto *firstBlock = &*function.begin();
+    blockWorklist.push_back(firstBlock);
+    blockAlreadyAddedToWorklist.insert(firstBlock);
+  }
+
   while (!blockWorklist.empty()) {
-    auto *block = blockWorklist.pop_back_val().getValueOr(nullptr);
-    if (block == nullptr) {
-      continue;
-    }
-
-    if (!blocksVisited.insert(block).second) {
-      continue;
-    }
+    auto *block = blockWorklist.pop_back_val();
 
     for (auto iterator = block->begin(), end = block->end(); iterator != end;) {
       auto *instruction = &*iterator;
@@ -150,14 +148,17 @@
         continue;
       }
 
-      instructions.push_back(instruction);
+      initialInstructionWorklist.push_back(instruction);
     }
 
-    for_each(block->getSuccessorBlocks(),
-             [&](SILBasicBlock *block) { blockWorklist.insert(block); });
+    llvm::copy_if(block->getSuccessorBlocks(),
+                  std::back_inserter(blockWorklist),
+                  [&](SILBasicBlock *block) -> bool {
+                    return blockAlreadyAddedToWorklist.insert(block).second;
+                  });
   }
 
-  worklist.addInitialGroup(instructions);
+  worklist.addInitialGroup(initialInstructionWorklist);
 }
 
 bool MandatoryCombiner::doOneIteration(SILFunction &function,
@@ -282,6 +283,12 @@
   void run() override {
     auto *function = getFunction();
 
+    // If this function is an external declaration, bail. We only want to visit
+    // functions with bodies.
+    if (function->isExternalDeclaration()) {
+      return;
+    }
+
     MandatoryCombiner combiner(createdInstructions);
     bool madeChange = combiner.runOnFunction(*function);
 
diff --git a/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp b/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp
index 6a3f5dc..2bfc9a1 100644
--- a/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp
+++ b/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp
@@ -783,9 +783,9 @@
   return nullptr;
 }
 
-/// Return true iff this function is a protocol witness for
-/// ExpressibleByStringInterpolation.init(stringInterpolation:) in OSLogMessage.
-bool isAutoGeneratedInitOfOSLogMessage(SILFunction &fun) {
+/// Return true iff the SIL function \c fun is a method of the \c OSLogMessage
+/// type.
+bool isMethodOfOSLogMessage(SILFunction &fun) {
   DeclContext *declContext = fun.getDeclContext();
   if (!declContext)
     return false;
@@ -818,11 +818,15 @@
       return;
     }
 
-    // Skip the auto-generated (transparent) witness method of OSLogMessage,
-    // which ends up invoking the OSLogMessage initializer:
-    // "oslog.message.init_interpolation" but without an interpolated
-    // string literal.
-    if (isAutoGeneratedInitOfOSLogMessage(fun)) {
+    // Skip methods of OSLogMessage type. This avoid unnecessary work and also
+    // avoids falsely diagnosing the auto-generated (transparent) witness method
+    // of OSLogMessage, which ends up invoking the OSLogMessage initializer:
+    // "oslog.message.init_interpolation" without an interpolated string
+    // literal that is expected by this pass.
+    // TODO: this check can be eliminated if there is a separate pass for
+    // diagnosing errors in the use of the OSLogMessage type, and this pass
+    // bails out when a use of the type is not optimizable.
+    if (isMethodOfOSLogMessage(fun)) {
       return;
     }
 
diff --git a/lib/SILOptimizer/Transforms/CopyPropagation.cpp b/lib/SILOptimizer/Transforms/CopyPropagation.cpp
index 185e900..52158b4 100644
--- a/lib/SILOptimizer/Transforms/CopyPropagation.cpp
+++ b/lib/SILOptimizer/Transforms/CopyPropagation.cpp
@@ -419,7 +419,7 @@
     originalDestroyBlocks.insert(use->getUser()->getParent());
   }
 
-  llvm::iterator_range<BlockSetVec::const_iterator>
+  iterator_range<BlockSetVec::const_iterator>
   getOriginalDestroyBlocks() const {
     return originalDestroyBlocks;
   }
diff --git a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
index dce868a..762ed91 100644
--- a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
+++ b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
@@ -285,9 +285,8 @@
     Result->replaceAllUsesWith(ProjInst);
   }
 
-  // We may have exposed trivially dead instructions due to
-  // simplifyInstruction... delete I and any such instructions!
-  recursivelyDeleteTriviallyDeadInstructions(I, true);
+  // Now that all of its uses have been eliminated, erase the destructure.
+  I->eraseFromParent();
 }
 
 bool OwnershipModelEliminatorVisitor::visitDestructureStructInst(
diff --git a/lib/SILOptimizer/Transforms/SILSROA.cpp b/lib/SILOptimizer/Transforms/SILSROA.cpp
index a15fe41..eafc9d4 100644
--- a/lib/SILOptimizer/Transforms/SILSROA.cpp
+++ b/lib/SILOptimizer/Transforms/SILSROA.cpp
@@ -286,7 +286,7 @@
     if (auto *DSI = dyn_cast<DeallocStackInst>(User)) {
       LLVM_DEBUG(llvm::dbgs() << "        Found DeallocStackInst!\n");
       // Create the allocations in reverse order.
-      for (auto *NewAI : swift::reversed(NewAllocations))
+      for (auto *NewAI : llvm::reverse(NewAllocations))
         B.createDeallocStack(DSI->getLoc(), SILValue(NewAI));
       ToRemove.push_back(DSI);
     }
diff --git a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
index bb4c3fb..4a45301 100644
--- a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
+++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
@@ -2792,7 +2792,7 @@
     llvm::SmallVectorImpl<SILValue> &NewIncomingValues) {
   unsigned ArgIndex = Arg->getIndex();
 
-  for (unsigned i : reversed(indices(BI->getAllOperands()))) {
+  for (unsigned i : llvm::reverse(indices(BI->getAllOperands()))) {
     // Skip this argument.
     if (i == ArgIndex)
       continue;
@@ -2811,7 +2811,7 @@
   unsigned ArgIndex = Arg->getIndex();
   if (Arg->getParent() == CBI->getTrueBB()) {
     ArrayRef<Operand> TrueArgs = CBI->getTrueOperands();
-    for (unsigned i : reversed(indices(TrueArgs))) {
+    for (unsigned i : llvm::reverse(indices(TrueArgs))) {
       // Skip this argument.
       if (i == ArgIndex)
         continue;
@@ -2824,7 +2824,7 @@
     NewFalseValues = OldIncomingValues;
   } else {
     ArrayRef<Operand> FalseArgs = CBI->getFalseOperands();
-    for (unsigned i : reversed(indices(FalseArgs))) {
+    for (unsigned i : llvm::reverse(indices(FalseArgs))) {
       // Skip this argument.
       if (i == ArgIndex)
         continue;
@@ -2947,7 +2947,7 @@
 
     auto Loc = RegularLocation::getAutoGeneratedLocation();
     assert(NewIncomingValues.empty() && "NewIncomingValues was not cleared?");
-    for (auto &P : reversed(Projections)) {
+    for (auto &P : llvm::reverse(Projections)) {
       auto *ProjInst = P.createProjection(B, Loc, Base).get();
       NewIncomingValues.push_back(ProjInst);
     }
diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp
index 649b3dd..f089e25 100644
--- a/lib/SILOptimizer/Utils/ConstExpr.cpp
+++ b/lib/SILOptimizer/Utils/ConstExpr.cpp
@@ -123,12 +123,22 @@
   /// addresses.
   llvm::DenseMap<SILValue, SymbolicValue> calculatedValues;
 
+  /// If a SILValue is not bound to a SymbolicValue in the calculatedValues,
+  /// try to compute it recursively by visiting its defining instruction.
+  bool recursivelyComputeValueIfNotInState = false;
+
 public:
   ConstExprFunctionState(ConstExprEvaluator &evaluator, SILFunction *fn,
                          SubstitutionMap substitutionMap,
-                         unsigned &numInstEvaluated)
+                         unsigned &numInstEvaluated,
+                         bool enableTopLevelEvaluation)
       : evaluator(evaluator), fn(fn), substitutionMap(substitutionMap),
-        numInstEvaluated(numInstEvaluated) {}
+        numInstEvaluated(numInstEvaluated),
+        recursivelyComputeValueIfNotInState(enableTopLevelEvaluation) {
+    assert((!fn || !enableTopLevelEvaluation) &&
+           "top-level evaluation must be disabled when evaluating a function"
+           " body step by step");
+  }
 
   /// Pretty print the state to stderr.
   void dump() const {
@@ -168,8 +178,9 @@
     return result;
   }
 
-  /// Return the SymbolicValue for the specified SIL value, lazily computing
-  /// it if needed.
+  /// Return the SymbolicValue for the specified SIL value. If the SIL value is
+  /// not in \c calculatedValues, try computing the SymbolicValue recursively
+  /// if \c recursivelyComputeValueIfNotInState flag is set.
   SymbolicValue getConstantValue(SILValue value);
 
   /// Evaluate the specified instruction in a flow sensitive way, for use by
@@ -232,14 +243,6 @@
 SymbolicValue ConstExprFunctionState::computeConstantValue(SILValue value) {
   assert(!calculatedValues.count(value));
 
-  // If the client is asking for the value of a stack object that hasn't been
-  // computed, and if fn is null, then we are in top level code, and the
-  // stack object must be a single store value.  Since this is a very different
-  // computation, split it out to its own path.
-  if (!fn && value->getType().isAddress() && isa<AllocStackInst>(value)) {
-    return getSingleWriterAddressValue(value);
-  }
-
   // If this a trivial constant instruction that we can handle, then fold it
   // immediately.
   if (auto *ili = dyn_cast<IntegerLiteralInst>(value))
@@ -382,17 +385,6 @@
   if (auto *builtin = dyn_cast<BuiltinInst>(value))
     return computeConstantValueBuiltin(builtin);
 
-  if (auto *apply = dyn_cast<ApplyInst>(value)) {
-    auto callResult = computeCallResult(apply);
-
-    // If this failed, return the error code.
-    if (callResult.hasValue())
-      return callResult.getValue();
-
-    assert(calculatedValues.count(apply));
-    return calculatedValues[apply];
-  }
-
   if (auto *enumVal = dyn_cast<EnumInst>(value)) {
     if (!enumVal->hasOperand())
       return SymbolicValue::getEnum(enumVal->getElement());
@@ -1174,15 +1166,37 @@
   return None;
 }
 
-/// Return the SymbolicValue for the specified SIL value, lazily computing
-/// it if needed.
 SymbolicValue ConstExprFunctionState::getConstantValue(SILValue value) {
   // Check to see if we already have an answer.
   auto it = calculatedValues.find(value);
   if (it != calculatedValues.end())
     return it->second;
 
-  // Compute the value of a normal instruction based on its operands.
+  if (!recursivelyComputeValueIfNotInState) {
+    return getUnknown(evaluator, value, UnknownReason::UntrackedSILValue);
+  }
+
+  // If the client is asking for the value of a stack object that hasn't been
+  // computed, and if we have to recursively compute it, the stack object must
+  // be a single store value. Since this is a very different computation,
+  // split it out to its own path.
+  if (value->getType().isAddress() && isa<AllocStackInst>(value)) {
+    return getSingleWriterAddressValue(value);
+  }
+
+  if (auto *apply = dyn_cast<ApplyInst>(value)) {
+    auto callResult = computeCallResult(apply);
+
+    // If this failed, return the error code.
+    if (callResult.hasValue())
+      return callResult.getValue();
+
+    assert(calculatedValues.count(apply));
+    return calculatedValues[apply];
+  }
+
+  // Compute the value of a normal single-value instructions based on its
+  // operands.
   auto result = computeConstantValue(value);
 
   // If this is the top-level lazy interpreter, output a debug trace.
@@ -1567,15 +1581,6 @@
     return None;
   }
 
-  // Make sure that our copy_value, begin_borrow form constants. Otherwise,
-  // return why.
-  if (isa<CopyValueInst>(inst) || isa<BeginBorrowInst>(inst)) {
-    auto result = getConstantValue(inst->getOperand(0));
-    if (!result.isConstant())
-      return result;
-    return None;
-  }
-
   // If this is a deallocation of a memory object that we are tracking, then
   // don't do anything.  The memory is allocated in a BumpPtrAllocator so there
   // is no useful way to free it.
@@ -1596,7 +1601,10 @@
     }
   }
 
-  // If this is a call, evaluate it.
+  // If this is a call, evaluate it. Calls are handled separately from other
+  // single-valued instructions because calls which return void will not be
+  // mapped to a symbolic value. Every other single-valued instruction will be
+  // mapped to a symbolic value if its evaluation is successful.
   if (auto apply = dyn_cast<ApplyInst>(inst))
     return computeCallResult(apply);
 
@@ -1622,13 +1630,13 @@
                           injectEnumInst->getOperand());
   }
 
-  // If the instruction produces a result, try constant folding it.
-  // If this fails, then we fail.
-  if (isa<SingleValueInstruction>(inst)) {
-    auto oneResultVal = inst->getResults()[0];
-    auto result = getConstantValue(oneResultVal);
+  // If the instruction produces a result, try computing it, and fail if the
+  // computation fails.
+  if (auto *singleValueInst = dyn_cast<SingleValueInstruction>(inst)) {
+    auto result = computeConstantValue(singleValueInst);
     if (!result.isConstant())
       return result;
+    setValue(singleValueInst, result);
     LLVM_DEBUG(llvm::dbgs() << "  RESULT: "; result.dump());
     return None;
   }
@@ -1767,7 +1775,8 @@
                      ConstExprEvaluator &evaluator) {
   assert(!fn.isExternalDeclaration() && "Can't analyze bodyless function");
   ConstExprFunctionState state(evaluator, &fn, substitutionMap,
-                               numInstEvaluated);
+                               numInstEvaluated,
+                               /*TopLevelEvaluation*/ false);
 
   // TODO: implement caching.
   // TODO: reject code that is too complex.
@@ -1860,7 +1869,9 @@
 void ConstExprEvaluator::computeConstantValues(
     ArrayRef<SILValue> values, SmallVectorImpl<SymbolicValue> &results) {
   unsigned numInstEvaluated = 0;
-  ConstExprFunctionState state(*this, nullptr, {}, numInstEvaluated);
+  ConstExprFunctionState state(*this, /*SILFunction*/ nullptr, {},
+                               numInstEvaluated,
+                               /*enableTopLevelEvaluation*/ true);
   for (auto v : values) {
     auto symVal = state.getConstantValue(v);
     results.push_back(symVal);
@@ -1881,7 +1892,8 @@
                                                bool trackCallees)
     : evaluator(alloc, assertConf, trackCallees),
       internalState(
-          new ConstExprFunctionState(evaluator, fun, {}, stepsEvaluated)) {
+          new ConstExprFunctionState(evaluator, fun, {}, stepsEvaluated,
+                                     /*enableTopLevelEvaluation*/ false)) {
   assert(fun);
 }
 
diff --git a/lib/SILOptimizer/Utils/InstOptUtils.cpp b/lib/SILOptimizer/Utils/InstOptUtils.cpp
index 7d6e490..76f6d65 100644
--- a/lib/SILOptimizer/Utils/InstOptUtils.cpp
+++ b/lib/SILOptimizer/Utils/InstOptUtils.cpp
@@ -1085,7 +1085,7 @@
   // are cleaning up has the same live range as the partial_apply. Otherwise, we
   // may be inserting destroy_addr of alloc_stack that have already been passed
   // to a dealloc_stack.
-  for (unsigned i : reversed(indices(args))) {
+  for (unsigned i : llvm::reverse(indices(args))) {
     SILValue arg = args[i];
     SILParameterInfo paramInfo = params[i];
 
diff --git a/lib/SILOptimizer/Utils/StackNesting.cpp b/lib/SILOptimizer/Utils/StackNesting.cpp
index adce944..e295760 100644
--- a/lib/SILOptimizer/Utils/StackNesting.cpp
+++ b/lib/SILOptimizer/Utils/StackNesting.cpp
@@ -139,7 +139,7 @@
     changed = false;
 
     // It's a backward dataflow problem.
-    for (BlockInfo &BI : reversed(BlockInfos)) {
+    for (BlockInfo &BI : llvm::reverse(BlockInfos)) {
       // Collect the alive-bits (at the block exit) from the successor blocks.
       for (BlockInfo *SuccBI : BI.Successors) {
         BI.AliveStackLocsAtExit |= SuccBI->AliveStackLocsAtEntry;
@@ -158,7 +158,7 @@
         }
         BI.AliveStackLocsAtExit = Bits;
       }
-      for (SILInstruction *StackInst : reversed(BI.StackInsts)) {
+      for (SILInstruction *StackInst : llvm::reverse(BI.StackInsts)) {
         if (StackInst->isAllocatingStack()) {
           int BitNr = bitNumberForAlloc(StackInst);
           if (Bits != StackLocs[BitNr].AliveLocs) {
@@ -246,7 +246,7 @@
 //   dealloc_stack %1
 StackNesting::Changes StackNesting::insertDeallocsAtBlockBoundaries() {
   Changes changes = Changes::None;
-  for (const BlockInfo &BI : reversed(BlockInfos)) {
+  for (const BlockInfo &BI : llvm::reverse(BlockInfos)) {
     for (unsigned SuccIdx = 0, NumSuccs = BI.Successors.size();
          SuccIdx < NumSuccs; ++SuccIdx) {
 
@@ -280,11 +280,11 @@
 
   // Visit all blocks. Actually the order doesn't matter, but let's to it in
   // the same order as in solve().
-  for (const BlockInfo &BI : reversed(BlockInfos)) {
+  for (const BlockInfo &BI : llvm::reverse(BlockInfos)) {
     Bits = BI.AliveStackLocsAtExit;
 
     // Insert/remove deallocations inside blocks.
-    for (SILInstruction *StackInst : reversed(BI.StackInsts)) {
+    for (SILInstruction *StackInst : llvm::reverse(BI.StackInsts)) {
       if (StackInst->isAllocatingStack()) {
         // For allocations we just update the bit-set.
         int BitNr = bitNumberForAlloc(StackInst);
diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp
index 76ccd8c..2d4e03e 100644
--- a/lib/Sema/BuilderTransform.cpp
+++ b/lib/Sema/BuilderTransform.cpp
@@ -586,14 +586,16 @@
   assert(transformedType && "Missing type");
 
   // Record the transformation.
-  assert(std::find_if(builderTransformedClosures.begin(),
-                      builderTransformedClosures.end(),
-                      [&](const std::tuple<ClosureExpr *, Type, Expr *> &elt) {
-                        return std::get<0>(elt) == closure;
-                      }) == builderTransformedClosures.end() &&
+  assert(std::find_if(
+      builderTransformedClosures.begin(),
+      builderTransformedClosures.end(),
+      [&](const std::pair<ClosureExpr *, AppliedBuilderTransform> &elt) {
+        return elt.first == closure;
+      }) == builderTransformedClosures.end() &&
          "already transformed this closure along this path!?!");
   builderTransformedClosures.push_back(
-    std::make_tuple(closure, builderType, singleExpr));
+      std::make_pair(closure,
+                     AppliedBuilderTransform{builderType, singleExpr}));
 
   // Bind the result type of the closure to the type of the transformed
   // expression.
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 9326574..d09c96d 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -3382,7 +3382,7 @@
 
       // Local function to add the optional injections to final result.
       auto addFinalOptionalInjections = [&](Expr *result) {
-        for (auto destType : reversed(destOptionalInjections)) {
+        for (auto destType : llvm::reverse(destOptionalInjections)) {
           result =
             cs.cacheType(new (tc.Context) InjectIntoOptionalExpr(result,
                                                                  destType));
@@ -4490,11 +4490,12 @@
       auto closure = new (ctx)
           AutoClosureExpr(E, leafTy, discriminator, cs.DC);
       auto param = new (ctx) ParamDecl(
-          ParamDecl::Specifier::Default, SourceLoc(),
+          SourceLoc(),
           /*argument label*/ SourceLoc(), Identifier(),
           /*parameter name*/ SourceLoc(), ctx.getIdentifier("$0"), closure);
       param->setType(baseTy);
       param->setInterfaceType(baseTy->mapTypeOutOfContext());
+      param->setSpecifier(ParamSpecifier::Default);
 
       // The outer closure.
       //
@@ -4504,12 +4505,13 @@
       auto outerClosure = new (ctx)
           AutoClosureExpr(closure, closureTy, discriminator, cs.DC);
       auto outerParam =
-          new (ctx) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(),
+          new (ctx) ParamDecl(SourceLoc(),
                               /*argument label*/ SourceLoc(), Identifier(),
                               /*parameter name*/ SourceLoc(),
                               ctx.getIdentifier("$kp$"), outerClosure);
       outerParam->setType(keyPathTy);
       outerParam->setInterfaceType(keyPathTy->mapTypeOutOfContext());
+      outerParam->setSpecifier(ParamSpecifier::Default);
 
       // let paramRef = "$0"
       auto *paramRef = new (ctx)
@@ -5916,7 +5918,7 @@
                       diag::invalid_differentiable_function_conversion_expr,
                       isToTypeLinear);
           if (paramDecl->getType()->is<AnyFunctionType>()) {
-            auto *typeRepr = paramDecl->getTypeLoc().getTypeRepr();
+            auto *typeRepr = paramDecl->getTypeRepr();
             while (auto *attributed = dyn_cast<AttributedTypeRepr>(typeRepr))
               typeRepr = attributed->getTypeRepr();
             std::string attributeString = "@differentiable";
@@ -5927,7 +5929,7 @@
             tc.diagnose(paramDecl->getLoc(),
                 diag::invalid_differentiable_function_conversion_parameter,
                 attributeString)
-               .highlight(paramDecl->getTypeLoc().getSourceRange())
+               .highlight(paramDecl->getTypeRepr()->getSourceRange())
                .fixItInsert(paramListLoc, attributeString + " ");
           }
           return;
@@ -7628,7 +7630,7 @@
         auto builder =
             Rewriter.solution.builderTransformedClosures.find(closure);
         if (builder != Rewriter.solution.builderTransformedClosures.end()) {
-          auto singleExpr = builder->second.second;
+          auto singleExpr = builder->second.singleExpr;
           auto returnStmt = new (tc.Context) ReturnStmt(
              singleExpr->getStartLoc(), singleExpr, /*implicit=*/true);
           auto braceStmt = BraceStmt::create(
@@ -7759,7 +7761,7 @@
       if (auto *closure = dyn_cast<ClosureExpr>(E)) {
         auto result = solution.builderTransformedClosures.find(closure);
         if (result != solution.builderTransformedClosures.end()) {
-          auto *transformedExpr = result->second.second;
+          auto *transformedExpr = result->second.singleExpr;
           // Since this closure has been transformed into something
           // else let's look inside transformed expression instead.
           transformedExpr->walk(*this);
diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp
index 4ca680d..b7093db 100644
--- a/lib/Sema/CSDiagnostics.cpp
+++ b/lib/Sema/CSDiagnostics.cpp
@@ -987,7 +987,10 @@
       emitDiagnostic(PD->getLoc(), diag::noescape_parameter, PD->getName());
 
   if (!PD->isAutoClosure()) {
-    note.fixItInsert(PD->getTypeLoc().getSourceRange().Start, "@escaping ");
+    SourceLoc reprLoc;
+    if (auto *repr = PD->getTypeRepr())
+      reprLoc = repr->getStartLoc();
+    note.fixItInsert(reprLoc, "@escaping ");
   } // TODO: add in a fixit for autoclosure
 
   return true;
@@ -2144,6 +2147,12 @@
 }
 
 void ContextualFailure::tryFixIts(InFlightDiagnostic &diagnostic) const {
+  auto *locator = getLocator();
+  // Can't apply any of the fix-its below if this failure
+  // is related to `inout` argument.
+  if (locator->isLastElement<LocatorPathElt::LValueConversion>())
+    return;
+
   if (trySequenceSubsequenceFixIts(diagnostic))
     return;
 
@@ -4127,9 +4136,8 @@
   // with parameters, if there are, we'll have to add
   // type information to the replacement argument.
   bool explicitTypes =
-      llvm::any_of(params->getArray(), [](const ParamDecl *param) {
-        return param->getTypeLoc().getTypeRepr();
-      });
+      llvm::any_of(params->getArray(),
+                   [](const ParamDecl *param) { return param->getTypeRepr(); });
 
   if (isMultiLineClosure)
     OS << '\n' << indent;
@@ -4882,13 +4890,49 @@
           ? emitDiagnostic(argExpr->getLoc(),
                            diag::single_tuple_parameter_mismatch_special,
                            choice->getDescriptiveKind(), paramTy, subsStr)
-          : emitDiagnostic(
-                argExpr->getLoc(), diag::single_tuple_parameter_mismatch_normal,
-                choice->getDescriptiveKind(), name, paramTy, subsStr);
+          : emitDiagnostic(argExpr->getLoc(),
+                           diag::single_tuple_parameter_mismatch_normal,
+                           choice->getDescriptiveKind(), name, paramTy, subsStr);
 
-  diagnostic.highlight(argExpr->getSourceRange())
-      .fixItInsertAfter(argExpr->getStartLoc(), "(")
-      .fixItInsert(argExpr->getEndLoc(), ")");
+
+  auto newLeftParenLoc = argExpr->getStartLoc();
+  if (auto *TE = dyn_cast<TupleExpr>(argExpr)) {
+    auto firstArgLabel = TE->getElementName(0);
+    // Cover situations like:
+    //
+    // func foo(x: (Int, Int)) {}
+    // foo(x: 0, 1)
+    //
+    // Where left paren should be suggested after the label,
+    // since the label belongs to the parameter itself.
+    if (!firstArgLabel.empty()) {
+      auto paramTuple = resolveType(ParamType)->castTo<TupleType>();
+      // If the label of the first argument matches the one required
+      // by the parameter it would be omitted from the fixed parameter type.
+      if (!paramTuple->getElement(0).hasName())
+        newLeftParenLoc = Lexer::getLocForEndOfToken(getASTContext().SourceMgr,
+                                                     TE->getElementNameLoc(0));
+    }
+  }
+
+  // If the parameter is a generic parameter, it's hard to say
+  // whether use of a tuple is really intended here, so let's
+  // attach a fix-it to a note instead of the diagnostic message
+  // to indicate that it's not the only right solution possible.
+  if (auto *typeVar = ParamType->getAs<TypeVariableType>()) {
+    if (typeVar->getImpl().getGenericParameter()) {
+      diagnostic.flush();
+
+      emitDiagnostic(argExpr->getLoc(), diag::note_maybe_forgot_to_form_tuple)
+          .fixItInsertAfter(newLeftParenLoc, "(")
+          .fixItInsert(argExpr->getEndLoc(), ")");
+    }
+  } else {
+    diagnostic.highlight(argExpr->getSourceRange())
+        .fixItInsertAfter(newLeftParenLoc, "(")
+        .fixItInsert(argExpr->getEndLoc(), ")");
+  }
+
   return true;
 }
 
@@ -5044,9 +5088,11 @@
 }
 
 bool ArgumentMismatchFailure::diagnoseAsNote() {
+  auto *locator = getLocator();
   if (auto *callee = getCallee()) {
     emitDiagnostic(callee, diag::candidate_has_invalid_argument_at_position,
-                   getToType(), getParamPosition());
+                   getToType(), getParamPosition(),
+                   locator->isLastElement<LocatorPathElt::LValueConversion>());
     return true;
   }
 
diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp
index 0ce51f4..d395538 100644
--- a/lib/Sema/CSFix.cpp
+++ b/lib/Sema/CSFix.cpp
@@ -707,14 +707,42 @@
 
   const auto &param = params.front();
 
-  auto *paramTy = param.getOldType()->getAs<TupleType>();
-  if (!paramTy || paramTy->getNumElements() != args.size())
+  if (param.isInOut() || param.isVariadic() || param.isAutoClosure())
+    return true;
+
+  auto paramTy = param.getOldType();
+
+  // Parameter type has to be either a tuple (with the same arity as
+  // argument list), or a type variable.
+  if (!(paramTy->is<TupleType>() &&
+        paramTy->castTo<TupleType>()->getNumElements() == args.size()) &&
+      !paramTy->is<TypeVariableType>())
     return true;
 
   SmallVector<TupleTypeElt, 4> argElts;
-  for (const auto &arg : args) {
-    argElts.push_back(
-        {arg.getPlainType(), arg.getLabel(), arg.getParameterFlags()});
+
+  for (unsigned index : indices(args)) {
+    const auto &arg = args[index];
+
+    auto label = arg.getLabel();
+    auto flags = arg.getParameterFlags();
+
+    // In situations where there is a single labeled parameter
+    // we need to form a tuple with omits first label e.g.
+    //
+    // func foo<T>(x: T) {}
+    // foo(x: 0, 1)
+    //
+    // We'd want to suggest argument list to be `x: (0, 1)` instead
+    // of `(x: 0, 1)` which would be incorrect.
+    if (index == 0 && param.getLabel() == label)
+      label = Identifier();
+
+    // Tuple can't have `inout` elements.
+    if (flags.isInOut())
+      return true;
+
+    argElts.push_back({arg.getPlainType(), label});
   }
 
   bindings[0].clear();
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 37e6f7f..32e8c2b 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -24,6 +24,7 @@
 #include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/SubstitutionMap.h"
 #include "swift/Sema/IDETypeChecking.h"
+#include "swift/Subsystems.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/StringExtras.h"
@@ -2044,8 +2045,8 @@
         Type paramType, internalType;
 
         // If a type was explicitly specified, use its opened type.
-        if (auto type = param->getTypeLoc().getType()) {
-          paramType = closureExpr->mapTypeIntoContext(type);
+        if (param->getTypeRepr()) {
+          paramType = closureExpr->mapTypeIntoContext(param->getInterfaceType());
           // FIXME: Need a better locator for a pattern as a base.
           paramType = CS.openUnboundGenericType(paramType, locator);
           internalType = paramType;
@@ -2572,11 +2573,6 @@
         return Type();
       }
 
-      // If the 'self' parameter is not configured, something went
-      // wrong elsewhere and should have been diagnosed already.
-      if (!selfDecl->hasInterfaceType())
-        return ErrorType::get(tc.Context);
-
       auto selfTy = CS.DC->mapTypeIntoContext(
         typeContext->getDeclaredInterfaceType());
       auto superclassTy = selfTy->getSuperclass();
@@ -2593,28 +2589,24 @@
     }
     
     Type visitIfExpr(IfExpr *expr) {
-      // The conditional expression must conform to LogicValue.
+      // Condition must convert to Bool.
       auto boolDecl = CS.getASTContext().getBoolDecl();
       if (!boolDecl)
         return Type();
 
-      // Condition must convert to Bool.
       CS.addConstraint(ConstraintKind::Conversion,
                        CS.getType(expr->getCondExpr()),
                        boolDecl->getDeclaredType(),
                        CS.getConstraintLocator(expr->getCondExpr()));
 
       // The branches must be convertible to a common type.
-      auto resultTy = CS.createTypeVariable(CS.getConstraintLocator(expr),
-                                            TVO_PrefersSubtypeBinding |
-                                            TVO_CanBindToNoEscape);
-      CS.addConstraint(ConstraintKind::Conversion,
-                       CS.getType(expr->getThenExpr()), resultTy,
-                       CS.getConstraintLocator(expr->getThenExpr()));
-      CS.addConstraint(ConstraintKind::Conversion,
-                       CS.getType(expr->getElseExpr()), resultTy,
-                       CS.getConstraintLocator(expr->getElseExpr()));
-      return resultTy;
+      return CS.addJoinConstraint(CS.getConstraintLocator(expr),
+          {
+            { CS.getType(expr->getThenExpr()),
+              CS.getConstraintLocator(expr->getThenExpr()) },
+            { CS.getType(expr->getElseExpr()),
+              CS.getConstraintLocator(expr->getElseExpr()) }
+          });
     }
     
     virtual Type visitImplicitConversionExpr(ImplicitConversionExpr *expr) {
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index dc756d6..065c0a1 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -2654,11 +2654,23 @@
       auto result = matchTypes(lhs, rhs, ConstraintKind::Conversion,
                                TMF_ApplyingFix, locator);
 
-      if (!result.isFailure()) {
-        conversionsOrFixes.push_back(
-            AllowInOutConversion::create(*this, lhs, rhs, loc));
-        break;
+      ConstraintFix *fix = nullptr;
+      if (result.isFailure()) {
+        // If this is a "destination" argument to a mutating operator
+        // like `+=`, let's consider it contextual and only attempt
+        // to fix type mismatch on the "source" right-hand side of
+        // such operators.
+        if (isOperatorArgument(loc) &&
+            loc->findLast<LocatorPathElt::ApplyArgToParam>()->getArgIdx() == 0)
+          break;
+
+        fix = AllowArgumentMismatch::create(*this, lhs, rhs, loc);
+      } else {
+        fix = AllowInOutConversion::create(*this, lhs, rhs, loc);
       }
+
+      conversionsOrFixes.push_back(fix);
+      break;
     }
 
     if (elt.getKind() != ConstraintLocator::ApplyArgToParam)
@@ -3007,13 +3019,38 @@
     if (repairByInsertingExplicitCall(lhs, rhs))
       return true;
 
-    auto result = matchTypes(lhs, rhs, ConstraintKind::ArgumentConversion,
-        TypeMatchFlags::TMF_ApplyingFix,
-        locator.withPathElement(ConstraintLocator::FunctionArgument));
+    auto isPointerType = [](Type type) -> bool {
+      return bool(
+          type->lookThroughAllOptionalTypes()->getAnyPointerElementType());
+    };
 
-    if (result.isSuccess())
-      conversionsOrFixes.push_back(AllowAutoClosurePointerConversion::create(
-          *this, lhs, rhs, getConstraintLocator(locator)));
+    // Let's see whether this is an implicit conversion to a pointer type
+    // which is invalid in @autoclosure context e.g. from `inout`, Array
+    // or String.
+    if (!isPointerType(lhs) && isPointerType(rhs)) {
+      auto result = matchTypes(
+          lhs, rhs, ConstraintKind::ArgumentConversion,
+          TypeMatchFlags::TMF_ApplyingFix,
+          locator.withPathElement(ConstraintLocator::FunctionArgument));
+
+      if (result.isSuccess())
+        conversionsOrFixes.push_back(AllowAutoClosurePointerConversion::create(
+            *this, lhs, rhs, getConstraintLocator(locator)));
+    }
+
+    // In situations like this:
+    //
+    // struct S<T> {}
+    // func foo(_: @autoclosure () -> S<Int>) {}
+    // foo(S<String>())
+    //
+    // Generic type conversion mismatch is a better fix which is going to
+    // point to the generic arguments that did not align properly.
+    if (hasConversionOrRestriction(ConversionRestrictionKind::DeepEquality))
+      break;
+
+    conversionsOrFixes.push_back(AllowArgumentMismatch::create(
+        *this, lhs, rhs, getConstraintLocator(locator)));
     break;
   }
 
@@ -6397,6 +6434,7 @@
 
   auto loc = locator.getBaseLocator();
   if (definitelyFunctionType) {
+    increaseScore(SK_FunctionConversion);
     return SolutionKind::Solved;
   } else if (!anyComponentsUnresolved ||
              (definitelyKeyPathType && capability == ReadOnly)) {
@@ -8129,6 +8167,35 @@
   }
 }
 
+Type ConstraintSystem::addJoinConstraint(
+    ConstraintLocator *locator,
+    ArrayRef<std::pair<Type, ConstraintLocator *>> inputs) {
+  switch (inputs.size()) {
+  case 0:
+    return Type();
+
+  case 1:
+    return inputs.front().first;
+
+  default:
+    // Produce the join below.
+    break;
+  }
+
+  // Create a type variable to capture the result of the join.
+  Type resultTy = createTypeVariable(locator,
+                                     (TVO_PrefersSubtypeBinding |
+                                      TVO_CanBindToNoEscape));
+
+  // Introduce conversions from each input type to the type variable.
+  for (const auto &input : inputs) {
+    addConstraint(
+      ConstraintKind::Conversion, input.first, resultTy, input.second);
+  }
+
+  return resultTy;
+}
+
 void ConstraintSystem::addExplicitConversionConstraint(
                                            Type fromType, Type toType,
                                            bool allowFixes,
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index abfd321..91b82ea 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -174,14 +174,11 @@
 
   for (const auto &transformed : builderTransformedClosures) {
     auto known =
-        solution.builderTransformedClosures.find(std::get<0>(transformed));
+        solution.builderTransformedClosures.find(transformed.first);
     if (known != solution.builderTransformedClosures.end()) {
-      assert(known->second.second == std::get<2>(transformed));
+      assert(known->second.singleExpr == transformed.second.singleExpr);
     }
-    solution.builderTransformedClosures.insert(
-      std::make_pair(std::get<0>(transformed),
-                     std::make_pair(std::get<1>(transformed),
-                                    std::get<2>(transformed))));
+    solution.builderTransformedClosures.insert(transformed);
   }
 
   return solution;
@@ -253,10 +250,7 @@
     CheckedConformances.push_back(conformance);
 
   for (const auto &transformed : solution.builderTransformedClosures) {
-    builderTransformedClosures.push_back(
-      std::make_tuple(transformed.first,
-                      transformed.second.first,
-                      transformed.second.second));
+    builderTransformedClosures.push_back(transformed);
   }
     
   // Register any fixes produced along this path.
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 1e8689c..c4f37383 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -236,8 +236,9 @@
 
       // Create the parameter.
       auto *arg = new (ctx)
-          ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), Loc,
+          ParamDecl(SourceLoc(), Loc,
                     var->getName(), Loc, var->getName(), decl);
+      arg->setSpecifier(ParamSpecifier::Default);
       arg->setInterfaceType(varInterfaceType);
       arg->setImplicit();
       
@@ -657,8 +658,7 @@
   // Create the initializer parameter patterns.
   OptionSet<ParameterList::CloneFlags> options
     = (ParameterList::Implicit |
-       ParameterList::Inherited |
-       ParameterList::WithoutTypes);
+       ParameterList::Inherited);
   auto *superclassParams = superclassCtor->getParameters();
   auto *bodyParams = superclassParams->clone(ctx, options);
 
@@ -675,7 +675,6 @@
     auto substTy = paramTy.subst(subMap);
 
     bodyParam->setInterfaceType(substTy);
-    bodyParam->getTypeLoc() = TypeLoc::withoutLoc(substTy);
   }
 
   // Create the initializer declaration, inheriting the name,
diff --git a/lib/Sema/ConstraintGraph.cpp b/lib/Sema/ConstraintGraph.cpp
index 85b28be..1b4134c 100644
--- a/lib/Sema/ConstraintGraph.cpp
+++ b/lib/Sema/ConstraintGraph.cpp
@@ -1058,7 +1058,7 @@
 
               // Add edges between this type variable and every other type
               // variable in the path.
-              for (auto otherTypeVar : reversed(currentPath)) {
+              for (auto otherTypeVar : llvm::reverse(currentPath)) {
                 // When we run into our own type variable, we're done.
                 if (otherTypeVar == typeVar)
                   break;
@@ -1121,7 +1121,7 @@
       SmallVector<TypeVariableType *, 4> orderedReps;
       orderedReps.reserve(representativeTypeVars.size());
       SmallPtrSet<TypeVariableType *, 4> visited;
-      for (auto rep : reversed(representativeTypeVars)) {
+      for (auto rep : llvm::reverse(representativeTypeVars)) {
         // Perform a postorder depth-first search through the one-way digraph,
         // starting at this representative, to establish the dependency
         // ordering amongst components that are reachable
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index 2f3e91c..09e409c 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -3229,6 +3229,21 @@
   return isOperator(expr, "~=");
 }
 
+bool constraints::isOperatorArgument(ConstraintLocator *locator,
+                                     StringRef expectedOperator) {
+  if (!locator->findLast<LocatorPathElt::ApplyArgToParam>())
+    return false;
+
+  if (auto *AE = dyn_cast_or_null<ApplyExpr>(locator->getAnchor())) {
+    if (isa<PrefixUnaryExpr>(AE) || isa<BinaryExpr>(AE) ||
+        isa<PostfixUnaryExpr>(AE))
+      return expectedOperator.empty() ||
+             isOperator(AE->getFn(), expectedOperator);
+  }
+
+  return false;
+}
+
 bool constraints::isArgumentOfPatternMatchingOperator(
     ConstraintLocator *locator) {
   auto *binaryOp = dyn_cast_or_null<BinaryExpr>(locator->getAnchor());
@@ -3239,13 +3254,6 @@
 
 bool constraints::isArgumentOfReferenceEqualityOperator(
     ConstraintLocator *locator) {
-  if (!locator->findLast<LocatorPathElt::ApplyArgToParam>())
-    return false;
-
-  if (auto *binaryOp = dyn_cast_or_null<BinaryExpr>(locator->getAnchor())) {
-    auto *fnExpr = binaryOp->getFn();
-    return isOperator(fnExpr, "===") || isOperator(fnExpr, "!==");
-  }
-
-  return false;
+  return isOperatorArgument(locator, "===") ||
+         isOperatorArgument(locator, "!==");
 }
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 55709d9..e1a0080 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -502,6 +502,16 @@
 /// The number of score kinds.
 const unsigned NumScoreKinds = SK_LastScoreKind + 1;
 
+/// Describes what happened when a function builder transform was applied
+/// to a particular closure.
+struct AppliedBuilderTransform {
+  /// The builder type that was applied to the closure.
+  Type builderType;
+
+  /// The single expression to which the closure was transformed.
+  Expr *singleExpr;
+};
+
 /// Describes the fixed score of a solution to the constraint system.
 struct Score {
   unsigned Data[NumScoreKinds] = {};
@@ -578,7 +588,7 @@
 /// An AST node that can gain type information while solving.
 using TypedNode =
     llvm::PointerUnion3<const Expr *, const TypeLoc *,
-                        const ParamDecl *>;
+                        const VarDecl *>;
 
 /// Display a score.
 llvm::raw_ostream &operator<<(llvm::raw_ostream &out, const Score &score);
@@ -656,7 +666,7 @@
       Conformances;
 
   /// The set of closures that have been transformed by a function builder.
-  llvm::MapVector<ClosureExpr *, std::pair<Type, Expr *>>
+  llvm::MapVector<ClosureExpr *, AppliedBuilderTransform>
       builderTransformedClosures;
 
   /// Simplify the given type by substituting all occurrences of
@@ -1065,7 +1075,7 @@
   /// the types on the expression nodes.
   llvm::DenseMap<const Expr *, TypeBase *> ExprTypes;
   llvm::DenseMap<const TypeLoc *, TypeBase *> TypeLocTypes;
-  llvm::DenseMap<const ParamDecl *, TypeBase *> ParamTypes;
+  llvm::DenseMap<const VarDecl *, TypeBase *> VarTypes;
   llvm::DenseMap<std::pair<const KeyPathExpr *, unsigned>, TypeBase *>
       KeyPathComponentTypes;
 
@@ -1150,7 +1160,7 @@
       CheckedConformances;
 
   /// The set of closures that have been transformed by a function builder.
-  SmallVector<std::tuple<ClosureExpr *, Type, Expr *>, 4>
+  std::vector<std::pair<ClosureExpr *, AppliedBuilderTransform>>
       builderTransformedClosures;
 
 public:
@@ -1833,8 +1843,8 @@
     } else if (auto typeLoc = node.dyn_cast<const TypeLoc *>()) {
       TypeLocTypes[typeLoc] = type.getPointer();
     } else {
-      auto param = node.get<const ParamDecl *>();
-      ParamTypes[param] = type.getPointer();
+      auto var = node.get<const VarDecl *>();
+      VarTypes[var] = type.getPointer();
     }
 
     // Record the fact that we ascribed a type to this node.
@@ -1858,8 +1868,8 @@
     } else if (auto typeLoc = node.dyn_cast<const TypeLoc *>()) {
       TypeLocTypes.erase(typeLoc);
     } else {
-      auto param = node.get<const ParamDecl *>();
-      ParamTypes.erase(param);
+      auto var = node.get<const VarDecl *>();
+      VarTypes.erase(var);
     }
   }
 
@@ -1887,8 +1897,8 @@
     } else if (auto typeLoc = node.dyn_cast<const TypeLoc *>()) {
       return TypeLocTypes.find(typeLoc) != TypeLocTypes.end();
     } else {
-      auto param = node.get<const ParamDecl *>();
-      return ParamTypes.find(param) != ParamTypes.end();
+      auto var = node.get<const VarDecl *>();
+      return VarTypes.find(var) != VarTypes.end();
     }
   }
 
@@ -1913,9 +1923,9 @@
     return TypeLocTypes.find(&L)->second;
   }
 
-  Type getType(const ParamDecl *P) const {
-    assert(hasType(P) && "Expected type to have been set!");
-    return ParamTypes.find(P)->second;
+  Type getType(const VarDecl *VD) const {
+    assert(hasType(VD) && "Expected type to have been set!");
+    return VarTypes.find(VD)->second;
   }
 
   Type getType(const KeyPathExpr *KP, unsigned I) const {
@@ -2130,6 +2140,17 @@
   void addConstraint(Requirement req, ConstraintLocatorBuilder locator,
                      bool isFavored = false);
 
+  /// Add a "join" constraint between a set of types, producing the common
+  /// supertype.
+  ///
+  /// Currently, a "join" is modeled by a set of conversion constraints to
+  /// a new type variable. At some point, we may want a new constraint kind
+  /// to cover the join.
+  ///
+  /// \returns the joined type, which is generally a new type variable.
+  Type addJoinConstraint(ConstraintLocator *locator,
+                         ArrayRef<std::pair<Type, ConstraintLocator *>> inputs);
+
   /// Add a key path application constraint to the constraint system.
   void addKeyPathApplicationConstraint(Type keypath, Type root, Type value,
                                        ConstraintLocatorBuilder locator,
@@ -3988,6 +4009,12 @@
 Expr *getArgumentExpr(Expr *expr, unsigned index);
 
 /// Determine whether given locator points to one of the arguments
+/// associated with the call to an operator. If the operator name
+/// is empty `true` is returned for any kind of operator.
+bool isOperatorArgument(ConstraintLocator *locator,
+                        StringRef expectedOperator = "");
+
+/// Determine whether given locator points to one of the arguments
 /// associated with implicit `~=` (pattern-matching) operator
 bool isArgumentOfPatternMatchingOperator(ConstraintLocator *locator);
 
diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp
index 7a0188c..16c03a8 100644
--- a/lib/Sema/DerivedConformanceCodable.cpp
+++ b/lib/Sema/DerivedConformanceCodable.cpp
@@ -466,9 +466,10 @@
                                             NominalTypeDecl *param) {
   // (keyedBy:)
   auto *keyedByDecl = new (C)
-      ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+      ParamDecl(SourceLoc(), SourceLoc(),
                 C.Id_keyedBy, SourceLoc(), C.Id_keyedBy, DC);
   keyedByDecl->setImplicit();
+  keyedByDecl->setSpecifier(ParamSpecifier::Default);
   keyedByDecl->setInterfaceType(returnType);
 
   // container(keyedBy:) method name
@@ -724,8 +725,9 @@
 
   // Params: (Encoder)
   auto *encoderParam = new (C)
-      ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), C.Id_to,
+      ParamDecl(SourceLoc(), SourceLoc(), C.Id_to,
                 SourceLoc(), C.Id_encoder, conformanceDC);
+  encoderParam->setSpecifier(ParamSpecifier::Default);
   encoderParam->setInterfaceType(encoderType);
 
   ParameterList *params = ParameterList::createWithoutLoc(encoderParam);
@@ -748,7 +750,6 @@
     encodeDecl->getAttrs().add(attr);
   }
 
-  encodeDecl->setGenericSignature(conformanceDC->getGenericSignatureOfContext());
   encodeDecl->computeType(FunctionType::ExtInfo().withThrows());
 
   encodeDecl->copyFormalAccessFrom(derived.Nominal,
@@ -1003,9 +1004,10 @@
   // Params: (Decoder)
   auto decoderType = C.getDecoderDecl()->getDeclaredInterfaceType();
   auto *decoderParamDecl = new (C) ParamDecl(
-      ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), C.Id_from,
+      SourceLoc(), SourceLoc(), C.Id_from,
       SourceLoc(), C.Id_decoder, conformanceDC);
   decoderParamDecl->setImplicit();
+  decoderParamDecl->setSpecifier(ParamSpecifier::Default);
   decoderParamDecl->setInterfaceType(decoderType);
 
   auto *paramList = ParameterList::createWithoutLoc(decoderParamDecl);
@@ -1028,7 +1030,6 @@
     initDecl->getAttrs().add(reqAttr);
   }
 
-  initDecl->setGenericSignature(conformanceDC->getGenericSignatureOfContext());
   initDecl->computeType(AnyFunctionType::ExtInfo().withThrows());
 
   initDecl->copyFormalAccessFrom(derived.Nominal,
diff --git a/lib/Sema/DerivedConformanceCodingKey.cpp b/lib/Sema/DerivedConformanceCodingKey.cpp
index dfe00f9..a6e399c 100644
--- a/lib/Sema/DerivedConformanceCodingKey.cpp
+++ b/lib/Sema/DerivedConformanceCodingKey.cpp
@@ -77,9 +77,10 @@
 
   // rawValue param to init(rawValue:)
   auto *rawValueDecl = new (C) ParamDecl(
-      ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), C.Id_rawValue,
+      SourceLoc(), SourceLoc(), C.Id_rawValue,
       SourceLoc(), C.Id_rawValue, parentDC);
   rawValueDecl->setInterfaceType(C.getIntDecl()->getDeclaredType());
+  rawValueDecl->setSpecifier(ParamSpecifier::Default);
   rawValueDecl->setImplicit();
   auto *paramList = ParameterList::createWithoutLoc(rawValueDecl);
 
@@ -119,8 +120,9 @@
 
   // rawValue
   auto *rawDecl =
-      new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+      new (C) ParamDecl(SourceLoc(), SourceLoc(),
                         paramName, SourceLoc(), paramName, parentDC);
+  rawDecl->setSpecifier(ParamSpecifier::Default);
   rawDecl->setInterfaceType(paramType);
   rawDecl->setImplicit();
 
@@ -142,7 +144,6 @@
   synthesizer(initDecl);
 
   // Compute the interface type of the initializer.
-  initDecl->setGenericSignature(parentDC->getGenericSignatureOfContext());
   initDecl->computeType();
 
   initDecl->setAccess(derived.Nominal->getFormalAccess());
diff --git a/lib/Sema/DerivedConformanceDifferentiable.cpp b/lib/Sema/DerivedConformanceDifferentiable.cpp
index 04fc58b..dfd50b1 100644
--- a/lib/Sema/DerivedConformanceDifferentiable.cpp
+++ b/lib/Sema/DerivedConformanceDifferentiable.cpp
@@ -326,9 +326,9 @@
   auto &C = derived.TC.Context;
   auto *parentDC = derived.getConformanceContext();
 
-  auto *param =
-      new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                        argumentName, SourceLoc(), parameterName, parentDC);
+  auto *param = new (C) ParamDecl(SourceLoc(), SourceLoc(), argumentName,
+                                  SourceLoc(), parameterName, parentDC);
+  param->setSpecifier(ParamDecl::Specifier::Default);
   param->setInterfaceType(parameterType);
   ParameterList *params = ParameterList::create(C, {param});
 
@@ -699,7 +699,6 @@
   aliasDecl->setGenericSignature(sourceDC->getGenericSignatureOfContext());
   cast<IterableDeclContext>(sourceDC->getAsDecl())->addMember(aliasDecl);
   aliasDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
-  aliasDecl->computeType();
   TC.validateDecl(aliasDecl);
   C.addSynthesizedDecl(aliasDecl);
 };
@@ -845,7 +844,6 @@
     aliasDecl->setUnderlyingType(selfType);
     aliasDecl->setImplicit();
     aliasDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
-    aliasDecl->computeType();
     TC.validateDecl(aliasDecl);
     derived.addMembersToConformanceContext({aliasDecl});
     C.addSynthesizedDecl(aliasDecl);
diff --git a/lib/Sema/DerivedConformanceElementaryFunctions.cpp b/lib/Sema/DerivedConformanceElementaryFunctions.cpp
index a83d480..57f806b 100644
--- a/lib/Sema/DerivedConformanceElementaryFunctions.cpp
+++ b/lib/Sema/DerivedConformanceElementaryFunctions.cpp
@@ -253,8 +253,9 @@
   // Create parameter declaration with the given name and type.
   auto createParamDecl = [&](StringRef name, Type type) -> ParamDecl * {
     auto *param = new (C)
-        ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                  Identifier(), SourceLoc(), C.getIdentifier(name), parentDC);
+        ParamDecl(SourceLoc(), SourceLoc(), Identifier(), SourceLoc(),
+                  C.getIdentifier(name), parentDC);
+    param->setSpecifier(ParamDecl::Specifier::Default);
     param->setInterfaceType(type);
     return param;
   };
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index c888a5c..fde9b9c 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -47,9 +47,6 @@
                                         ProtocolDecl *protocol) {
   SmallVector<ParamDecl *, 3> nonconformingAssociatedValues;
   for (auto elt : theEnum->getAllElements()) {
-    // FIXME: Remove this once getInterfaceType() on a ParamDecl works.
-    (void) elt->getInterfaceType();
-    
     auto PL = elt->getParameterList();
     if (!PL)
       continue;
@@ -143,8 +140,11 @@
     auto nonconformingAssociatedTypes =
         associatedValuesNotConformingToProtocol(DC, enumDecl, protocol);
     for (auto *typeToDiagnose : nonconformingAssociatedTypes) {
+      SourceLoc reprLoc;
+      if (auto *repr = typeToDiagnose->getTypeRepr())
+        reprLoc = repr->getStartLoc();
       ctx.Diags.diagnose(
-          typeToDiagnose->getTypeLoc().getLoc(),
+          reprLoc,
           diag::missing_member_type_conformance_prevents_synthesis,
           NonconformingMemberKind::AssociatedValue,
           typeToDiagnose->getInterfaceType(), protocol->getDeclaredType(),
@@ -706,9 +706,10 @@
   auto selfIfaceTy = parentDC->getDeclaredInterfaceType();
 
   auto getParamDecl = [&](StringRef s) -> ParamDecl * {
-    auto *param = new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(),
+    auto *param = new (C) ParamDecl(SourceLoc(),
                                     SourceLoc(), Identifier(), SourceLoc(),
                                     C.getIdentifier(s), parentDC);
+    param->setSpecifier(ParamSpecifier::Default);
     param->setInterfaceType(selfIfaceTy);
     return param;
   };
@@ -767,7 +768,6 @@
   eqDecl->setBodySynthesizer(bodySynthesizer);
 
   // Compute the interface type.
-  eqDecl->setGenericSignature(parentDC->getGenericSignatureOfContext());
   eqDecl->computeType();
 
   eqDecl->copyFormalAccessFrom(derived.Nominal, /*sourceIsParentContext*/ true);
@@ -869,10 +869,10 @@
   Type hasherType = hasherDecl->getDeclaredType();
 
   // Params: self (implicit), hasher
-  auto *hasherParamDecl = new (C) ParamDecl(ParamDecl::Specifier::InOut,
-                                            SourceLoc(),
+  auto *hasherParamDecl = new (C) ParamDecl(SourceLoc(),
                                             SourceLoc(), C.Id_into, SourceLoc(),
                                             C.Id_hasher, parentDC);
+  hasherParamDecl->setSpecifier(ParamSpecifier::InOut);
   hasherParamDecl->setInterfaceType(hasherType);
 
   ParameterList *params = ParameterList::createWithoutLoc(hasherParamDecl);
@@ -892,7 +892,6 @@
   hashDecl->setImplicit();
   hashDecl->setBodySynthesizer(bodySynthesizer);
 
-  hashDecl->setGenericSignature(parentDC->getGenericSignatureOfContext());
   hashDecl->computeType();
   hashDecl->copyFormalAccessFrom(derived.Nominal);
 
@@ -1242,7 +1241,6 @@
   getterDecl->setIsTransparent(false);
 
   // Compute the interface type of hashValue().
-  getterDecl->setGenericSignature(parentDC->getGenericSignatureOfContext());
   getterDecl->computeType();
 
   getterDecl->copyFormalAccessFrom(derived.Nominal,
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index d414743..2cb388e 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -410,8 +410,9 @@
   (void)rawType;
 
   auto *rawDecl = new (C)
-      ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+      ParamDecl(SourceLoc(), SourceLoc(),
                 C.Id_rawValue, SourceLoc(), C.Id_rawValue, parentDC);
+  rawDecl->setSpecifier(ParamSpecifier::Default);
   rawDecl->setInterfaceType(rawInterfaceType);
   rawDecl->setImplicit();
   auto paramList = ParameterList::createWithoutLoc(rawDecl);
@@ -429,7 +430,6 @@
   initDecl->setBodySynthesizer(&deriveBodyRawRepresentable_init);
 
   // Compute the interface type of the initializer.
-  initDecl->setGenericSignature(parentDC->getGenericSignatureOfContext());
   initDecl->computeType();
 
   initDecl->copyFormalAccessFrom(enumDecl, /*sourceIsParentContext*/true);
diff --git a/lib/Sema/DerivedConformanceRingMathProtocols.cpp b/lib/Sema/DerivedConformanceRingMathProtocols.cpp
index e2ea63a..d67e2ca 100644
--- a/lib/Sema/DerivedConformanceRingMathProtocols.cpp
+++ b/lib/Sema/DerivedConformanceRingMathProtocols.cpp
@@ -228,8 +228,9 @@
   // Create parameter declaration with the given name and type.
   auto createParamDecl = [&](StringRef name, Type type) -> ParamDecl * {
     auto *param = new (C)
-        ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                  Identifier(), SourceLoc(), C.getIdentifier(name), parentDC);
+        ParamDecl(SourceLoc(), SourceLoc(), Identifier(), SourceLoc(),
+                  C.getIdentifier(name), parentDC);
+    param->setSpecifier(ParamDecl::Specifier::Default);
     param->setInterfaceType(type);
     return param;
   };
diff --git a/lib/Sema/DerivedConformanceTensorArrayProtocol.cpp b/lib/Sema/DerivedConformanceTensorArrayProtocol.cpp
index 2abe2dc..6614bb0 100644
--- a/lib/Sema/DerivedConformanceTensorArrayProtocol.cpp
+++ b/lib/Sema/DerivedConformanceTensorArrayProtocol.cpp
@@ -149,7 +149,8 @@
     // If conformance reference is concrete, then use concrete witness
     // declaration for the operator.
     if (confRef->isConcrete())
-      memberMethodDecl = confRef->getConcrete()->getWitnessDecl(methodReq);
+      memberMethodDecl = confRef->getConcrete()->
+      getWitnessDecl(methodReq);
     assert(memberMethodDecl && "Member method declaration must exist");
     auto memberMethodDRE = new (C) DeclRefExpr(
         memberMethodDecl, DeclNameLoc(), /*Implicit*/ true);
@@ -227,8 +228,9 @@
   auto parentDC = derived.getConformanceContext();
 
   auto *param =
-      new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                        argumentName, SourceLoc(), parameterName, parentDC);
+      new (C) ParamDecl(SourceLoc(), SourceLoc(), argumentName, SourceLoc(),
+                        parameterName, parentDC);
+  param->setSpecifier(ParamDecl::Specifier::Default);
   param->setInterfaceType(parameterType);
   ParameterList *params = ParameterList::create(C, {param});
 
@@ -621,15 +623,15 @@
       C.getOptionalDecl(), Type(), {baseAddressType});
   Type intType = C.getIntDecl()->getDeclaredType();
 
-  auto *param1 = new (C) ParamDecl(
-      ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+  auto *param1 = new (C) ParamDecl(SourceLoc(), SourceLoc(),
       C.getIdentifier("_owning"), SourceLoc(), C.getIdentifier("tensorHandles"),
       parentDC);
+  param1->setSpecifier(ParamDecl::Specifier::Default);
   param1->setInterfaceType(addressType);
-  auto *param2 = new (C) ParamDecl(
-      ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
+  auto *param2 = new (C) ParamDecl(SourceLoc(), SourceLoc(),
       C.getIdentifier("count"), SourceLoc(), C.getIdentifier("count"),
       parentDC);
+  param2->setSpecifier(ParamDecl::Specifier::Default);
   param2->setInterfaceType(intType);
   ParameterList *params = ParameterList::create(C, {param1, param2});
 
diff --git a/lib/Sema/DerivedConformanceTensorGroup.cpp b/lib/Sema/DerivedConformanceTensorGroup.cpp
index 70fd013..656c193 100644
--- a/lib/Sema/DerivedConformanceTensorGroup.cpp
+++ b/lib/Sema/DerivedConformanceTensorGroup.cpp
@@ -323,8 +323,9 @@
   auto parentDC = derived.getConformanceContext();
 
   auto *param =
-      new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                        argumentName, SourceLoc(), parameterName, parentDC);
+      new (C) ParamDecl(SourceLoc(), SourceLoc(), argumentName, SourceLoc(),
+                        parameterName, parentDC);
+  param->setSpecifier(ParamDecl::Specifier::Default);
   param->setInterfaceType(parameterType);
   ParameterList *params = ParameterList::create(C, {param});
 
diff --git a/lib/Sema/DerivedConformanceVectorProtocol.cpp b/lib/Sema/DerivedConformanceVectorProtocol.cpp
index a1b6ad7..d461d05 100644
--- a/lib/Sema/DerivedConformanceVectorProtocol.cpp
+++ b/lib/Sema/DerivedConformanceVectorProtocol.cpp
@@ -214,8 +214,9 @@
   auto parentDC = derived.getConformanceContext();
 
   auto *param =
-      new (C) ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-                        argumentLabel, SourceLoc(), parameterName, parentDC);
+      new (C) ParamDecl(SourceLoc(), SourceLoc(), argumentLabel, SourceLoc(),
+                        parameterName, parentDC);
+  param->setSpecifier(ParamDecl::Specifier::Default);
   param->setInterfaceType(parameterType);
   ParameterList *params = ParameterList::create(C, {param});
 
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index 4de8767..0be5357 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -507,8 +507,6 @@
 AccessorDecl *
 DerivedConformance::declareDerivedPropertyGetter(VarDecl *property,
                                                  Type propertyContextType) {
-  bool isStatic = property->isStatic();
-
   auto &C = property->getASTContext();
   auto parentDC = property->getDeclContext();
   ParameterList *params = ParameterList::createEmpty(C);
@@ -523,11 +521,9 @@
     /*GenericParams=*/nullptr, params,
     TypeLoc::withoutLoc(propertyInterfaceType), parentDC);
   getterDecl->setImplicit();
-  getterDecl->setStatic(isStatic);
   getterDecl->setIsTransparent(false);
 
   // Compute the interface type of the getter.
-  getterDecl->setGenericSignature(parentDC->getGenericSignatureOfContext());
   getterDecl->computeType();
 
   getterDecl->copyFormalAccessFrom(property);
@@ -548,10 +544,9 @@
   auto parentDC = property->getDeclContext();
 
   auto propertyInterfaceType = property->getInterfaceType();
-  auto propertyParam = new (C)
-    ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
-              Identifier(), property->getLoc(), C.getIdentifier("newValue"),
-              parentDC);
+  auto propertyParam = new (C) ParamDecl(SourceLoc(), SourceLoc(), Identifier(),
+              property->getLoc(), C.getIdentifier("newValue"), parentDC);
+  propertyParam->setSpecifier(ParamDecl::Specifier::Default);
   propertyParam->setInterfaceType(propertyInterfaceType);
 
   ParameterList *params = ParameterList::create(C, propertyParam);
diff --git a/lib/Sema/QuoteTransform.cpp b/lib/Sema/QuoteTransform.cpp
index c90a271..d57a4a3 100644
--- a/lib/Sema/QuoteTransform.cpp
+++ b/lib/Sema/QuoteTransform.cpp
@@ -39,7 +39,7 @@
   void pop() { locs.pop_back(); }
 
   SourceLoc getLoc() {
-    for (auto loc : reversed(locs)) {
+    for (auto loc : llvm::reverse(locs)) {
       if (loc.isValid()) {
         return loc.Start;
       }
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index e6a83b6..af9c636 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -259,44 +259,23 @@
   return hadAnyIssues;
 }
 
-void TypeChecker::diagnoseGenericTypeExportability(const TypeLoc &TL,
+void TypeChecker::diagnoseGenericTypeExportability(SourceLoc Loc, Type T,
                                                    const DeclContext *DC) {
-  class GenericTypeFinder : public TypeDeclFinder {
-    using Callback = llvm::function_ref<void(SubstitutionMap)>;
-
-    const SourceFile &SF;
-    Callback callback;
-  public:
-    GenericTypeFinder(const SourceFile &SF, Callback callback)
-        : SF(SF), callback(callback) {}
-
-
-    Action visitBoundGenericType(BoundGenericType *ty) override {
-      ModuleDecl *useModule = SF.getParentModule();
-      SubstitutionMap subs = ty->getContextSubstitutionMap(useModule,
-                                                           ty->getDecl());
-      callback(subs);
-      return Action::Continue;
-    }
-
-    Action visitTypeAliasType(TypeAliasType *ty) override {
-      callback(ty->getSubstitutionMap());
-      return Action::Continue;
-    }
-  };
-
-  assert(TL.getType() && "type not validated yet");
-
   const SourceFile *SF = DC->getParentSourceFile();
   if (!SF)
     return;
 
-  TL.getType().walk(GenericTypeFinder(*SF, [&](SubstitutionMap subs) {
-    // FIXME: It would be nice to highlight just the part of the type that's
-    // problematic, but unfortunately the TypeRepr doesn't have the
-    // information we need and the Type doesn't easily map back to it.
-    (void)diagnoseGenericArgumentsExportability(TL.getLoc(), subs, *SF);
-  }));
+  // FIXME: It would be nice to highlight just the part of the type that's
+  // problematic, but unfortunately the TypeRepr doesn't have the
+  // information we need and the Type doesn't easily map back to it.
+  if (auto *BGT = dyn_cast<BoundGenericType>(T.getPointer())) {
+    ModuleDecl *useModule = SF->getParentModule();
+    auto subs = T->getContextSubstitutionMap(useModule, BGT->getDecl());
+    (void)diagnoseGenericArgumentsExportability(Loc, subs, *SF);
+  } else if (auto *TAT = dyn_cast<TypeAliasType>(T.getPointer())) {
+    auto subs = TAT->getSubstitutionMap();
+    (void)diagnoseGenericArgumentsExportability(Loc, subs, *SF);
+  }
 }
 
 bool
diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp
index 5d9f636..142234f 100644
--- a/lib/Sema/TypeCheckAccess.cpp
+++ b/lib/Sema/TypeCheckAccess.cpp
@@ -865,18 +865,18 @@
     bool problemIsElement = false;
 
     for (auto &P : *SD->getIndices()) {
-      checkTypeAccess(P->getTypeLoc(), SD, /*mayBeInferred*/false,
-                      [&](AccessScope typeAccessScope,
-                          const TypeRepr *thisComplainRepr,
-                          DowngradeToWarning downgradeDiag) {
-        if (typeAccessScope.isChildOf(minAccessScope) ||
-            (!complainRepr &&
-             typeAccessScope.hasEqualDeclContextWith(minAccessScope))) {
-          minAccessScope = typeAccessScope;
-          complainRepr = thisComplainRepr;
-          downgradeToWarning = downgradeDiag;
-        }
-      });
+      checkTypeAccess(
+          P->getInterfaceType(), P->getTypeRepr(), SD, /*mayBeInferred*/ false,
+          [&](AccessScope typeAccessScope, const TypeRepr *thisComplainRepr,
+              DowngradeToWarning downgradeDiag) {
+            if (typeAccessScope.isChildOf(minAccessScope) ||
+                (!complainRepr &&
+                 typeAccessScope.hasEqualDeclContextWith(minAccessScope))) {
+              minAccessScope = typeAccessScope;
+              complainRepr = thisComplainRepr;
+              downgradeToWarning = downgradeDiag;
+            }
+          });
     }
 
     checkTypeAccess(SD->getElementTypeLoc(), SD, /*mayBeInferred*/false,
@@ -930,18 +930,18 @@
     auto downgradeToWarning = DowngradeToWarning::No;
 
     for (auto *P : *fn->getParameters()) {
-      checkTypeAccess(P->getTypeLoc(), fn, /*mayBeInferred*/false,
-                      [&](AccessScope typeAccessScope,
-                          const TypeRepr *thisComplainRepr,
-                          DowngradeToWarning downgradeDiag) {
-        if (typeAccessScope.isChildOf(minAccessScope) ||
-            (!complainRepr &&
-             typeAccessScope.hasEqualDeclContextWith(minAccessScope))) {
-          minAccessScope = typeAccessScope;
-          complainRepr = thisComplainRepr;
-          downgradeToWarning = downgradeDiag;
-        }
-      });
+      checkTypeAccess(
+          P->getInterfaceType(), P->getTypeRepr(), fn, /*mayBeInferred*/ false,
+          [&](AccessScope typeAccessScope, const TypeRepr *thisComplainRepr,
+              DowngradeToWarning downgradeDiag) {
+            if (typeAccessScope.isChildOf(minAccessScope) ||
+                (!complainRepr &&
+                 typeAccessScope.hasEqualDeclContextWith(minAccessScope))) {
+              minAccessScope = typeAccessScope;
+              complainRepr = thisComplainRepr;
+              downgradeToWarning = downgradeDiag;
+            }
+          });
     }
 
     bool problemIsResult = false;
@@ -990,18 +990,18 @@
     if (!EED->hasAssociatedValues())
       return;
     for (auto &P : *EED->getParameterList()) {
-      checkTypeAccess(P->getTypeLoc(), EED, /*mayBeInferred*/false,
-                      [&](AccessScope typeAccessScope,
-                          const TypeRepr *complainRepr,
-                          DowngradeToWarning downgradeToWarning) {
-        auto typeAccess = typeAccessScope.accessLevelForDiagnostics();
-        auto diagID = diag::enum_case_access;
-        if (downgradeToWarning == DowngradeToWarning::Yes)
-          diagID = diag::enum_case_access_warn;
-        auto diag = TC.diagnose(EED, diagID,
-                                EED->getFormalAccess(), typeAccess);
-        highlightOffendingType(TC, diag, complainRepr);
-      });
+      checkTypeAccess(
+          P->getInterfaceType(), P->getTypeRepr(), EED, /*mayBeInferred*/ false,
+          [&](AccessScope typeAccessScope, const TypeRepr *complainRepr,
+              DowngradeToWarning downgradeToWarning) {
+            auto typeAccess = typeAccessScope.accessLevelForDiagnostics();
+            auto diagID = diag::enum_case_access;
+            if (downgradeToWarning == DowngradeToWarning::Yes)
+              diagID = diag::enum_case_access_warn;
+            auto diag =
+                TC.diagnose(EED, diagID, EED->getFormalAccess(), typeAccess);
+            highlightOffendingType(TC, diag, complainRepr);
+          });
     }
   }
 };
@@ -1375,17 +1375,17 @@
     checkGenericParamAccess(SD->getGenericParams(), SD);
 
     for (auto &P : *SD->getIndices()) {
-      checkTypeAccess(P->getTypeLoc(), SD, /*mayBeInferred*/false,
-                      [&](AccessScope typeAccessScope,
-                          const TypeRepr *complainRepr,
-                          DowngradeToWarning downgradeDiag) {
-        auto diagID = diag::subscript_type_usable_from_inline;
-        if (!TC.Context.isSwiftVersionAtLeast(5))
-          diagID = diag::subscript_type_usable_from_inline_warn;
-        auto diag = TC.diagnose(SD, diagID,
-                                /*problemIsElement=*/false);
-        highlightOffendingType(TC, diag, complainRepr);
-      });
+      checkTypeAccess(
+          P->getInterfaceType(), P->getTypeRepr(), SD, /*mayBeInferred*/ false,
+          [&](AccessScope typeAccessScope, const TypeRepr *complainRepr,
+              DowngradeToWarning downgradeDiag) {
+            auto diagID = diag::subscript_type_usable_from_inline;
+            if (!TC.Context.isSwiftVersionAtLeast(5))
+              diagID = diag::subscript_type_usable_from_inline_warn;
+            auto diag = TC.diagnose(SD, diagID,
+                                    /*problemIsElement=*/false);
+            highlightOffendingType(TC, diag, complainRepr);
+          });
     }
 
     checkTypeAccess(SD->getElementTypeLoc(), SD, /*mayBeInferred*/false,
@@ -1418,17 +1418,17 @@
       : isTypeContext ? FK_Method : FK_Function;
 
     for (auto *P : *fn->getParameters()) {
-      checkTypeAccess(P->getTypeLoc(), fn, /*mayBeInferred*/false,
-                      [&](AccessScope typeAccessScope,
-                          const TypeRepr *complainRepr,
-                          DowngradeToWarning downgradeDiag) {
-        auto diagID = diag::function_type_usable_from_inline;
-        if (!TC.Context.isSwiftVersionAtLeast(5))
-          diagID = diag::function_type_usable_from_inline_warn;
-        auto diag = TC.diagnose(fn, diagID, functionKind,
-                                /*problemIsResult=*/false);
-        highlightOffendingType(TC, diag, complainRepr);
-      });
+      checkTypeAccess(
+          P->getInterfaceType(), P->getTypeRepr(), fn, /*mayBeInferred*/ false,
+          [&](AccessScope typeAccessScope, const TypeRepr *complainRepr,
+              DowngradeToWarning downgradeDiag) {
+            auto diagID = diag::function_type_usable_from_inline;
+            if (!TC.Context.isSwiftVersionAtLeast(5))
+              diagID = diag::function_type_usable_from_inline_warn;
+            auto diag = TC.diagnose(fn, diagID, functionKind,
+                                    /*problemIsResult=*/false);
+            highlightOffendingType(TC, diag, complainRepr);
+          });
     }
 
     if (auto FD = dyn_cast<FuncDecl>(fn)) {
@@ -1450,16 +1450,16 @@
     if (!EED->hasAssociatedValues())
       return;
     for (auto &P : *EED->getParameterList()) {
-      checkTypeAccess(P->getTypeLoc(), EED, /*mayBeInferred*/false,
-                      [&](AccessScope typeAccessScope,
-                          const TypeRepr *complainRepr,
-                          DowngradeToWarning downgradeToWarning) {
-        auto diagID = diag::enum_case_usable_from_inline;
-        if (!TC.Context.isSwiftVersionAtLeast(5))
-          diagID = diag::enum_case_usable_from_inline_warn;
-        auto diag = TC.diagnose(EED, diagID);
-        highlightOffendingType(TC, diag, complainRepr);
-      });
+      checkTypeAccess(
+          P->getInterfaceType(), P->getTypeRepr(), EED, /*mayBeInferred*/ false,
+          [&](AccessScope typeAccessScope, const TypeRepr *complainRepr,
+              DowngradeToWarning downgradeToWarning) {
+            auto diagID = diag::enum_case_usable_from_inline;
+            if (!TC.Context.isSwiftVersionAtLeast(5))
+              diagID = diag::enum_case_usable_from_inline_warn;
+            auto diag = TC.diagnose(EED, diagID);
+            highlightOffendingType(TC, diag, complainRepr);
+          });
     }
   }
 };
@@ -1887,8 +1887,8 @@
     checkGenericParams(SD->getGenericParams(), SD);
 
     for (auto &P : *SD->getIndices()) {
-      checkType(P->getTypeLoc(), SD, getDiagnoseCallback(SD),
-                getDiagnoseCallback(SD));
+      checkType(P->getInterfaceType(), P->getTypeRepr(), SD,
+                getDiagnoseCallback(SD), getDiagnoseCallback(SD));
     }
     checkType(SD->getElementTypeLoc(), SD, getDiagnoseCallback(SD),
               getDiagnoseCallback(SD));
@@ -1898,8 +1898,8 @@
     checkGenericParams(fn->getGenericParams(), fn);
 
     for (auto *P : *fn->getParameters())
-      checkType(P->getTypeLoc(), fn, getDiagnoseCallback(fn),
-                getDiagnoseCallback(fn));
+      checkType(P->getInterfaceType(), P->getTypeRepr(), fn,
+                getDiagnoseCallback(fn), getDiagnoseCallback(fn));
   }
 
   void visitFuncDecl(FuncDecl *FD) {
@@ -1912,8 +1912,8 @@
     if (!EED->hasAssociatedValues())
       return;
     for (auto &P : *EED->getParameterList())
-      checkType(P->getTypeLoc(), EED, getDiagnoseCallback(EED),
-                getDiagnoseCallback(EED));
+      checkType(P->getInterfaceType(), P->getTypeRepr(), EED,
+                getDiagnoseCallback(EED), getDiagnoseCallback(EED));
   }
 
   void checkConstrainedExtensionRequirements(ExtensionDecl *ED,
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 8e8d5c8..dda4796 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -1231,7 +1231,7 @@
           Expr *target = nullptr;
           bool foundApply = false;
           bool foundRebind = false;
-          for (auto ancestor : reversed(ExprStack)) {
+          for (auto ancestor : llvm::reverse(ExprStack)) {
             if (isa<RebindSelfInConstructorExpr>(ancestor)) {
               // If we already have a rebind, then we're re-typechecking an
               // expression and are done.
@@ -1345,17 +1345,17 @@
   auto *PL = closure->getParameters();
 
   // Validate the parameters.
-  TypeResolutionOptions options(TypeResolverContext::ClosureExpr);
-  options |= TypeResolutionFlags::AllowUnspecifiedTypes;
-  options |= TypeResolutionFlags::AllowUnboundGenerics;
   bool hadParameterError = false;
 
-  if (TC.typeCheckParameterList(PL, closure, options)) {
-    // If we encounter an error validating the parameter list, don't bail.
-    // Instead, go on to validate any potential result type, and bail
-    // afterwards.  This allows for better diagnostics, and keeps the
-    // closure expression type well-formed.
-    hadParameterError = true;
+  // If we encounter an error validating the parameter list, don't bail.
+  // Instead, go on to validate any potential result type, and bail
+  // afterwards.  This allows for better diagnostics, and keeps the
+  // closure expression type well-formed.
+  for (auto param : *PL) {
+    // FIXME: Forces computation of isInvalid().
+    (void) param->getInterfaceType();
+
+    hadParameterError |= param->isInvalid();
   }
 
   // Validate the result type, if present.
@@ -2035,7 +2035,7 @@
 void ParentConditionalConformance::diagnoseConformanceStack(
     DiagnosticEngine &diags, SourceLoc loc,
     ArrayRef<ParentConditionalConformance> conformances) {
-  for (auto history : reversed(conformances)) {
+  for (auto history : llvm::reverse(conformances)) {
     diags.diagnose(loc, diag::requirement_implied_by_conditional_conformance,
                    history.ConformingType, history.Protocol);
   }
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 9431583..2de6005 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -1164,7 +1164,7 @@
 
       // Backing storage for 'lazy' or property wrappers is always final.
       if (VD->isLazyStorageProperty() ||
-          VD->getOriginalWrappedProperty())
+          VD->getOriginalWrappedProperty(PropertyWrapperSynthesizedPropertyKind::Backing))
         return true;
 
       if (auto *nominalDecl = VD->getDeclContext()->getSelfClassDecl()) {
@@ -1246,6 +1246,9 @@
 
 llvm::Expected<bool>
 IsStaticRequest::evaluate(Evaluator &evaluator, FuncDecl *decl) const {
+  if (auto *accessor = dyn_cast<AccessorDecl>(decl))
+    return accessor->getStorage()->isStatic();
+
   bool result = (decl->getStaticLoc().isValid() ||
                  decl->getStaticSpelling() != StaticSpellingKind::None);
   auto *dc = decl->getDeclContext();
@@ -1654,6 +1657,13 @@
       continue;
     }
 
+    // If the raw values of the enum case are fixed, then we trust our callers
+    // to have set things up correctly.  This comes up with imported enums
+    // and deserialized @objc enums which always have their raw values setup
+    // beforehand.
+    if (ED->LazySemanticInfo.hasFixedRawValues())
+      continue;
+
     // Check that the raw value is unique.
     RawValueKey key{prevValue};
     RawValueSource source{elt, lastExplicitValueElt};
@@ -2083,10 +2093,17 @@
   return group;
 }
 
+bool swift::doesContextHaveValueSemantics(DeclContext *dc) {
+  if (Type contextTy = dc->getDeclaredInterfaceType())
+    return !contextTy->hasReferenceSemantics();
+  return false;
+}
+
 llvm::Expected<SelfAccessKind>
 SelfAccessKindRequest::evaluate(Evaluator &evaluator, FuncDecl *FD) const {
   if (FD->getAttrs().getAttribute<MutatingAttr>(true)) {
-    if (!FD->isInstanceMember() || !FD->getDeclContext()->hasValueSemantics()) {
+    if (!FD->isInstanceMember() ||
+        !doesContextHaveValueSemantics(FD->getDeclContext())) {
       return SelfAccessKind::NonMutating;
     }
     return SelfAccessKind::Mutating;
@@ -2108,7 +2125,8 @@
     case AccessorKind::MutableAddress:
     case AccessorKind::Set:
     case AccessorKind::Modify:
-      if (AD->isInstanceMember() && AD->getDeclContext()->hasValueSemantics())
+      if (AD->isInstanceMember() &&
+          doesContextHaveValueSemantics(AD->getDeclContext()))
         return SelfAccessKind::Mutating;
       break;
 
@@ -3231,6 +3249,20 @@
                      FD->getFullName());
       }
     }
+
+    // If the function is exported to C, it must be representable in (Obj-)C.
+    // FIXME: This needs to be moved to its own request if we want to
+    // productize @_cdecl.
+    if (auto CDeclAttr = FD->getAttrs().getAttribute<swift::CDeclAttr>()) {
+      Optional<ForeignErrorConvention> errorConvention;
+      if (isRepresentableInObjC(FD, ObjCReason::ExplicitlyCDecl,
+                                errorConvention)) {
+        if (FD->hasThrows()) {
+          FD->setForeignErrorConvention(*errorConvention);
+          TC.diagnose(CDeclAttr->getLocation(), diag::cdecl_throws);
+        }
+      }
+    }
   }
 
   void visitModuleDecl(ModuleDecl *) { }
@@ -3573,6 +3605,47 @@
   DeclChecker(*this).visit(D);
 }
 
+// Returns 'nullptr' if this is the setter's 'newValue' parameter;
+// otherwise, returns the corresponding parameter of the subscript
+// declaration.
+static ParamDecl *getOriginalParamFromAccessor(AbstractStorageDecl *storage,
+                                               AccessorDecl *accessor,
+                                               ParamDecl *param) {
+  auto *accessorParams = accessor->getParameters();
+  unsigned startIndex = 0;
+
+  switch (accessor->getAccessorKind()) {
+  case AccessorKind::DidSet:
+  case AccessorKind::WillSet:
+  case AccessorKind::Set:
+    if (param == accessorParams->get(0)) {
+      // This is the 'newValue' parameter.
+      return nullptr;
+    }
+
+    startIndex = 1;
+    break;
+
+  default:
+    startIndex = 0;
+    break;
+  }
+
+  // If the parameter is not the 'newValue' parameter to a setter, it
+  // must be a subscript index parameter (or we have an invalid AST).
+  auto *subscript = cast<SubscriptDecl>(storage);
+  auto *subscriptParams = subscript->getIndices();
+
+  auto where = llvm::find_if(*accessorParams,
+                              [param](ParamDecl *other) {
+                                return other == param;
+                              });
+  assert(where != accessorParams->end());
+  unsigned index = where - accessorParams->begin();
+
+  return subscriptParams->get(index - startIndex);
+}
+
 llvm::Expected<bool>
 IsImplicitlyUnwrappedOptionalRequest::evaluate(Evaluator &evaluator,
                                                ValueDecl *decl) const {
@@ -3593,7 +3666,7 @@
     if (auto *subscript = dyn_cast<SubscriptDecl>(storage))
       TyR = subscript->getElementTypeLoc().getTypeRepr();
     else
-      TyR = cast<VarDecl>(storage)->getTypeLoc().getTypeRepr();
+      TyR = cast<VarDecl>(storage)->getTypeRepr();
     break;
   }
 
@@ -3606,51 +3679,20 @@
     if (param->isSelfParameter())
       return false;
 
-    // FIXME: This "which accessor parameter am I" dance will come up in
-    // other requests too. Factor it out when needed.
     if (auto *accessor = dyn_cast<AccessorDecl>(param->getDeclContext())) {
       auto *storage = accessor->getStorage();
-      auto *accessorParams = accessor->getParameters();
-      unsigned startIndex = 0;
-
-      switch (accessor->getAccessorKind()) {
-      case AccessorKind::DidSet:
-      case AccessorKind::WillSet:
-      case AccessorKind::Set:
-        if (param == accessorParams->get(0)) {
-          // This is the 'newValue' parameter.
-          return storage->isImplicitlyUnwrappedOptional();
-        }
-
-        startIndex = 1;
-        break;
-
-      default:
-        startIndex = 0;
-        break;
+      auto *originalParam = getOriginalParamFromAccessor(
+        storage, accessor, param);
+      if (originalParam == nullptr) {
+        // This is the setter's newValue parameter.
+        return storage->isImplicitlyUnwrappedOptional();
       }
 
-      // If the parameter is not the 'newValue' parameter to a setter, it
-      // must be a subscript index parameter (or we have an invalid AST).
-      auto *subscript = dyn_cast<SubscriptDecl>(storage);
-      if (!subscript)
-        return false;
-      auto *subscriptParams = subscript->getIndices();
-
-      auto where = llvm::find_if(*accessorParams,
-                                  [param](ParamDecl *other) {
-                                    return other == param;
-                                  });
-      assert(where != accessorParams->end());
-      unsigned index = where - accessorParams->begin();
-
-      auto *subscriptParam = subscriptParams->get(index - startIndex);
-
-      if (param != subscriptParam) {
+      if (param != originalParam) {
         // This is the 'subscript(...) { get { ... } set { ... } }' case.
         // This means we cloned the parameter list for each accessor.
         // Delegate to the original parameter.
-        return subscriptParam->isImplicitlyUnwrappedOptional();
+        return originalParam->isImplicitlyUnwrappedOptional();
       }
 
       // This is the 'subscript(...) { <<body of getter>> }' case.
@@ -3659,7 +3701,7 @@
     }
 
     // Handle eg, 'inout Int!' or '__owned NSObject!'.
-    TyR = param->getTypeLoc().getTypeRepr();
+    TyR = param->getTypeRepr();
     if (auto *STR = dyn_cast_or_null<SpecifierTypeRepr>(TyR))
       TyR = STR->getBase();
     break;
@@ -3892,8 +3934,7 @@
   return false;
 }
 
-static Type buildAddressorResultType(TypeChecker &TC,
-                                     AccessorDecl *addressor,
+static Type buildAddressorResultType(AccessorDecl *addressor,
                                      Type valueType) {
   assert(addressor->getAccessorKind() == AccessorKind::Address ||
          addressor->getAccessorKind() == AccessorKind::MutableAddress);
@@ -3905,34 +3946,185 @@
   return valueType->wrapInPointer(pointerKind);
 }
 
+llvm::Expected<Type>
+ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
+  auto &ctx = decl->getASTContext();
 
-static void validateResultType(ValueDecl *decl,
-                               TypeLoc &resultTyLoc) {
-  // Nothing to do if there's no result type loc to set into.
-  if (resultTyLoc.isNull())
-    return;
+  // Accessors always inherit their result type from their storage.
+  if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
+    auto *storage = accessor->getStorage();
 
-  // Check the result type. It is allowed to be opaque.
+    switch (accessor->getAccessorKind()) {
+    // For getters, set the result type to the value type.
+    case AccessorKind::Get:
+      return storage->getValueInterfaceType();
+
+    // For setters and observers, set the old/new value parameter's type
+    // to the value type.
+    case AccessorKind::DidSet:
+    case AccessorKind::WillSet:
+    case AccessorKind::Set:
+      return TupleType::getEmpty(ctx);
+
+    // Addressor result types can get complicated because of the owner.
+    case AccessorKind::Address:
+    case AccessorKind::MutableAddress:
+      return buildAddressorResultType(accessor, storage->getValueInterfaceType());
+
+    // Coroutine accessors don't mention the value type directly.
+    // If we add yield types to the function type, we'll need to update this.
+    case AccessorKind::Read:
+    case AccessorKind::Modify:
+      return TupleType::getEmpty(ctx);
+    }
+  }
+
+  auto *resultTyRepr = getResultTypeLoc().getTypeRepr();
+
+  // Nothing to do if there's no result type.
+  if (resultTyRepr == nullptr)
+    return TupleType::getEmpty(ctx);
+
+  // Handle opaque types.
   if (decl->getOpaqueResultTypeRepr()) {
     auto *opaqueDecl = decl->getOpaqueResultTypeDecl();
-    resultTyLoc.setType(
-        opaqueDecl
-        ? opaqueDecl->getDeclaredInterfaceType()
-        : ErrorType::get(decl->getASTContext()));
-  } else {
-    auto *dc = decl->getInnermostDeclContext();
-    auto resolution = TypeResolution::forInterface(dc);
-    TypeChecker::validateType(dc->getASTContext(),
-                              resultTyLoc, resolution,
-                              TypeResolverContext::FunctionResult);
+    return (opaqueDecl
+            ? opaqueDecl->getDeclaredInterfaceType()
+            : ErrorType::get(ctx));
   }
+
+  auto *dc = decl->getInnermostDeclContext();
+  auto resolution = TypeResolution::forInterface(dc);
+  return resolution.resolveType(
+      resultTyRepr, TypeResolverContext::FunctionResult);
+}
+
+llvm::Expected<ParamSpecifier>
+ParamSpecifierRequest::evaluate(Evaluator &evaluator,
+                                ParamDecl *param) const {
+  auto *dc = param->getDeclContext();
+
+  if (param->isSelfParameter()) {
+    auto selfParam = computeSelfParam(cast<AbstractFunctionDecl>(dc),
+                                      /*isInitializingCtor*/true,
+                                      /*wantDynamicSelf*/false);
+    return (selfParam.getParameterFlags().isInOut()
+            ? ParamSpecifier::InOut
+            : ParamSpecifier::Default);
+  }
+
+  if (auto *accessor = dyn_cast<AccessorDecl>(dc)) {
+    auto *storage = accessor->getStorage();
+    auto *originalParam = getOriginalParamFromAccessor(
+      storage, accessor, param);
+    if (originalParam == nullptr) {
+      // This is the setter's newValue parameter. Note that even though
+      // the AST uses the 'Default' specifier, SIL will lower this to a
+      // +1 parameter.
+      return ParamSpecifier::Default;
+    }
+
+    if (param != originalParam) {
+      // This is the 'subscript(...) { get { ... } set { ... } }' case.
+      // This means we cloned the parameter list for each accessor.
+      // Delegate to the original parameter.
+      return originalParam->getSpecifier();
+    }
+
+    // This is the 'subscript(...) { <<body of getter>> }' case.
+    // The subscript and the getter share their ParamDecls.
+    // Fall through.
+  }
+
+  auto typeRepr = param->getTypeRepr();
+  assert(typeRepr != nullptr && "Should call setSpecifier() on "
+         "synthesized parameter declarations");
+
+  auto *nestedRepr = typeRepr;
+
+  // Look through parens here; other than parens, specifiers
+  // must appear at the top level of a parameter type.
+  while (auto *tupleRepr = dyn_cast<TupleTypeRepr>(nestedRepr)) {
+    if (!tupleRepr->isParenType())
+      break;
+    nestedRepr = tupleRepr->getElementType(0);
+  }
+
+  if (isa<InOutTypeRepr>(nestedRepr) &&
+      param->isDefaultArgument()) {
+    auto &ctx = param->getASTContext();
+    ctx.Diags.diagnose(param->getDefaultValue()->getLoc(),
+                       swift::diag::cannot_provide_default_value_inout,
+                       param->getName());
+    return ParamSpecifier::Default;
+  }
+
+  if (isa<InOutTypeRepr>(nestedRepr)) {
+    return ParamSpecifier::InOut;
+  } else if (isa<SharedTypeRepr>(nestedRepr)) {
+    return ParamSpecifier::Shared;
+  } else if (isa<OwnedTypeRepr>(nestedRepr)) {
+    return ParamSpecifier::Owned;
+  }
+
+  return ParamSpecifier::Default;
+}
+
+static Type validateParameterType(ParamDecl *decl) {
+  auto *dc = decl->getDeclContext();
+  auto resolution = TypeResolution::forInterface(dc);
+
+  TypeResolutionOptions options(None);
+  if (isa<AbstractClosureExpr>(dc)) {
+    options = TypeResolutionOptions(TypeResolverContext::ClosureExpr);
+    options |= TypeResolutionFlags::AllowUnspecifiedTypes;
+    options |= TypeResolutionFlags::AllowUnboundGenerics;
+  } else if (isa<AbstractFunctionDecl>(dc)) {
+    options = TypeResolutionOptions(TypeResolverContext::AbstractFunctionDecl);
+  } else if (isa<SubscriptDecl>(dc)) {
+    options = TypeResolutionOptions(TypeResolverContext::SubscriptDecl);
+  } else {
+    assert(isa<EnumElementDecl>(dc));
+    options = TypeResolutionOptions(TypeResolverContext::EnumElementDecl);
+  }
+
+  // If the element is a variadic parameter, resolve the parameter type as if
+  // it were in non-parameter position, since we want functions to be
+  // @escaping in this case.
+  options.setContext(decl->isVariadic() ?
+                       TypeResolverContext::VariadicFunctionInput :
+                       TypeResolverContext::FunctionInput);
+  options |= TypeResolutionFlags::Direct;
+
+  auto TL = TypeLoc(decl->getTypeRepr());
+
+  auto &ctx = dc->getASTContext();
+  if (TypeChecker::validateType(ctx, TL, resolution, options)) {
+    decl->setInvalid();
+    return ErrorType::get(ctx);
+  }
+
+  Type Ty = TL.getType();
+  if (decl->isVariadic()) {
+    Ty = TypeChecker::getArraySliceType(decl->getStartLoc(), Ty);
+    if (Ty.isNull()) {
+      decl->setInvalid();
+      return ErrorType::get(ctx);
+    }
+
+    // Disallow variadic parameters in enum elements.
+    if (options.getBaseContext() == TypeResolverContext::EnumElementDecl) {
+      decl->diagnose(diag::enum_element_ellipsis);
+      decl->setInvalid();
+      return ErrorType::get(ctx);
+    }
+
+    return Ty;
+  }
+  return TL.getType();
 }
 
 void TypeChecker::validateDecl(ValueDecl *D) {
-  // Generic parameters are validated as part of their context.
-  if (isa<GenericTypeParamDecl>(D))
-    return;
-
   // Handling validation failure due to re-entrancy is left
   // up to the caller, who must call hasInterfaceType() to
   // check that validateDecl() returned a fully-formed decl.
@@ -3960,35 +4152,44 @@
   case DeclKind::IfConfig:
   case DeclKind::PoundDiagnostic:
   case DeclKind::MissingMember:
-    llvm_unreachable("not a value decl");
-
   case DeclKind::Module:
-    return;
-      
+  case DeclKind::OpaqueType:
   case DeclKind::GenericTypeParam:
-    llvm_unreachable("handled above");
+    llvm_unreachable("should not get here");
+    return;
 
   case DeclKind::AssociatedType: {
     auto assocType = cast<AssociatedTypeDecl>(D);
-    assocType->computeType();
+    auto interfaceTy = assocType->getDeclaredInterfaceType();
+    assocType->setInterfaceType(MetatypeType::get(interfaceTy, Context));
     break;
   }
 
   case DeclKind::TypeAlias: {
     auto typeAlias = cast<TypeAliasDecl>(D);
-    typeAlias->computeType();
+
+    auto genericSig = typeAlias->getGenericSignature();
+    SubstitutionMap subs;
+    if (genericSig)
+      subs = genericSig->getIdentitySubstitutionMap();
+
+    Type parent;
+    auto parentDC = typeAlias->getDeclContext();
+    if (parentDC->isTypeContext())
+      parent = parentDC->getSelfInterfaceType();
+    auto sugaredType = TypeAliasType::get(typeAlias, parent, subs,
+                                          typeAlias->getUnderlyingType());
+    typeAlias->setInterfaceType(MetatypeType::get(sugaredType, Context));
     break;
   }
-      
-  case DeclKind::OpaqueType:
-    break;
 
   case DeclKind::Enum:
   case DeclKind::Struct:
   case DeclKind::Class:
   case DeclKind::Protocol: {
     auto nominal = cast<NominalTypeDecl>(D);
-    nominal->computeType();
+    Type declaredInterfaceTy = nominal->getDeclaredInterfaceType();
+    nominal->setInterfaceType(MetatypeType::get(declaredInterfaceTy, Context));
 
     if (auto *ED = dyn_cast<EnumDecl>(nominal)) {
       // @objc enums use their raw values as the value representation, so we
@@ -4006,10 +4207,40 @@
     break;
   }
 
-  case DeclKind::Param:
-    // Can't fallthough because parameter without a type doesn't have
-    // valid signature, but that shouldn't matter anyway.
-    return;
+  case DeclKind::Param: {
+    auto *PD = cast<ParamDecl>(D);
+    if (PD->isSelfParameter()) {
+      auto *AFD = cast<AbstractFunctionDecl>(PD->getDeclContext());
+      auto selfParam = computeSelfParam(AFD,
+                                        /*isInitializingCtor*/true,
+                                        /*wantDynamicSelf*/true);
+      PD->setInterfaceType(selfParam.getPlainType());
+      break;
+    }
+
+    if (auto *accessor = dyn_cast<AccessorDecl>(PD->getDeclContext())) {
+      auto *storage = accessor->getStorage();
+      auto *originalParam = getOriginalParamFromAccessor(
+        storage, accessor, PD);
+      if (originalParam == nullptr) {
+        auto type = storage->getValueInterfaceType();
+        PD->setInterfaceType(type);
+        break;
+      }
+
+      if (originalParam != PD) {
+        PD->setInterfaceType(originalParam->getInterfaceType());
+        break;
+      }
+    }
+
+    if (!PD->getTypeRepr())
+      return;
+
+    auto ty = validateParameterType(PD);
+    PD->setInterfaceType(ty);
+    break;
+  }
 
   case DeclKind::Var: {
     auto *VD = cast<VarDecl>(D);
@@ -4047,147 +4278,36 @@
   }
 
   case DeclKind::Func:
-  case DeclKind::Accessor: {
-    auto *FD = cast<FuncDecl>(D);
-
-    DeclValidationRAII IBV(FD);
-
-    // Accessors should pick up various parts of their type signatures
-    // directly from the storage declaration instead of re-deriving them.
-    // FIXME: should this include the generic signature?
-    if (auto accessor = dyn_cast<AccessorDecl>(FD)) {
-      auto storage = accessor->getStorage();
-
-      // Note that it's important for correctness that we're filling in
-      // empty TypeLocs, because otherwise revertGenericFuncSignature might
-      // erase the types we set, causing them to be re-validated in a later
-      // pass.  That later validation might be incorrect even if the TypeLocs
-      // are a clone of the type locs from which we derived the value type,
-      // because the rules for interpreting types in parameter contexts
-      // are sometimes different from the rules elsewhere; for example,
-      // function types default to non-escaping.
-
-      auto valueParams = accessor->getParameters();
-
-      // Determine the value type.
-      Type valueIfaceTy = storage->getValueInterfaceType();
-      if (auto SD = dyn_cast<SubscriptDecl>(storage)) {
-        // Copy the index types instead of re-validating them.
-        auto indices = SD->getIndices();
-        for (size_t i = 0, e = indices->size(); i != e; ++i) {
-          auto subscriptParam = indices->get(i);
-          if (!subscriptParam->hasInterfaceType())
-            continue;
-
-          Type paramIfaceTy = subscriptParam->getInterfaceType();
-
-          auto accessorParam = valueParams->get(valueParams->size() - e + i);
-          accessorParam->setInterfaceType(paramIfaceTy);
-          accessorParam->getTypeLoc().setType(paramIfaceTy);
-        }
-      }
-
-      // Propagate the value type into the correct position.
-      switch (accessor->getAccessorKind()) {
-      // For getters, set the result type to the value type.
-      case AccessorKind::Get:
-        accessor->getBodyResultTypeLoc().setType(valueIfaceTy);
-        break;
-
-      // For setters and observers, set the old/new value parameter's type
-      // to the value type.
-      case AccessorKind::DidSet:
-      case AccessorKind::WillSet:
-      case AccessorKind::Set: {
-        auto newValueParam = valueParams->get(0);
-        newValueParam->setInterfaceType(valueIfaceTy);
-        newValueParam->getTypeLoc().setType(valueIfaceTy);
-        accessor->getBodyResultTypeLoc().setType(TupleType::getEmpty(Context));
-        break;
-      }
-
-      // Addressor result types can get complicated because of the owner.
-      case AccessorKind::Address:
-      case AccessorKind::MutableAddress:
-        if (Type resultType =
-              buildAddressorResultType(*this, accessor, valueIfaceTy)) {
-          accessor->getBodyResultTypeLoc().setType(resultType);
-        }
-        break;
-
-      // These don't mention the value type directly.
-      // If we add yield types to the function type, we'll need to update this.
-      case AccessorKind::Read:
-      case AccessorKind::Modify:
-        accessor->getBodyResultTypeLoc().setType(TupleType::getEmpty(Context));
-        break;
-      }
-    }
-    
-    // We want the function to be available for name lookup as soon
-    // as it has a valid interface type.
-    typeCheckParameterList(FD->getParameters(), FD,
-                           TypeResolverContext::AbstractFunctionDecl);
-    validateResultType(FD, FD->getBodyResultTypeLoc());
-    // FIXME: Roll all of this interface type computation into a request.
-    FD->computeType();
-
-    // SWIFT_ENABLE_TENSORFLOW
-    // TODO(TF-789): Find proper way to type-check `@differentiable` attributes.
-    checkDeclDifferentiableAttributes(FD);
-    // SWIFT_ENABLE_TENSORFLOW END
-
-    // If the function is exported to C, it must be representable in (Obj-)C.
-    if (auto CDeclAttr = FD->getAttrs().getAttribute<swift::CDeclAttr>()) {
-      Optional<ForeignErrorConvention> errorConvention;
-      if (isRepresentableInObjC(FD, ObjCReason::ExplicitlyCDecl,
-                                errorConvention)) {
-        if (FD->hasThrows()) {
-          FD->setForeignErrorConvention(*errorConvention);
-          diagnose(CDeclAttr->getLocation(), diag::cdecl_throws);
-        }
-      }
-    }
-    
-    break;
-  }
-
-  case DeclKind::Constructor: {
-    auto *CD = cast<ConstructorDecl>(D);
-
-    DeclValidationRAII IBV(CD);
-
-    typeCheckParameterList(CD->getParameters(), CD,
-                           TypeResolverContext::AbstractFunctionDecl);
-    CD->computeType();
-    // SWIFT_ENABLE_TENSORFLOW
-    // TODO(TF-789): Find proper way to type-check `@differentiable` attributes.
-    checkDeclDifferentiableAttributes(CD);
-    // SWIFT_ENABLE_TENSORFLOW END
-    break;
-  }
-
+  case DeclKind::Accessor:
+  case DeclKind::Constructor:
   case DeclKind::Destructor: {
-    auto *DD = cast<DestructorDecl>(D);
-
-    DeclValidationRAII IBV(DD);
-
-    typeCheckParameterList(DD->getParameters(), DD,
-                           TypeResolverContext::AbstractFunctionDecl);
-    DD->computeType();
+    auto *AFD = cast<AbstractFunctionDecl>(D);
+    DeclValidationRAII IBV(AFD);
+    AFD->computeType();
+    // SWIFT_ENABLE_TENSORFLOW
+    // TODO(TF-789): Find proper way to type-check `@differentiable` attributes.
+    checkDeclDifferentiableAttributes(AFD);
+    // SWIFT_ENABLE_TENSORFLOW END
     break;
   }
 
   case DeclKind::Subscript: {
     auto *SD = cast<SubscriptDecl>(D);
-
     DeclValidationRAII IBV(SD);
 
-    typeCheckParameterList(SD->getIndices(), SD,
-                           TypeResolverContext::SubscriptDecl);
-    validateResultType(SD, SD->getElementTypeLoc());
-    SD->computeType();
+    auto elementTy = SD->getElementInterfaceType();
 
+    SmallVector<AnyFunctionType::Param, 2> argTy;
+    SD->getIndices()->getParams(argTy);
+
+    Type funcTy;
+    if (auto sig = SD->getGenericSignature())
+      funcTy = GenericFunctionType::get(sig, argTy, elementTy);
+    else
+      funcTy = FunctionType::get(argTy, elementTy);
+
+    // Record the interface type.
+    SD->setInterfaceType(funcTy);
     // SWIFT_ENABLE_TENSORFLOW
     // TODO(TF-789): Find proper way to type-check `@differentiable` attributes.
     checkDeclDifferentiableAttributes(SD);
@@ -4198,16 +4318,30 @@
 
   case DeclKind::EnumElement: {
     auto *EED = cast<EnumElementDecl>(D);
-    EnumDecl *ED = EED->getParentEnum();
-
     DeclValidationRAII IBV(EED);
 
+    auto *ED = EED->getParentEnum();
+
+    // The type of the enum element is either (Self.Type) -> Self
+    // or (Self.Type) -> (Args...) -> Self.
+    auto resultTy = ED->getDeclaredInterfaceType();
+
+    AnyFunctionType::Param selfTy(MetatypeType::get(resultTy, Context));
+
     if (auto *PL = EED->getParameterList()) {
-      typeCheckParameterList(PL, ED,
-                             TypeResolverContext::EnumElementDecl);
+      SmallVector<AnyFunctionType::Param, 4> argTy;
+      PL->getParams(argTy);
+
+      resultTy = FunctionType::get(argTy, resultTy);
     }
 
-    EED->computeType();
+    if (auto genericSig = ED->getGenericSignature())
+      resultTy = GenericFunctionType::get(genericSig, {selfTy}, resultTy);
+    else
+      resultTy = FunctionType::get({selfTy}, resultTy);
+
+    // Record the interface type.
+    EED->setInterfaceType(resultTy);
     break;
   }
   }
diff --git a/lib/Sema/TypeCheckDecl.h b/lib/Sema/TypeCheckDecl.h
index d6eaeaf..f546f78 100644
--- a/lib/Sema/TypeCheckDecl.h
+++ b/lib/Sema/TypeCheckDecl.h
@@ -25,6 +25,8 @@
 class ValueDecl;
 class Pattern;
 
+bool doesContextHaveValueSemantics(DeclContext *dc);
+
 /// Walks up the override chain for \p CD until it finds an initializer that is
 /// required and non-implicit. If no such initializer exists, returns the
 /// declaration where \c required was introduced (i.e. closest to the root
diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp
index 909e6f8..3ed5a84 100644
--- a/lib/Sema/TypeCheckDeclObjC.cpp
+++ b/lib/Sema/TypeCheckDeclObjC.cpp
@@ -228,7 +228,7 @@
   if (P->hasType()) {
     Type ParamTy = P->getType();
     SourceRange SR;
-    if (auto typeRepr = P->getTypeLoc().getTypeRepr())
+    if (auto typeRepr = P->getTypeRepr())
       SR = typeRepr->getSourceRange();
     diagnoseTypeNotRepresentableInObjC(AFD, ParamTy, SR);
   }
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index a801702..9235d24 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -284,8 +284,8 @@
     if (!paramTy || !parentParamTy)
       return;
 
-    TypeLoc TL = decl->getTypeLoc();
-    if (!TL.getTypeRepr())
+    auto *repr = decl->getTypeRepr();
+    if (!repr)
       return;
 
     bool paramIsOptional =  (bool) paramTy->getOptionalObjectType();
@@ -305,11 +305,11 @@
                                  member->getDescriptiveKind(),
                                  isa<SubscriptDecl>(member),
                                  parentParamTy, paramTy);
-      if (TL.getTypeRepr()->isSimple()) {
-        diag.fixItInsertAfter(TL.getSourceRange().End, "?");
+      if (repr->isSimple()) {
+        diag.fixItInsertAfter(repr->getEndLoc(), "?");
       } else {
-        diag.fixItInsert(TL.getSourceRange().Start, "(");
-        diag.fixItInsertAfter(TL.getSourceRange().End, ")?");
+        diag.fixItInsert(repr->getStartLoc(), "(");
+        diag.fixItInsertAfter(repr->getEndLoc(), ")?");
       }
       return;
     }
@@ -318,25 +318,24 @@
       return;
 
     // Allow silencing this warning using parens.
-    if (TL.getType()->hasParenSugar())
+    if (paramTy->hasParenSugar())
       return;
 
-    diags.diagnose(decl->getStartLoc(), diag::override_unnecessary_IUO,
-                   member->getDescriptiveKind(), parentParamTy, paramTy)
-      .highlight(TL.getSourceRange());
+    diags
+        .diagnose(decl->getStartLoc(), diag::override_unnecessary_IUO,
+                  member->getDescriptiveKind(), parentParamTy, paramTy)
+        .highlight(repr->getSourceRange());
 
-    auto sugaredForm =
-      dyn_cast<ImplicitlyUnwrappedOptionalTypeRepr>(TL.getTypeRepr());
-    if (sugaredForm) {
-      diags.diagnose(sugaredForm->getExclamationLoc(),
-                     diag::override_unnecessary_IUO_remove)
-        .fixItRemove(sugaredForm->getExclamationLoc());
+    if (auto iuoRepr = dyn_cast<ImplicitlyUnwrappedOptionalTypeRepr>(repr)) {
+      diags
+          .diagnose(iuoRepr->getExclamationLoc(),
+                    diag::override_unnecessary_IUO_remove)
+          .fixItRemove(iuoRepr->getExclamationLoc());
     }
 
-    diags.diagnose(TL.getSourceRange().Start,
-                   diag::override_unnecessary_IUO_silence)
-      .fixItInsert(TL.getSourceRange().Start, "(")
-      .fixItInsertAfter(TL.getSourceRange().End, ")");
+    diags.diagnose(repr->getStartLoc(), diag::override_unnecessary_IUO_silence)
+        .fixItInsert(repr->getStartLoc(), "(")
+        .fixItInsertAfter(repr->getEndLoc(), ")");
   };
 
   // FIXME: If we ever allow argument reordering, this is incorrect.
diff --git a/lib/Sema/TypeCheckError.cpp b/lib/Sema/TypeCheckError.cpp
index 86c2079..1eed9a5 100644
--- a/lib/Sema/TypeCheckError.cpp
+++ b/lib/Sema/TypeCheckError.cpp
@@ -461,7 +461,7 @@
 
       // Use the most significant result from the arguments.
       Classification result;
-      for (auto arg : reversed(args)) {
+      for (auto arg : llvm::reverse(args)) {
         auto fnType = type->getAs<AnyFunctionType>();
         if (!fnType) return Classification::forInvalidCode();
 
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 112fee6..cfd442c 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -642,7 +642,7 @@
 
       auto params = func ? func->getParameters() : subscr->getIndices();
       for (auto param : *params) {
-        auto *typeRepr = param->getTypeLoc().getTypeRepr();
+        auto *typeRepr = param->getTypeRepr();
         if (typeRepr == nullptr)
           continue;
 
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 9dd54f1..3b6b159 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -744,124 +744,6 @@
   return hadError;
 }
 
-static bool validateParameterType(ParamDecl *decl, TypeResolution resolution,
-                                  TypeResolutionOptions options,
-                                  TypeChecker &TC) {
-  if (auto ty = decl->getTypeLoc().getType())
-    return ty->hasError();
-
-  auto origContext = options.getContext();
-  options.setContext(None);
-
-  // If the element is a variadic parameter, resolve the parameter type as if
-  // it were in non-parameter position, since we want functions to be
-  // @escaping in this case.
-  options.setContext(decl->isVariadic() ?
-                       TypeResolverContext::VariadicFunctionInput :
-                       TypeResolverContext::FunctionInput);
-  options |= TypeResolutionFlags::Direct;
-
-  bool hadError = false;
-
-  auto &TL = decl->getTypeLoc();
-
-  // We might have a null typeLoc if this is a closure parameter list,
-  // where parameters are allowed to elide their types.
-  if (!TL.isNull()) {
-    hadError |= TypeChecker::validateType(TC.Context, TL, resolution, options);
-  }
-
-  Type Ty = TL.getType();
-  if (decl->isVariadic() && !Ty.isNull() && !hadError) {
-    Ty = TC.getArraySliceType(decl->getStartLoc(), Ty);
-    if (Ty.isNull()) {
-      hadError = true;
-    }
-    TL.setType(Ty);
-
-    // Disallow variadic parameters in enum elements.
-    if (!hadError && origContext == TypeResolverContext::EnumElementDecl) {
-      TC.diagnose(decl->getStartLoc(), diag::enum_element_ellipsis);
-      hadError = true;
-    }
-  }
-
-  if (hadError)
-    TL.setInvalidType(TC.Context);
-
-  return hadError;
-}
-
-/// Type check a parameter list.
-bool TypeChecker::typeCheckParameterList(ParameterList *PL,
-                                         DeclContext *dc,
-                                         TypeResolutionOptions options) {
-  auto resolution = TypeResolution::forInterface(dc);
-
-  bool hadError = false;
-  
-  for (auto param : *PL) {
-    auto typeRepr = param->getTypeLoc().getTypeRepr();
-    if (!typeRepr &&
-        param->hasInterfaceType()) {
-      hadError |= param->isInvalid();
-      continue;
-    }
-
-    hadError |= validateParameterType(param, resolution, options, *this);
-    
-    auto type = param->getTypeLoc().getType();
-
-    // If there was no type specified, and if we're not looking at a
-    // ClosureExpr, then we have a parse error (no type was specified).  The
-    // parser will have already diagnosed this, but treat this as a type error
-    // as well to get the ParamDecl marked invalid and to get an ErrorType.
-    if (!type) {
-      // Closure argument lists are allowed to be missing types.
-      if (options.isAnyExpr())
-        continue;
-      param->setInvalid();
-    }
-    
-    if (param->isInvalid() || type->hasError()) {
-      param->markInvalid();
-      hadError = true;
-    } else {
-      param->setInterfaceType(type);
-    }
-
-    if (!hadError) {
-      auto *nestedRepr = typeRepr;
-
-      // Look through parens here; other than parens, specifiers
-      // must appear at the top level of a parameter type.
-      while (auto *tupleRepr = dyn_cast<TupleTypeRepr>(nestedRepr)) {
-        if (!tupleRepr->isParenType())
-          break;
-        nestedRepr = tupleRepr->getElementType(0);
-      }
-
-      if (isa<InOutTypeRepr>(nestedRepr)) {
-        param->setSpecifier(ParamDecl::Specifier::InOut);
-      } else if (isa<SharedTypeRepr>(nestedRepr)) {
-        param->setSpecifier(ParamDecl::Specifier::Shared);
-      } else if (isa<OwnedTypeRepr>(nestedRepr)) {
-        param->setSpecifier(ParamDecl::Specifier::Owned);
-      }
-    }
-
-    if (param->isInOut() && param->isDefaultArgument()) {
-      diagnose(param->getDefaultValue()->getLoc(),
-               swift::diag::cannot_provide_default_value_inout,
-               param->getName());
-      param->markInvalid();
-      hadError = true;
-    }
-  }
-  
-  return hadError;
-}
-
 bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
                                    TypeResolutionOptions options) {
   switch (P->getKind()) {
@@ -1133,9 +1015,7 @@
     P->setType(type);
     var->setInterfaceType(interfaceType);
     var->setType(var->getDeclContext()->mapTypeIntoContext(interfaceType));
-
-    var->getTypeLoc() = tyLoc;
-    var->getTypeLoc().setType(var->getType());
+    var->setTypeRepr(tyLoc.getTypeRepr());
 
     // FIXME: Should probably just remove the forbidden prefix stuff, it no
     // longer makes a lot of sense in a request-based world.
@@ -1646,7 +1526,7 @@
     if (param->isInvalid())
       return true;
 
-    if (auto type = param->getTypeLoc().getType())
+    if (auto type = param->getType())
       return !isValidType(type);
 
     return true;
diff --git a/lib/Sema/TypeCheckPropertyWrapper.cpp b/lib/Sema/TypeCheckPropertyWrapper.cpp
index 19d94e5..f59e9c5 100644
--- a/lib/Sema/TypeCheckPropertyWrapper.cpp
+++ b/lib/Sema/TypeCheckPropertyWrapper.cpp
@@ -26,6 +26,16 @@
 #include "swift/AST/TypeCheckRequests.h"
 using namespace swift;
 
+/// The kind of property initializer to look for
+enum class PropertyWrapperInitKind {
+  /// An initial-value initializer (i.e. `init(initialValue:)`)
+  InitialValue,
+  /// An wrapped-value initializer (i.e. `init(wrappedValue:)`)
+  WrappedValue,
+  /// An default-value initializer (i.e. `init()` or `init(defaultArgs...)`)
+  Default
+};
+
 /// Find the named property in a property wrapper to which access will
 /// be delegated.
 static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal,
@@ -79,52 +89,63 @@
   return var;
 }
 
-/// Determine whether we have a suitable wrapped-value initializer within
-/// a property wrapper type.
-static ConstructorDecl *findInitialValueInit(
-    ASTContext &ctx,
-    NominalTypeDecl *nominal,
-    VarDecl *valueVar,
-    Identifier argumentLabel) {
-  // Retrieve the type of the 'value' property.
-  Type valueVarType = valueVar->getValueInterfaceType();
-
+/// Determine whether we have a suitable initializer within a property wrapper
+/// type.
+static ConstructorDecl *
+findSuitableWrapperInit(ASTContext &ctx, NominalTypeDecl *nominal,
+                        VarDecl *valueVar, PropertyWrapperInitKind initKind) {
   enum class NonViableReason {
     Failable,
     ParameterTypeMismatch,
     Inaccessible,
   };
-  SmallVector<std::tuple<ConstructorDecl*, NonViableReason, Type>, 2> nonviable;
-  SmallVector<ConstructorDecl *, 2> initialValueInitializers;
 
+  SmallVector<std::tuple<ConstructorDecl *, NonViableReason, Type>, 2>
+      nonviable;
+  SmallVector<ConstructorDecl *, 2> viableInitializers;
   SmallVector<ValueDecl *, 2> decls;
+
+  Identifier argumentLabel;
+  switch (initKind) {
+  case PropertyWrapperInitKind::InitialValue:
+    argumentLabel = ctx.Id_initialValue;
+    break;
+  case PropertyWrapperInitKind::WrappedValue:
+    argumentLabel = ctx.Id_wrappedValue;
+    break;
+  case PropertyWrapperInitKind::Default:
+    break;
+  }
+
   nominal->lookupQualified(nominal, DeclBaseName::createConstructor(),
                            NL_QualifiedDefault, decls);
   for (const auto &decl : decls) {
     auto init = dyn_cast<ConstructorDecl>(decl);
-    if (!init || init->getDeclContext() != nominal || init->getGenericParams())
+    if (!init || init->getDeclContext() != nominal || init->isGeneric())
       continue;
 
+    ParamDecl *argumentParam = nullptr;
+    bool hasExtraneousParam = false;
     // Check whether every parameter meets one of the following criteria:
     //   (1) The parameter has a default argument, or
     //   (2) The parameter has the given argument label.
-    ParamDecl *wrappedValueParam = nullptr;
     for (auto param : *init->getParameters()) {
       // Recognize the first parameter with the requested argument label.
-      if (param->getArgumentName() == argumentLabel && !wrappedValueParam) {
-        wrappedValueParam = param;
+      if (!argumentLabel.empty() && param->getArgumentName() == argumentLabel &&
+          !argumentParam) {
+        argumentParam = param;
         continue;
       }
 
       if (param->isDefaultArgument())
         continue;
 
-      // Forget we had a match.
-      wrappedValueParam = nullptr;
+      // Skip this init as the param doesn't meet the above criteria
+      hasExtraneousParam = true;
       break;
     }
 
-    if (!wrappedValueParam)
+    if (hasExtraneousParam)
       continue;
 
     // Failable initializers cannot be used.
@@ -141,33 +162,37 @@
       continue;
     }
 
-    if (!wrappedValueParam->hasInterfaceType())
-      continue;
+    // Additional checks for initial-value and wrapped-value initializers
+    if (initKind != PropertyWrapperInitKind::Default) {
+      if (!argumentParam)
+        continue;
 
-    if (wrappedValueParam->isInOut() || wrappedValueParam->isVariadic())
-      continue;
+      if (!argumentParam->hasInterfaceType())
+        continue;
 
-    auto paramType = wrappedValueParam->getInterfaceType();
-    if (wrappedValueParam->isAutoClosure()) {
-      if (auto *fnType = paramType->getAs<FunctionType>())
-        paramType = fnType->getResult();
+      if (argumentParam->isInOut() || argumentParam->isVariadic())
+        continue;
+
+      auto paramType = argumentParam->getInterfaceType();
+      if (argumentParam->isAutoClosure()) {
+        if (auto *fnType = paramType->getAs<FunctionType>())
+          paramType = fnType->getResult();
+      }
+
+      // The parameter type must be the same as the type of `valueVar` or an
+      // autoclosure thereof.
+      if (!paramType->isEqual(valueVar->getValueInterfaceType())) {
+        nonviable.push_back(std::make_tuple(
+            init, NonViableReason::ParameterTypeMismatch, paramType));
+        continue;
+      }
     }
 
-    // The parameter type must be the same as the type of `valueVar` or an
-    // autoclosure thereof.
-    if (!paramType->isEqual(valueVarType)) {
-      nonviable.push_back(
-          std::make_tuple(init, NonViableReason::ParameterTypeMismatch,
-                          paramType));
-      continue;
-    }
-
-    // Check the type
-    initialValueInitializers.push_back(init);
+    viableInitializers.push_back(init);
   }
 
   // If we found some nonviable candidates but no viable ones, complain.
-  if (initialValueInitializers.empty() && !nonviable.empty()) {
+  if (viableInitializers.empty() && !nonviable.empty()) {
     for (const auto &candidate : nonviable) {
       auto init = std::get<0>(candidate);
       auto reason = std::get<1>(candidate);
@@ -187,69 +212,15 @@
 
       case NonViableReason::ParameterTypeMismatch:
         init->diagnose(diag::property_wrapper_wrong_initial_value_init,
-                       init->getFullName(), paramType, valueVarType);
+                       init->getFullName(), paramType,
+                       valueVar->getValueInterfaceType());
         valueVar->diagnose(diag::decl_declared_here, valueVar->getFullName());
         break;
       }
     }
   }
 
-  return initialValueInitializers.empty() ? nullptr
-                                          : initialValueInitializers.front();
-}
-
-/// Determine whether we have a suitable init() within a property
-/// wrapper type.
-static ConstructorDecl *findDefaultInit(ASTContext &ctx,
-                                        NominalTypeDecl *nominal) {
-  SmallVector<ConstructorDecl *, 2> defaultValueInitializers;
-  DeclName initName(ctx, DeclBaseName::createConstructor(),
-                    ArrayRef<Identifier>());
-  SmallVector<ValueDecl *, 2> decls;
-  nominal->lookupQualified(nominal, initName, NL_QualifiedDefault, decls);
-  for (const auto &decl : decls) {
-    auto init = dyn_cast<ConstructorDecl>(decl);
-    if (!init || init->getDeclContext() != nominal)
-      continue;
-
-    defaultValueInitializers.push_back(init);
-  }
-
-  switch (defaultValueInitializers.size()) {
-  case 0:
-    return nullptr;
-
-  case 1:
-    break;
-
-  default:
-    // Diagnose ambiguous init() initializers.
-    nominal->diagnose(diag::property_wrapper_ambiguous_default_value_init,
-                      nominal->getDeclaredType());
-    for (auto init : defaultValueInitializers) {
-      init->diagnose(diag::kind_declname_declared_here,
-                     init->getDescriptiveKind(), init->getFullName());
-    }
-    return nullptr;
-  }
-
-  // 'init()' must be as accessible as the nominal type.
-  auto init = defaultValueInitializers.front();
-  if (init->getFormalAccess() < nominal->getFormalAccess()) {
-    init->diagnose(diag::property_wrapper_type_requirement_not_accessible,
-                     init->getFormalAccess(), init->getDescriptiveKind(),
-                     init->getFullName(), nominal->getDeclaredType(),
-                     nominal->getFormalAccess());
-    return nullptr;
-  }
-
-  // The initializer must not be failable.
-  if (init->isFailable()) {
-    init->diagnose(diag::property_wrapper_failable_init, initName);
-    return nullptr;
-  }
-
-  return init;
+  return viableInitializers.empty() ? nullptr : viableInitializers.front();
 }
 
 /// Determine whether we have a suitable static subscript to which we
@@ -335,10 +306,11 @@
   
   PropertyWrapperTypeInfo result;
   result.valueVar = valueVar;
-  if (findInitialValueInit(ctx, nominal, valueVar, ctx.Id_wrappedValue))
+  if (findSuitableWrapperInit(ctx, nominal, valueVar,
+                              PropertyWrapperInitKind::WrappedValue))
     result.wrappedValueInit = PropertyWrapperTypeInfo::HasWrappedValueInit;
-  else if (auto init = findInitialValueInit(
-               ctx, nominal, valueVar, ctx.Id_initialValue)) {
+  else if (auto init = findSuitableWrapperInit(
+               ctx, nominal, valueVar, PropertyWrapperInitKind::InitialValue)) {
     result.wrappedValueInit = PropertyWrapperTypeInfo::HasInitialValueInit;
 
     if (init->getLoc().isValid()) {
@@ -355,7 +327,11 @@
     }
   }
 
-  result.defaultInit = findDefaultInit(ctx, nominal);
+  if (findSuitableWrapperInit(ctx, nominal, /*valueVar=*/nullptr,
+                              PropertyWrapperInitKind::Default)) {
+    result.defaultInit = PropertyWrapperTypeInfo::HasDefaultValueInit;
+  }
+
   result.projectedValueVar =
     findValueProperty(ctx, nominal, ctx.Id_projectedValue,
                       /*allowMissing=*/true);
@@ -664,7 +640,7 @@
   ASTContext &ctx = var->getASTContext();
   auto wrapperAttrs = var->getAttachedPropertyWrappers();
   Expr *initializer = value;
-  for (unsigned i : reversed(indices(wrapperAttrs))) {
+  for (unsigned i : llvm::reverse(indices(wrapperAttrs))) {
     Type wrapperType =
       backingStorageType ? computeWrappedValueType(var, backingStorageType, i)
                          : var->getAttachedPropertyWrapperType(i);
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index eb85f07..bfc99aa 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1946,8 +1946,7 @@
     return SourceLoc();
   }
 
-  return getOptionalityLoc(params->get(getParameterIndex())->getTypeLoc()
-                           .getTypeRepr());
+  return getOptionalityLoc(params->get(getParameterIndex())->getTypeRepr());
 }
 
 SourceLoc OptionalAdjustment::getOptionalityLoc(TypeRepr *tyR) const {
@@ -2551,9 +2550,7 @@
                                                     SourceLoc(),
                                                     /*genericparams*/nullptr, 
                                                     DC);
-    aliasDecl->setGenericSignature(DC->getGenericSignatureOfContext());
     aliasDecl->setUnderlyingType(type);
-    aliasDecl->computeType();
     
     aliasDecl->setImplicit();
     if (type->hasError())
diff --git a/lib/Sema/TypeCheckREPL.cpp b/lib/Sema/TypeCheckREPL.cpp
index 5760db0..f0c53aa 100644
--- a/lib/Sema/TypeCheckREPL.cpp
+++ b/lib/Sema/TypeCheckREPL.cpp
@@ -231,10 +231,11 @@
 
   // Build function of type T->() which prints the operand.
   auto *Arg = new (Context) ParamDecl(
-      ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(), Identifier(), Loc,
+      SourceLoc(), SourceLoc(), Identifier(), Loc,
       Context.getIdentifier("arg"), /*DC*/ newTopLevel);
   Arg->setType(E->getType());
   Arg->setInterfaceType(E->getType());
+  Arg->setSpecifier(ParamSpecifier::Default);
   auto params = ParameterList::createWithoutLoc(Arg);
 
   unsigned discriminator = TLC.claimNextClosureDiscriminator();
diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp
index 11668e7..c874465 100644
--- a/lib/Sema/TypeCheckStorage.cpp
+++ b/lib/Sema/TypeCheckStorage.cpp
@@ -269,9 +269,8 @@
 llvm::Expected<bool>
 IsGetterMutatingRequest::evaluate(Evaluator &evaluator,
                                   AbstractStorageDecl *storage) const {
-  auto storageDC = storage->getDeclContext();
-  bool result = (!storage->isStatic() && storageDC->isTypeContext() &&
-                 storageDC->hasValueSemantics());
+  bool result = (!storage->isStatic() &&
+                 doesContextHaveValueSemantics(storage->getDeclContext()));
 
   // 'lazy' overrides the normal accessor-based rules and heavily
   // restricts what accessors can be used.  The getter is considered
@@ -299,7 +298,7 @@
 
   // Protocol requirements are always written as '{ get }' or '{ get set }';
   // the @_borrowed attribute determines if getReadImpl() becomes Get or Read.
-  if (isa<ProtocolDecl>(storageDC))
+  if (isa<ProtocolDecl>(storage->getDeclContext()))
     return checkMutability(AccessorKind::Get);
 
   switch (storage->getReadImpl()) {
@@ -325,9 +324,8 @@
                                   AbstractStorageDecl *storage) const {
   // By default, the setter is mutating if we have an instance member of a
   // value type, but this can be overridden below.
-  auto storageDC = storage->getDeclContext();
-  bool result = (!storage->isStatic() && storageDC->isTypeContext() &&
-                 storageDC->hasValueSemantics());
+  bool result = (!storage->isStatic() &&
+                 doesContextHaveValueSemantics(storage->getDeclContext()));
 
   // If we have an attached property wrapper, the setter is mutating
   // or not based on the composition of the wrappers.
@@ -432,8 +430,7 @@
 
   // Clone the parameter list over for a new decl, so we get new ParamDecls.
   auto indices = subscript->getIndices()->clone(context,
-                                                ParameterList::Implicit|
-                                                ParameterList::WithoutTypes);
+                                                ParameterList::Implicit);
 
   // Give all of the parameters meaningless names so that we can forward
   // them properly.  If it's declared anonymously, SILGen will think
@@ -586,8 +583,6 @@
                                    TargetImpl target,
                                    bool isLValue,
                                    ASTContext &ctx) {
-  (void)accessor->getInterfaceType();
-  
   // Local function to "finish" the expression, creating a member reference
   // to the given sequence of underlying variables.
   Optional<EnclosingSelfPropertyWrapperAccess> enclosingSelfAccess;
@@ -1678,9 +1673,6 @@
   else
     getter->setSelfAccessKind(SelfAccessKind::NonMutating);
 
-  if (storage->isStatic())
-    getter->setStatic();
-
   if (!storage->requiresOpaqueAccessor(AccessorKind::Get))
     getter->setForcedStaticDispatch(true);
 
@@ -1696,17 +1688,16 @@
 
   SourceLoc loc = storage->getLoc();
 
-  bool isStatic = storage->isStatic();
   bool isMutating = storage->isSetterMutating();
 
   GenericParamList *genericParams = createAccessorGenericParams(storage);
 
   // Add a "(value : T, indices...)" argument list.
-  auto *param = new (ctx) ParamDecl(ParamDecl::Specifier::Default,
-                                    SourceLoc(), SourceLoc(),
+  auto *param = new (ctx) ParamDecl(SourceLoc(), SourceLoc(),
                                     Identifier(), loc,
                                     ctx.getIdentifier("value"),
                                     storage->getDeclContext());
+  param->setSpecifier(ParamSpecifier::Default);
   param->setImplicit();
 
   auto *params = buildIndexForwardingParamList(storage, param, ctx);
@@ -1725,9 +1716,6 @@
   else
     setter->setSelfAccessKind(SelfAccessKind::NonMutating);
 
-  if (isStatic)
-    setter->setStatic();
-
   // All mutable storage requires a setter.
   assert(storage->requiresOpaqueAccessor(AccessorKind::Set));
 
@@ -1744,7 +1732,6 @@
 
   SourceLoc loc = storage->getLoc();
 
-  bool isStatic = storage->isStatic();
   bool isMutating = storage->isGetterMutating();
   if (kind == AccessorKind::Modify)
     isMutating |= storage->isSetterMutating();
@@ -1771,9 +1758,6 @@
   else
     accessor->setSelfAccessKind(SelfAccessKind::NonMutating);
 
-  if (isStatic)
-    accessor->setStatic();
-
   // If the storage does not provide this accessor as an opaque accessor,
   // we can't add a dynamically-dispatched method entry for the accessor,
   // so force it to be statically dispatched. ("final" would be inappropriate
@@ -2436,12 +2420,16 @@
 static void finishProtocolStorageImplInfo(AbstractStorageDecl *storage,
                                           StorageImplInfo &info) {
   if (auto *var = dyn_cast<VarDecl>(storage)) {
+    SourceLoc typeLoc;
+    if (auto *repr = var->getTypeRepr())
+      typeLoc = repr->getLoc();
+    
     if (info.hasStorage()) {
       // Protocols cannot have stored properties.
       if (var->isLet()) {
         var->diagnose(diag::protocol_property_must_be_computed_var)
-          .fixItReplace(var->getParentPatternBinding()->getLoc(), "var")
-          .fixItInsertAfter(var->getTypeLoc().getLoc(), " { get }");
+            .fixItReplace(var->getParentPatternBinding()->getLoc(), "var")
+            .fixItInsertAfter(typeLoc, " { get }");
       } else {
         auto diag = var->diagnose(diag::protocol_property_must_be_computed);
         auto braces = var->getBracesRange();
@@ -2449,7 +2437,7 @@
         if (braces.isValid())
           diag.fixItReplace(braces, "{ get <#set#> }");
         else
-          diag.fixItInsertAfter(var->getTypeLoc().getLoc(), " { get <#set#> }");
+          diag.fixItInsertAfter(typeLoc, " { get <#set#> }");
       }
     }
   }
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index ea37b24..cc4cec0 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -730,6 +730,12 @@
   if (!result)
     return result;
 
+  if (!options.contains(TypeResolutionFlags::AllowUnavailable)) {
+    if (options.isAnyExpr() || dc->getParent()->isLocalContext())
+      if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal)
+        diagnoseGenericTypeExportability(loc, result, dc);
+  }
+
   // Migration hack.
   bool isMutablePointer;
   if (isPointerToVoid(dc->getASTContext(), result, isMutablePointer)) {
@@ -1657,10 +1663,9 @@
 /// has `@autoclosure` attribute, and if so, validate that such use is correct.
 /// \returns true if there was an error, false otherwise.
 static bool validateAutoClosureAttributeUse(DiagnosticEngine &Diags,
-                                            const TypeLoc &loc,
+                                            const TypeRepr *TR,
                                             Type type,
                                             TypeResolutionOptions options) {
-  auto *TR = loc.getTypeRepr();
   if (!TR || TR->isInvalid())
     return false;
 
@@ -1683,7 +1688,7 @@
       isValid &= llvm::none_of(
           fnType->getParams(), [&](const FunctionType::Param &param) {
             return param.isAutoClosure() &&
-                   validateAutoClosureAttr(Diags, loc.getLoc(),
+                   validateAutoClosureAttr(Diags, TR->getLoc(),
                                            param.getPlainType());
           });
     }
@@ -1702,30 +1707,8 @@
   if (Context.Stats)
     Context.Stats->getFrontendCounters().NumTypesValidated++;
 
-  Type type = Loc.getType();
-  if (type.isNull()) {
-    type = resolution.resolveType(Loc.getTypeRepr(), options);
-    if (!type) {
-      type = ErrorType::get(Context);
-      // Diagnose types that are illegal in SIL.
-    } else if (options.contains(TypeResolutionFlags::SILType)
-               && !type->isLegalSILType()) {
-      Context.Diags.diagnose(Loc.getLoc(), diag::illegal_sil_type, type);
-      Loc.setInvalidType(Context);
-      return true;
-    } else if (validateAutoClosureAttributeUse(Context.Diags, Loc,
-                                               type, options)) {
-      type = ErrorType::get(Context);
-    }
-  }
-
+  Type type = resolution.resolveType(Loc.getTypeRepr(), options);
   Loc.setType(type);
-  if (!type->hasError()) {
-    const DeclContext *DC = resolution.getDeclContext();
-    if (options.isAnyExpr() || DC->getParent()->isLocalContext())
-      if (DC->getResilienceExpansion() == ResilienceExpansion::Minimal)
-        TypeChecker::diagnoseGenericTypeExportability(Loc, DC);
-  }
 
   return type->hasError();
 }
@@ -1833,16 +1816,34 @@
 
 Type TypeResolution::resolveType(TypeRepr *TyR,
                               TypeResolutionOptions options) {
-  FrontendStatsTracer StatsTracer(getASTContext().Stats, "resolve-type", TyR);
-  PrettyStackTraceTypeRepr stackTrace(getASTContext(), "resolving", TyR);
+  auto &ctx = getASTContext();
+
+  FrontendStatsTracer StatsTracer(ctx.Stats, "resolve-type", TyR);
+  PrettyStackTraceTypeRepr stackTrace(ctx, "resolving", TyR);
 
   TypeResolver typeResolver(*this);
   auto result = typeResolver.resolveType(TyR, options);
-  
-  // If we resolved down to an error, make sure to mark the typeRepr as invalid
-  // so we don't produce a redundant diagnostic.
-  if (result && result->hasError())
-    TyR->setInvalid();
+
+  if (result) {
+    // If we resolved down to an error, make sure to mark the typeRepr as invalid
+    // so we don't produce a redundant diagnostic.
+    if (result->hasError()) {
+      TyR->setInvalid();
+      return result;
+    }
+
+    auto loc = TyR->getLoc();
+
+    if (options.contains(TypeResolutionFlags::SILType)
+        && !result->isLegalSILType()) {
+      ctx.Diags.diagnose(loc, diag::illegal_sil_type, result);
+      return ErrorType::get(ctx);
+    }
+
+    if (validateAutoClosureAttributeUse(ctx.Diags, TyR, result, options))
+      return ErrorType::get(ctx);
+  }
+
   return result;
 }
 
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index 20d4481..fc883e6 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -330,7 +330,7 @@
   }
   TC.ClosuresWithUncomputedCaptures.clear();
 
-  for (AbstractFunctionDecl *FD : reversed(TC.definedFunctions)) {
+  for (AbstractFunctionDecl *FD : llvm::reverse(TC.definedFunctions)) {
     TypeChecker::computeCaptures(FD);
   }
 
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 742d78b..61855ed 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1427,10 +1427,6 @@
 
   bool typeCheckCatchPattern(CatchStmt *S, DeclContext *dc);
 
-  /// Type check a parameter list.
-  bool typeCheckParameterList(ParameterList *PL, DeclContext *dc,
-                              TypeResolutionOptions options);
-
   /// Coerce a pattern to the given type.
   ///
   /// \param P The pattern, which may be modified by this coercion.
@@ -1834,6 +1830,7 @@
                                            const DeclContext *DC,
                                            FragileFunctionKind fragileKind);
 
+public:
   /// Given that a type is used from a particular context which
   /// exposes it in the interface of the current module, diagnose if its
   /// generic arguments require the use of conformances that cannot reasonably
@@ -1841,10 +1838,9 @@
   ///
   /// This method \e only checks how generic arguments are used; it is assumed
   /// that the declarations involved have already been checked elsewhere.
-  static void diagnoseGenericTypeExportability(const TypeLoc &TL,
+  static void diagnoseGenericTypeExportability(SourceLoc loc, Type type,
                                                const DeclContext *DC);
 
-public:
   /// Given that \p DC is within a fragile context for some reason, describe
   /// why.
   ///
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index fd36e06..d8e79bb 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -1874,6 +1874,8 @@
     return AFD;
   if (auto SD = dyn_cast<SubscriptDecl>(D))
     return SD;
+  if (auto EED = dyn_cast<EnumElementDecl>(D))
+    return EED;
 
   llvm_unreachable("Unknown Decl : DeclContext kind");
 }
@@ -2293,7 +2295,6 @@
 
     auto underlying = MF.getType(underlyingTypeID);
     alias->setUnderlyingType(underlying);
-    alias->computeType();
     
     if (auto accessLevel = getActualAccessLevel(rawAccessLevel))
       alias->setAccess(*accessLevel);
@@ -2361,8 +2362,6 @@
         &MF, defaultDefinitionID);
     declOrOffset = assocType;
 
-    assocType->computeType();
-
     assert(!assocType->getDeclaredInterfaceType()->hasError() &&
            "erroneous associated type");
 
@@ -2437,8 +2436,6 @@
       theStruct->setImplicit();
     theStruct->setIsObjC(isObjC);
 
-    theStruct->computeType();
-
     handleInherited(theStruct,
                     rawInheritedAndDependencyIDs.slice(0, numInheritedTypes));
 
@@ -2777,10 +2774,11 @@
     if (!specifier)
       MF.fatal();
 
-    auto param = MF.createDecl<ParamDecl>(*specifier, SourceLoc(), SourceLoc(),
+    auto param = MF.createDecl<ParamDecl>(SourceLoc(), SourceLoc(),
                                           MF.getIdentifier(argNameID),
                                           SourceLoc(),
                                           MF.getIdentifier(paramNameID), DC);
+    param->setSpecifier(*specifier);
 
     declOrOffset = param;
 
@@ -3219,8 +3217,6 @@
       proto->setImplicit();
     proto->setIsObjC(isObjC);
 
-    proto->computeType();
-
     proto->setCircularityCheck(CircularityCheck::Checked);
 
     proto->setLazyRequirementSignature(&MF,
@@ -3423,8 +3419,6 @@
     if (inheritsSuperclassInitializers)
       theClass->setInheritsSuperclassInitializers();
 
-    theClass->computeType();
-
     handleInherited(theClass,
                     rawInheritedAndDependencyIDs.slice(0, numInheritedTypes));
 
@@ -3499,8 +3493,6 @@
 
     theEnum->setRawType(MF.getType(rawTypeID));
 
-    theEnum->computeType();
-
     auto rawInheritedIDs = rawInheritedAndDependencyIDs.slice(0, numInherited);
     handleInherited(theEnum, rawInheritedIDs);
 
@@ -3554,24 +3546,24 @@
       }
     }
 
-    // Read payload parameter list, if it exists.
-    ParameterList *paramList = nullptr;
-    if (hasPayload) {
-      paramList = MF.readParameterList();
-    }
-
     DeclContext *DC = MF.getDeclContext(contextID);
     if (declOrOffset.isComplete())
       return declOrOffset;
 
     auto elem = MF.createDecl<EnumElementDecl>(SourceLoc(),
                                                name,
-                                               paramList,
+                                               nullptr,
                                                SourceLoc(),
                                                nullptr,
                                                DC);
     declOrOffset = elem;
 
+    // Read payload parameter list, if it exists.
+    if (hasPayload) {
+      auto *paramList = MF.readParameterList();
+      elem->setParameterList(paramList);
+    }
+
     // Deserialize the literal raw value, if any.
     switch ((EnumElementRawValueKind)rawValueKindID) {
     case EnumElementRawValueKind::None:
@@ -3586,8 +3578,6 @@
     }
     }
 
-    elem->computeType();
-
     if (isImplicit)
       elem->setImplicit();
     elem->setAccess(std::max(cast<EnumDecl>(DC)->getFormalAccess(),
@@ -3701,7 +3691,6 @@
     auto elemInterfaceType = MF.getType(elemInterfaceTypeID);
     subscript->getElementTypeLoc().setType(elemInterfaceType);
     subscript->setImplicitlyUnwrappedOptional(isIUO);
-    subscript->computeType();
 
     if (isImplicit)
       subscript->setImplicit();
diff --git a/lib/Serialization/DeserializationErrors.h b/lib/Serialization/DeserializationErrors.h
index 8f61caf..2856b31 100644
--- a/lib/Serialization/DeserializationErrors.h
+++ b/lib/Serialization/DeserializationErrors.h
@@ -207,7 +207,7 @@
   }
 
   DeclBaseName getLastName() const {
-    for (auto &piece : reversed(path)) {
+    for (auto &piece : llvm::reverse(path)) {
       DeclBaseName result = piece.getAsBaseName();
       if (!result.empty())
         return result;
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index 115b500..f987195 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -14,6 +14,7 @@
 #include "BCReadingExtras.h"
 #include "DeserializationErrors.h"
 #include "DocFormat.h"
+#include "SourceInfoFormat.h"
 #include "ModuleFormat.h"
 #include "swift/Serialization/SerializationOptions.h"
 #include "swift/Subsystems.h"
@@ -1222,13 +1223,166 @@
   return true;
 }
 
+class ModuleFile::DeclUSRTableInfo {
+public:
+  using internal_key_type = StringRef;
+  using external_key_type = StringRef;
+  using data_type = uint32_t;
+  using hash_value_type = uint32_t;
+  using offset_type = unsigned;
+
+  internal_key_type GetInternalKey(external_key_type key) { return key; }
+
+  hash_value_type ComputeHash(internal_key_type key) {
+    assert(!key.empty());
+    return llvm::djbHash(key, SWIFTSOURCEINFO_HASH_SEED);
+  }
+
+  static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+    return lhs == rhs;
+  }
+
+  static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
+    unsigned keyLength = endian::readNext<uint32_t, little, unaligned>(data);
+    unsigned dataLength = 4;
+    return { keyLength, dataLength };
+  }
+
+  static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+    return StringRef(reinterpret_cast<const char*>(data), length);
+  }
+
+  data_type ReadData(internal_key_type key, const uint8_t *data, unsigned length) {
+    assert(length == 4);
+    return endian::readNext<uint32_t, little, unaligned>(data);
+  }
+};
+
+std::unique_ptr<ModuleFile::SerializedDeclUSRTable>
+ModuleFile::readDeclUSRsTable(ArrayRef<uint64_t> fields, StringRef blobData) {
+  if (fields.empty() || blobData.empty())
+     return nullptr;
+  uint32_t tableOffset = static_cast<uint32_t>(fields.front());
+  auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+  return std::unique_ptr<SerializedDeclUSRTable>(
+    SerializedDeclUSRTable::Create(base + tableOffset, base + sizeof(uint32_t),
+                                   base));
+}
+
+bool ModuleFile::readDeclLocsBlock(llvm::BitstreamCursor &cursor) {
+  cursor.EnterSubBlock(DECL_LOCS_BLOCK_ID);
+
+  SmallVector<uint64_t, 4> scratch;
+  StringRef blobData;
+
+  while (!cursor.AtEndOfStream()) {
+    auto entry = cursor.advance();
+    switch (entry.Kind) {
+    case llvm::BitstreamEntry::EndBlock:
+      return true;
+
+    case llvm::BitstreamEntry::Error:
+      return false;
+
+    case llvm::BitstreamEntry::SubBlock:
+      // Unknown sub-block, which this version of the compiler won't use.
+      if (cursor.SkipBlock())
+        return false;
+      break;
+
+    case llvm::BitstreamEntry::Record:
+      scratch.clear();
+      unsigned kind = cursor.readRecord(entry.ID, scratch, &blobData);
+
+      switch (kind) {
+      case decl_locs_block::BASIC_DECL_LOCS:
+        BasicDeclLocsData = blobData;
+        break;
+      case decl_locs_block::TEXT_DATA:
+        SourceLocsTextData = blobData;
+        break;
+      case decl_locs_block::DECL_USRS:
+        DeclUSRsTable = readDeclUSRsTable(scratch, blobData);
+        break;
+      default:
+        // Unknown index kind, which this version of the compiler won't use.
+        break;
+      }
+      break;
+    }
+  }
+
+  return false;
+}
+
+bool ModuleFile::readModuleSourceInfoIfPresent() {
+  if (!this->ModuleSourceInfoInputBuffer)
+    return true;
+
+  llvm::BitstreamCursor infoCursor{ModuleSourceInfoInputBuffer->getMemBufferRef()};
+  if (!checkModuleSignature(infoCursor, SWIFTSOURCEINFO_SIGNATURE) ||
+      !enterTopLevelModuleBlock(infoCursor, MODULE_SOURCEINFO_BLOCK_ID)) {
+    return false;
+  }
+
+  SmallVector<uint64_t, 64> scratch;
+  llvm::BitstreamEntry topLevelEntry;
+
+  bool hasValidControlBlock = false;
+  ValidationInfo info;
+
+  while (!infoCursor.AtEndOfStream()) {
+    topLevelEntry = infoCursor.advance(AF_DontPopBlockAtEnd);
+    if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
+      break;
+
+    switch (topLevelEntry.ID) {
+    case CONTROL_BLOCK_ID: {
+      infoCursor.EnterSubBlock(CONTROL_BLOCK_ID);
+
+      info = validateControlBlock(infoCursor, scratch,
+                                  {SWIFTSOURCEINFO_VERSION_MAJOR,
+                                   SWIFTSOURCEINFO_VERSION_MINOR},
+                                  /*extendedInfo*/nullptr);
+      if (info.status != Status::Valid)
+        return false;
+      // Check that the swiftsourceinfo is actually for this module.
+      if (info.name != Name)
+        return false;
+      hasValidControlBlock = true;
+      break;
+    }
+
+    case DECL_LOCS_BLOCK_ID: {
+      if (!hasValidControlBlock || !readDeclLocsBlock(infoCursor))
+        return false;
+      break;
+    }
+
+    default:
+      // Unknown top-level block, possibly for use by a future version of the
+      // module format.
+      if (infoCursor.SkipBlock())
+        return false;
+      break;
+    }
+  }
+
+  if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock)
+    return false;
+
+  return true;
+}
+
 ModuleFile::ModuleFile(
     std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
     std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
+    std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
     bool isFramework, serialization::ValidationInfo &info,
     serialization::ExtendedValidationInfo *extInfo)
     : ModuleInputBuffer(std::move(moduleInputBuffer)),
       ModuleDocInputBuffer(std::move(moduleDocInputBuffer)),
+      ModuleSourceInfoInputBuffer(std::move(moduleSourceInfoInputBuffer)),
       DeserializedTypeCallback([](Type ty) {}) {
   assert(!hasError());
   Bits.IsFramework = isFramework;
@@ -1465,7 +1619,8 @@
     info.status = error(Status::Malformed);
     return;
   }
-
+  // Read source info file.
+  readModuleSourceInfoIfPresent();
   if (!readModuleDocIfPresent()) {
     info.status = error(Status::MalformedDocumentation);
     return;
@@ -2202,36 +2357,68 @@
 
   if (!DeclCommentTable)
     return None;
-
-  if (D->isImplicit())
-    return None;
-
-  if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
-    // Compute the USR.
-    llvm::SmallString<128> USRBuffer;
-    {
-      llvm::raw_svector_ostream OS(USRBuffer);
-      if (ide::printExtensionUSR(ED, OS))
-        return None;
-    }
-     return getCommentForDeclByUSR(USRBuffer.str());
-  }
-
-  auto *VD = dyn_cast<ValueDecl>(D);
-  if (!VD)
-    return None;
-
   // Compute the USR.
   llvm::SmallString<128> USRBuffer;
-  {
-    llvm::raw_svector_ostream OS(USRBuffer);
-    if (ide::printDeclUSR(VD, OS))
-      return None;
-  }
+  llvm::raw_svector_ostream OS(USRBuffer);
+  if (ide::printDeclUSR(D, OS))
+    return None;
 
   return getCommentForDeclByUSR(USRBuffer.str());
 }
 
+Optional<BasicDeclLocs>
+ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
+  assert(D);
+
+  // Keep these as assertions instead of early exits to ensure that we are not
+  // doing extra work.  These cases should be handled by clients of this API.
+  assert(!D->hasClangNode() &&
+         "cannot find comments for Clang decls in Swift modules");
+  assert(D->getDeclContext()->getModuleScopeContext() == FileContext &&
+         "Decl is from a different serialized file");
+  if (!DeclUSRsTable)
+    return None;
+  // Future compilers may not provide BasicDeclLocsData anymore.
+  if (BasicDeclLocsData.empty())
+    return None;
+  // Compute the USR.
+  llvm::SmallString<128> USRBuffer;
+  llvm::raw_svector_ostream OS(USRBuffer);
+  if (ide::printDeclUSR(D, OS))
+    return None;
+
+  auto It = DeclUSRsTable->find(OS.str());
+  if (It == DeclUSRsTable->end())
+    return None;
+  auto UsrId = *It;
+  uint32_t NumSize = 4;
+  // Size of BasicDeclLocs in the buffer.
+  // FilePathOffset + LocNum * LineColumn
+  uint32_t LineColumnCount = 3;
+  uint32_t RecordSize = NumSize + NumSize * 2 * LineColumnCount;
+  uint32_t RecordOffset = RecordSize * UsrId;
+  assert(RecordOffset < BasicDeclLocsData.size());
+  assert(BasicDeclLocsData.size() % RecordSize == 0);
+  BasicDeclLocs Result;
+  auto *Record = BasicDeclLocsData.data() + RecordOffset;
+  auto ReadNext = [&Record]() {
+    return endian::readNext<uint32_t, little, unaligned>(Record);
+  };
+
+  auto FilePath = SourceLocsTextData.substr(ReadNext());
+  size_t TerminatorOffset = FilePath.find('\0');
+  assert(TerminatorOffset != StringRef::npos && "unterminated string data");
+  Result.SourceFilePath = FilePath.slice(0, TerminatorOffset);
+#define READ_FIELD(X)                                                         \
+Result.X.Line = ReadNext();                                                   \
+Result.X.Column = ReadNext();
+  READ_FIELD(Loc)
+  READ_FIELD(StartLoc)
+  READ_FIELD(EndLoc)
+#undef READ_FIELD
+  return Result;
+}
+
 const static StringRef Separator = "/";
 
 Optional<StringRef> ModuleFile::getGroupNameById(unsigned Id) const {
diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h
index 7153216..4fc5e2c 100644
--- a/lib/Serialization/ModuleFile.h
+++ b/lib/Serialization/ModuleFile.h
@@ -64,6 +64,7 @@
   /// The module file data.
   std::unique_ptr<llvm::MemoryBuffer> ModuleInputBuffer;
   std::unique_ptr<llvm::MemoryBuffer> ModuleDocInputBuffer;
+  std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoInputBuffer;
 
   /// The cursor used to lazily load things from the file.
   llvm::BitstreamCursor DeclTypeCursor;
@@ -405,6 +406,18 @@
   std::unique_ptr<GroupNameTable> GroupNamesMap;
   std::unique_ptr<SerializedDeclCommentTable> DeclCommentTable;
 
+  class DeclUSRTableInfo;
+  using SerializedDeclUSRTable =
+      llvm::OnDiskIterableChainedHashTable<DeclUSRTableInfo>;
+  std::unique_ptr<SerializedDeclUSRTable> DeclUSRsTable;
+
+  /// A blob of 0 terminated string segments referenced in \c SourceLocsTextData
+  StringRef SourceLocsTextData;
+
+  /// An array of fixed size source location data for each USR appearing in
+  /// \c DeclUSRsTable.
+  StringRef BasicDeclLocsData;
+
   struct ModuleBits {
     /// The decl ID of the main class in this module file, if it has one.
     unsigned EntryPointDeclID : 31;
@@ -444,6 +457,7 @@
   /// Constructs a new module and validates it.
   ModuleFile(std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
              std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
+             std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
              bool isFramework, serialization::ValidationInfo &info,
              serialization::ExtendedValidationInfo *extInfo);
 
@@ -540,6 +554,21 @@
   /// Returns false if there was an error.
   bool readModuleDocIfPresent();
 
+  /// Reads the source loc block, which contains USR to decl location mapping.
+  ///
+  /// Returns false if there was an error.
+  bool readDeclLocsBlock(llvm::BitstreamCursor &cursor);
+
+  /// Loads data from #ModuleSourceInfoInputBuffer.
+  ///
+  /// Returns false if there was an error.
+  bool readModuleSourceInfoIfPresent();
+
+  /// Read an on-disk decl hash table stored in
+  /// \c sourceinfo_block::DeclUSRSLayout format.
+  std::unique_ptr<SerializedDeclUSRTable>
+  readDeclUSRsTable(ArrayRef<uint64_t> fields, StringRef blobData);
+
   /// Recursively reads a pattern from \c DeclTypeCursor.
   llvm::Expected<Pattern *> readPattern(DeclContext *owningDC);
 
@@ -612,11 +641,13 @@
   static serialization::ValidationInfo
   load(std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
        std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
+       std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
        bool isFramework, std::unique_ptr<ModuleFile> &theModule,
        serialization::ExtendedValidationInfo *extInfo = nullptr) {
     serialization::ValidationInfo info;
     theModule.reset(new ModuleFile(std::move(moduleInputBuffer),
                                    std::move(moduleDocInputBuffer),
+                                   std::move(moduleSourceInfoInputBuffer),
                                    isFramework, info, extInfo));
     return info;
   }
@@ -804,7 +835,7 @@
   Optional<CommentInfo> getCommentForDecl(const Decl *D) const;
   Optional<CommentInfo> getCommentForDeclByUSR(StringRef USR) const;
   Optional<StringRef> getGroupNameByUSR(StringRef USR) const;
-
+  Optional<BasicDeclLocs> getBasicDeclLocsForDecl(const Decl *D) const;
   Identifier getDiscriminatorForPrivateValue(const ValueDecl *D);
 
   // MARK: Deserialization interface
diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h
index c749f6c..29db40c 100644
--- a/lib/Serialization/ModuleFormat.h
+++ b/lib/Serialization/ModuleFormat.h
@@ -654,6 +654,28 @@
   ///
   /// \sa comment_block
   COMMENT_BLOCK_ID,
+
+  /// The module source location container block, which contains all other
+  /// source location blocks.
+  ///
+  /// This is part of a stable format and should not be renumbered.
+  ///
+  /// Though we strive to keep the format stable, breaking the format of
+  /// .swiftsourceinfo doesn't have consequences as serious as breaking the
+  /// format of .swiftdoc because .swiftsourceinfo file is for local development
+  /// use only.
+  MODULE_SOURCEINFO_BLOCK_ID = 192,
+
+  /// The source location block, which contains decl locations.
+  ///
+  /// This is part of a stable format and should not be renumbered.
+  ///
+  /// Though we strive to keep the format stable, breaking the format of
+  /// .swiftsourceinfo doesn't have consequences as serious as breaking the format
+  /// of .swiftdoc because .swiftsourceinfo file is for local development use only.
+  ///
+  /// \sa decl_locs_block
+  DECL_LOCS_BLOCK_ID,
 };
 
 /// The record types within the control block.
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 09b76d1..083590f 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -439,7 +439,7 @@
 
 static bool shouldSerializeAsLocalContext(const DeclContext *DC) {
   return DC->isLocalContext() && !isa<AbstractFunctionDecl>(DC) &&
-        !isa<SubscriptDecl>(DC);
+        !isa<SubscriptDecl>(DC) && !isa<EnumElementDecl>(DC);
 }
 
 namespace {
@@ -2760,7 +2760,7 @@
 
     // Reverse the list, and write the parameter lists, from outermost
     // to innermost.
-    for (auto *genericParams : swift::reversed(allGenericParams))
+    for (auto *genericParams : llvm::reverse(allGenericParams))
       writeGenericParams(genericParams);
 
     writeMembers(id, extension->getMembers(), isClassExtension);
@@ -3334,17 +3334,6 @@
   }
 
   void visitAccessorDecl(const AccessorDecl *fn) {
-    // Accessor synthesis and type checking is now sufficiently lazy that
-    // we might have unvalidated accessors in a primary file.
-    //
-    // FIXME: Once accessor synthesis and getInterfaceType() itself are
-    // request-ified this goes away.
-    if (!fn->hasInterfaceType()) {
-      assert(fn->isImplicit());
-      // FIXME: Remove this one
-      (void)fn->getInterfaceType();
-    }
-
     using namespace decls_block;
     verifyAttrSerializable(fn);
 
diff --git a/lib/Serialization/SerializeDoc.cpp b/lib/Serialization/SerializeDoc.cpp
index 68acb25..8bac1ec 100644
--- a/lib/Serialization/SerializeDoc.cpp
+++ b/lib/Serialization/SerializeDoc.cpp
@@ -12,7 +12,7 @@
 
 #include "DocFormat.h"
 #include "Serialization.h"
-
+#include "SourceInfoFormat.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/DiagnosticsCommon.h"
@@ -20,7 +20,9 @@
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/SourceFile.h"
 #include "swift/AST/USRGeneration.h"
+#include "swift/Basic/Defer.h"
 #include "swift/Basic/SourceManager.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/DJB.h"
 #include "llvm/Support/EndianStream.h"
 #include "llvm/Support/OnDiskHashTable.h"
@@ -298,6 +300,51 @@
   GroupNames.emit(Scratch, BlobStream.str());
 }
 
+static bool hasDoubleUnderscore(Decl *D) {
+  // Exclude decls with double-underscored names, either in arguments or
+  // base names.
+  static StringRef Prefix = "__";
+
+  if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
+    // If it's a function with a parameter with leading double underscore,
+    // it's a private function.
+    if (AFD->getParameters()->hasInternalParameter(Prefix))
+      return true;
+  }
+
+  if (auto SubscriptD = dyn_cast<SubscriptDecl>(D)) {
+    if (SubscriptD->getIndices()->hasInternalParameter(Prefix))
+      return true;
+  }
+  if (auto *VD = dyn_cast<ValueDecl>(D)) {
+    auto Name = VD->getBaseName();
+    if (!Name.isSpecial() &&
+        Name.getIdentifier().str().startswith(Prefix)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool shouldIncludeDecl(Decl *D, bool ExcludeDoubleUnderscore) {
+  if (auto *VD = dyn_cast<ValueDecl>(D)) {
+    // Skip the decl if it's not visible to clients. The use of
+    // getEffectiveAccess is unusual here; we want to take the testability
+    // state into account and emit documentation if and only if they are
+    // visible to clients (which means public ordinarily, but
+    // public+internal when testing enabled).
+    if (VD->getEffectiveAccess() < swift::AccessLevel::Public)
+      return false;
+  }
+  if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
+    return shouldIncludeDecl(ED->getExtendedNominal(), ExcludeDoubleUnderscore);
+  }
+  if (ExcludeDoubleUnderscore && hasDoubleUnderscore(D)) {
+    return false;
+  }
+  return true;
+}
+
 static void writeDeclCommentTable(
     const comment_block::DeclCommentListLayout &DeclCommentList,
     const SourceFile *SF, const ModuleDecl *M,
@@ -323,44 +370,6 @@
       return StringRef(Mem, String.size());
     }
 
-    bool shouldIncludeDecl(Decl *D) {
-      if (auto *VD = dyn_cast<ValueDecl>(D)) {
-        // Skip the decl if it's not visible to clients. The use of
-        // getEffectiveAccess is unusual here; we want to take the testability
-        // state into account and emit documentation if and only if they are
-        // visible to clients (which means public ordinarily, but
-        // public+internal when testing enabled).
-        if (VD->getEffectiveAccess() < swift::AccessLevel::Public)
-          return false;
-      }
-      // Exclude decls with double-underscored names, either in arguments or
-      // base names.
-      StringRef Prefix = "__";
-      if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
-        return shouldIncludeDecl(ED->getExtendedNominal());
-      }
-
-      if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
-        // If it's a function with a parameter with leading double underscore,
-        // it's a private function.
-        if (AFD->getParameters()->hasInternalParameter(Prefix))
-          return false;
-      }
-
-      if (auto SubscriptD = dyn_cast<SubscriptDecl>(D)) {
-        if (SubscriptD->getIndices()->hasInternalParameter(Prefix))
-          return false;
-      }
-      if (auto *VD = dyn_cast<ValueDecl>(D)) {
-        auto Name = VD->getBaseName();
-        if (!Name.isSpecial() &&
-            Name.getIdentifier().str().startswith(Prefix)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
     bool shouldSerializeDoc(Decl *D) {
       // When building the stdlib we intend to serialize unusual comments.
       // This situation is represented by GroupContext.isEnable().  In that
@@ -393,7 +402,7 @@
     }
 
     bool walkToDeclPre(Decl *D) override {
-      if (!shouldIncludeDecl(D))
+      if (!shouldIncludeDecl(D, /*ExcludeDoubleUnderscore*/true))
         return false;
       if (!shouldSerializeDoc(D))
         return true;
@@ -410,7 +419,7 @@
       {
         USRBuffer.clear();
         llvm::raw_svector_ostream OS(USRBuffer);
-        if (ide::printDeclUSR(VD, OS))
+        if (ide::printValueDeclUSR(VD, OS))
           return true;
       }
 
@@ -502,7 +511,288 @@
 
   S.writeToStream(os);
 }
+namespace {
+struct DeclLocationsTableData {
+  uint32_t SourceFileOffset;
+  LineColumn Loc;
+  LineColumn StartLoc;
+  LineColumn EndLoc;
+};
 
-void serialization::writeSourceInfoToStream(raw_ostream &os, ModuleOrSourceFile DC) {
-  os << "Some stuff";
+class USRTableInfo {
+public:
+  using key_type = StringRef;
+  using key_type_ref = key_type;
+  using data_type = uint32_t;
+  using data_type_ref = const data_type &;
+  using hash_value_type = uint32_t;
+  using offset_type = unsigned;
+
+  hash_value_type ComputeHash(key_type_ref key) {
+    assert(!key.empty());
+    return llvm::djbHash(key, SWIFTSOURCEINFO_HASH_SEED);
+  }
+
+  std::pair<unsigned, unsigned>
+  EmitKeyDataLength(raw_ostream &out, key_type_ref key, data_type_ref data) {
+    const unsigned numLen = 4;
+    uint32_t keyLength = key.size();
+    uint32_t dataLength = numLen;
+    endian::Writer writer(out, little);
+    writer.write<uint32_t>(keyLength);
+    return { keyLength, dataLength };
+  }
+
+  void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+    out << key;
+  }
+
+  void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                unsigned len) {
+    endian::Writer writer(out, little);
+    writer.write<uint32_t>(data);
+  }
+};
+
+class DeclUSRsTableWriter {
+  llvm::StringSet<> USRs;
+  llvm::OnDiskChainedHashTableGenerator<USRTableInfo> generator;
+public:
+  uint32_t peekNextId() const { return USRs.size(); }
+  Optional<uint32_t> getNewUSRId(StringRef USR) {
+    // Attempt to insert the USR into the StringSet.
+    auto It = USRs.insert(USR);
+    // If the USR exists in the StringSet, return None.
+    if (!It.second)
+      return None;
+    auto Id = USRs.size() - 1;
+    // We have to insert the USR from the StringSet because it's where the
+    // memory is owned.
+    generator.insert(It.first->getKey(), Id);
+    return Id;
+  }
+  void emitUSRsRecord(llvm::BitstreamWriter &out) {
+    decl_locs_block::DeclUSRSLayout USRsList(out);
+    SmallVector<uint64_t, 8> scratch;
+    llvm::SmallString<32> hashTableBlob;
+    uint32_t tableOffset;
+    {
+      llvm::raw_svector_ostream blobStream(hashTableBlob);
+      // Make sure that no bucket is at offset 0
+      endian::write<uint32_t>(blobStream, 0, little);
+      tableOffset = generator.Emit(blobStream);
+    }
+    USRsList.emit(scratch, tableOffset, hashTableBlob);
+  }
+};
+
+class StringWriter {
+  llvm::StringMap<uint32_t> IndexMap;
+  llvm::SmallString<1024> Buffer;
+public:
+  uint32_t getTextOffset(StringRef Text) {
+    if (IndexMap.find(Text) == IndexMap.end()) {
+      IndexMap.insert({Text, Buffer.size()});
+      Buffer.append(Text);
+      Buffer.push_back('\0');
+    }
+    return IndexMap[Text];
+  }
+
+  void emitSourceFilesRecord(llvm::BitstreamWriter &Out) {
+    decl_locs_block::TextDataLayout TextBlob(Out);
+    SmallVector<uint64_t, 8> scratch;
+    TextBlob.emit(scratch, Buffer);
+  }
+};
+
+struct BasicDeclLocsTableWriter : public ASTWalker {
+  llvm::SmallString<1024> Buffer;
+  DeclUSRsTableWriter &USRWriter;
+  StringWriter &FWriter;
+  BasicDeclLocsTableWriter(DeclUSRsTableWriter &USRWriter,
+                           StringWriter &FWriter): USRWriter(USRWriter),
+                           FWriter(FWriter) {}
+
+  std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override { return { false, S };}
+  std::pair<bool, Expr *> walkToExprPre(Expr *E) override { return { false, E };}
+  bool walkToTypeLocPre(TypeLoc &TL) override { return false; }
+  bool walkToTypeReprPre(TypeRepr *T) override { return false; }
+  bool walkToParameterListPre(ParameterList *PL) override { return false; }
+
+  void appendToBuffer(DeclLocationsTableData data) {
+    llvm::raw_svector_ostream out(Buffer);
+    endian::Writer writer(out, little);
+    writer.write<uint32_t>(data.SourceFileOffset);
+#define WRITE_LINE_COLUMN(X)                                                  \
+writer.write<uint32_t>(data.X.Line);                                          \
+writer.write<uint32_t>(data.X.Column);
+    WRITE_LINE_COLUMN(Loc)
+    WRITE_LINE_COLUMN(StartLoc);
+    WRITE_LINE_COLUMN(EndLoc);
+#undef WRITE_LINE_COLUMN
+  }
+
+  Optional<uint32_t> calculateNewUSRId(Decl *D) {
+    llvm::SmallString<512> Buffer;
+    llvm::raw_svector_ostream OS(Buffer);
+    if (ide::printDeclUSR(D, OS))
+      return None;
+    return USRWriter.getNewUSRId(OS.str());
+  }
+
+  LineColumn getLineColumn(SourceManager &SM, SourceLoc Loc) {
+    LineColumn Result;
+    if (Loc.isValid()) {
+      auto LC = SM.getLineAndColumn(Loc);
+      Result.Line = LC.first;
+      Result.Column = LC.second;
+    }
+    return Result;
+  }
+
+  Optional<DeclLocationsTableData> getLocData(Decl *D) {
+    auto *File = D->getDeclContext()->getModuleScopeContext();
+    auto Locs = cast<FileUnit>(File)->getBasicLocsForDecl(D);
+    if (!Locs.hasValue())
+      return None;
+    DeclLocationsTableData Result;
+    llvm::SmallString<128> AbsolutePath = Locs->SourceFilePath;
+    llvm::sys::fs::make_absolute(AbsolutePath);
+    Result.SourceFileOffset = FWriter.getTextOffset(AbsolutePath.str());
+#define COPY_LINE_COLUMN(X)                                                   \
+Result.X.Line = Locs->X.Line;                                                 \
+Result.X.Column = Locs->X.Column;
+    COPY_LINE_COLUMN(Loc)
+    COPY_LINE_COLUMN(StartLoc)
+    COPY_LINE_COLUMN(EndLoc)
+#undef COPY_LINE_COLUMN
+    return Result;
+  }
+
+  bool shouldSerializeSourceLoc(Decl *D) {
+    if (D->isImplicit())
+      return false;
+    return true;
+  }
+
+  bool walkToDeclPre(Decl *D) override {
+    SWIFT_DEFER {
+      assert(USRWriter.peekNextId() * sizeof(DeclLocationsTableData)
+             == Buffer.size() &&
+            "USR Id has a one-to-one mapping with DeclLocationsTableData");
+    };
+    // .swiftdoc doesn't include comments for double underscored symbols, but
+    // for .swiftsourceinfo, having the source location for these symbols isn't
+    // a concern becuase these symbols are in .swiftinterface anyway.
+    if (!shouldIncludeDecl(D, /*ExcludeDoubleUnderscore*/false))
+      return false;
+    if (!shouldSerializeSourceLoc(D))
+      return true;
+    // If we cannot get loc data for D, don't proceed.
+    auto LocData = getLocData(D);
+    if (!LocData.hasValue())
+      return true;
+    // If we have handled this USR before, don't proceed.
+    auto USR = calculateNewUSRId(D);
+    if (!USR.hasValue())
+      return true;
+    appendToBuffer(*LocData);
+    return true;
+  }
+};
+
+static void emitBasicLocsRecord(llvm::BitstreamWriter &Out,
+                                ModuleOrSourceFile MSF,
+                                DeclUSRsTableWriter &USRWriter,
+                                StringWriter &FWriter) {
+  assert(MSF);
+  const decl_locs_block::BasicDeclLocsLayout DeclLocsList(Out);
+  BasicDeclLocsTableWriter Writer(USRWriter, FWriter);
+  if (auto *SF = MSF.dyn_cast<SourceFile*>()) {
+    SF->walk(Writer);
+  } else {
+    MSF.get<ModuleDecl*>()->walk(Writer);
+  }
+
+  SmallVector<uint64_t, 8> scratch;
+  DeclLocsList.emit(scratch, Writer.Buffer);
+}
+
+class SourceInfoSerializer : public SerializerBase {
+public:
+  using SerializerBase::SerializerBase;
+  using SerializerBase::writeToStream;
+
+  using SerializerBase::Out;
+  using SerializerBase::M;
+  using SerializerBase::SF;
+  /// Writes the BLOCKINFO block for the module sourceinfo file.
+  void writeSourceInfoBlockInfoBlock() {
+    BCBlockRAII restoreBlock(Out, llvm::bitc::BLOCKINFO_BLOCK_ID, 2);
+
+    SmallVector<unsigned char, 64> nameBuffer;
+#define BLOCK(X) emitBlockID(X ## _ID, #X, nameBuffer)
+#define BLOCK_RECORD(K, X) emitRecordID(K::X, #X, nameBuffer)
+
+    BLOCK(MODULE_SOURCEINFO_BLOCK);
+
+    BLOCK(CONTROL_BLOCK);
+    BLOCK_RECORD(control_block, METADATA);
+    BLOCK_RECORD(control_block, MODULE_NAME);
+    BLOCK_RECORD(control_block, TARGET);
+
+    BLOCK(DECL_LOCS_BLOCK);
+    BLOCK_RECORD(decl_locs_block, BASIC_DECL_LOCS);
+    BLOCK_RECORD(decl_locs_block, DECL_USRS);
+    BLOCK_RECORD(decl_locs_block, TEXT_DATA);
+
+#undef BLOCK
+#undef BLOCK_RECORD
+  }
+  /// Writes the Swift sourceinfo file header and name.
+  void writeSourceInfoHeader() {
+    {
+      BCBlockRAII restoreBlock(Out, CONTROL_BLOCK_ID, 3);
+      control_block::ModuleNameLayout ModuleName(Out);
+      control_block::MetadataLayout Metadata(Out);
+      control_block::TargetLayout Target(Out);
+
+      auto& LangOpts = M->getASTContext().LangOpts;
+      Metadata.emit(ScratchRecord, SWIFTSOURCEINFO_VERSION_MAJOR,
+                    SWIFTSOURCEINFO_VERSION_MINOR,
+                    /*short version string length*/0, /*compatibility length*/0,
+              version::getSwiftFullVersion(LangOpts.EffectiveLanguageVersion));
+
+      ModuleName.emit(ScratchRecord, M->getName().str());
+      Target.emit(ScratchRecord, LangOpts.Target.str());
+    }
+  }
+};
+}
+void serialization::writeSourceInfoToStream(raw_ostream &os,
+                                            ModuleOrSourceFile DC) {
+  assert(DC);
+  SourceInfoSerializer S{SWIFTSOURCEINFO_SIGNATURE, DC};
+  // FIXME: This is only really needed for debugging. We don't actually use it.
+  S.writeSourceInfoBlockInfoBlock();
+  {
+    BCBlockRAII moduleBlock(S.Out, MODULE_SOURCEINFO_BLOCK_ID, 2);
+    S.writeSourceInfoHeader();
+    {
+      BCBlockRAII restoreBlock(S.Out, DECL_LOCS_BLOCK_ID, 4);
+      DeclUSRsTableWriter USRWriter;
+      StringWriter FPWriter;
+      emitBasicLocsRecord(S.Out, DC, USRWriter, FPWriter);
+      // Emit USR table mapping from a USR to USR Id.
+      // The basic locs record uses USR Id instead of actual USR, so that we
+      // don't need to repeat USR texts for newly added records.
+      USRWriter.emitUSRsRecord(S.Out);
+      // A blob of 0 terminated strings referenced by the location records,
+      // e.g. file paths.
+      FPWriter.emitSourceFilesRecord(S.Out);
+    }
+  }
+
+  S.writeToStream(os);
 }
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index 137a0cc..2ece9e5 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -263,10 +263,43 @@
   return std::error_code();
 }
 
+void
+SerializedModuleLoaderBase::openModuleSourceInfoFileIfPresent(
+                                                      AccessPathElem ModuleID,
+                                                      StringRef ModulePath,
+                                            StringRef ModuleSourceInfoFilename,
+                              std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
+  if (!ModuleSourceInfoBuffer)
+    return;
+  llvm::vfs::FileSystem &FS = *Ctx.SourceMgr.getFileSystem();
+  llvm::SmallString<128> PathWithoutProjectDir(ModulePath);
+  llvm::sys::path::replace_extension(PathWithoutProjectDir,
+                  file_types::getExtension(file_types::TY_SwiftSourceInfoFile));
+  llvm::SmallString<128> PathWithProjectDir = PathWithoutProjectDir.str();
+  StringRef FileName = llvm::sys::path::filename(PathWithoutProjectDir);
+  llvm::sys::path::remove_filename(PathWithProjectDir);
+  llvm::sys::path::append(PathWithProjectDir, "Project");
+  llvm::sys::path::append(PathWithProjectDir, FileName);
+
+  // Try to open the module source info file from the "Project" directory.
+  // If it does not exist, ignore the error.
+  if (auto ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithProjectDir)) {
+    *ModuleSourceInfoBuffer = std::move(*ModuleSourceInfoOrErr);
+    return;
+  }
+  // Try to open the module source info file adjacent to the .swiftmodule file.
+  if (auto ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithoutProjectDir)) {
+    *ModuleSourceInfoBuffer = std::move(*ModuleSourceInfoOrErr);
+    return;
+  }
+}
+
 std::error_code SerializedModuleLoaderBase::openModuleFiles(
     AccessPathElem ModuleID, StringRef ModulePath, StringRef ModuleDocPath,
+    StringRef ModuleSourceInfoFileName,
     std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
   assert(((ModuleBuffer && ModuleDocBuffer) ||
           (!ModuleBuffer && !ModuleDocBuffer)) &&
          "Module and Module Doc buffer must both be initialized or NULL");
@@ -294,6 +327,10 @@
   if (!ModuleOrErr)
     return ModuleOrErr.getError();
 
+  // Open .swiftsourceinfo file if it's present.
+  openModuleSourceInfoFileIfPresent(ModuleID, ModulePath,
+                                    ModuleSourceInfoFileName,
+                                    ModuleSourceInfoBuffer);
   auto ModuleDocErr =
     openModuleDocFile(ModuleID, ModuleDocPath, ModuleDocBuffer);
   if (ModuleDocErr)
@@ -306,9 +343,10 @@
 
 std::error_code SerializedModuleLoader::findModuleFilesInDirectory(
     AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
-    StringRef ModuleDocFilename,
+    StringRef ModuleDocFilename, StringRef ModuleSourceInfoFileName,
     std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
   if (LoadMode == ModuleLoadingMode::OnlyInterface)
     return std::make_error_code(std::errc::not_supported);
 
@@ -319,8 +357,10 @@
   return SerializedModuleLoaderBase::openModuleFiles(ModuleID,
                                                      ModulePath,
                                                      ModuleDocPath,
+                                                     ModuleSourceInfoFileName,
                                                      ModuleBuffer,
-                                                     ModuleDocBuffer);
+                                                     ModuleDocBuffer,
+                                                     ModuleSourceInfoBuffer);
 }
 
 bool SerializedModuleLoader::maybeDiagnoseTargetMismatch(
@@ -361,15 +401,19 @@
 struct ModuleFilenamePair {
   llvm::SmallString<64> module;
   llvm::SmallString<64> moduleDoc;
+  llvm::SmallString<64> moduleSourceInfo;
 
   ModuleFilenamePair(StringRef baseName)
-    : module(baseName), moduleDoc(baseName)
+    : module(baseName), moduleDoc(baseName), moduleSourceInfo(baseName)
   {
     module += '.';
     module += file_types::getExtension(file_types::TY_SwiftModuleFile);
 
     moduleDoc += '.';
     moduleDoc += file_types::getExtension(file_types::TY_SwiftModuleDocFile);
+
+    moduleSourceInfo += '.';
+    moduleSourceInfo += file_types::getExtension(file_types::TY_SwiftSourceInfoFile);
   }
 };
 
@@ -377,6 +421,7 @@
 SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
            std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
            std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
+           std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
            bool &isFramework, bool &isSystemModule) {
   llvm::SmallString<64> moduleName(moduleID.first.str());
   ModuleFilenamePair fileNames(moduleName);
@@ -400,7 +445,9 @@
     for (const auto &targetFileNames : targetFileNamePairs) {
       auto result = findModuleFilesInDirectory(moduleID, currPath,
                         targetFileNames.module, targetFileNames.moduleDoc,
-                        moduleBuffer, moduleDocBuffer);
+                        targetFileNames.moduleSourceInfo,
+                        moduleBuffer, moduleDocBuffer,
+                        moduleSourceInfoBuffer);
       if (!result) {
         return true;
       } else if (result == std::errc::not_supported) {
@@ -452,7 +499,8 @@
 
           auto result = findModuleFilesInDirectory(
               moduleID, path, fileNames.module.str(), fileNames.moduleDoc.str(),
-              moduleBuffer, moduleDocBuffer);
+              fileNames.moduleSourceInfo.str(),
+              moduleBuffer, moduleDocBuffer, moduleSourceInfoBuffer);
           if (!result)
             return true;
           else if (result == std::errc::not_supported)
@@ -520,6 +568,7 @@
     ModuleDecl &M, Optional<SourceLoc> diagLoc,
     std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
     std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
+    std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
     bool isFramework, bool treatAsPartialModule) {
   assert(moduleInputBuffer);
 
@@ -540,6 +589,7 @@
   serialization::ValidationInfo loadInfo =
       ModuleFile::load(std::move(moduleInputBuffer),
                        std::move(moduleDocInputBuffer),
+                       std::move(moduleSourceInfoInputBuffer),
                        isFramework, loadedModuleFile,
                        &extendedInfo);
   if (loadInfo.status == serialization::Status::Valid) {
@@ -770,7 +820,7 @@
   // Look on disk.
   bool isFramework = false;
   bool isSystemModule = false;
-  return findModule(mID, nullptr, nullptr, isFramework, isSystemModule);
+  return findModule(mID, nullptr, nullptr, nullptr, isFramework, isSystemModule);
 }
 
 bool MemoryBufferSerializedModuleLoader::canImportModule(
@@ -792,9 +842,11 @@
 
   std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer;
   std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer;
+  std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer;
 
   // Look on disk.
   if (!findModule(moduleID, &moduleInputBuffer, &moduleDocInputBuffer,
+                  &moduleSourceInfoInputBuffer,
                   isFramework, isSystemModule)) {
     return nullptr;
   }
@@ -814,8 +866,8 @@
   SWIFT_DEFER { M->setHasResolvedImports(); };
 
   if (!loadAST(*M, moduleID.second, std::move(moduleInputBuffer),
-               std::move(moduleDocInputBuffer), isFramework,
-               /*treatAsPartialModule*/false)) {
+               std::move(moduleDocInputBuffer), std::move(moduleSourceInfoInputBuffer),
+               isFramework, /*treatAsPartialModule*/false)) {
     M->setFailedToLoad();
   }
 
@@ -850,7 +902,7 @@
   auto *M = ModuleDecl::create(moduleID.first, Ctx);
   SWIFT_DEFER { M->setHasResolvedImports(); };
 
-  if (!loadAST(*M, moduleID.second, std::move(moduleInputBuffer), {},
+  if (!loadAST(*M, moduleID.second, std::move(moduleInputBuffer), {}, {},
                isFramework, treatAsPartialModule)) {
     return nullptr;
   }
@@ -884,9 +936,10 @@
 
 std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
     AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
-    StringRef ModuleDocFilename,
+    StringRef ModuleDocFilename, StringRef ModuleSourceInfoFilename,
     std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
-    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
+    std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
   // This is a soft error instead of an llvm_unreachable because this API is
   // primarily used by LLDB which makes it more likely that unwitting changes to
   // the Swift compiler accidentally break the contract.
@@ -1010,6 +1063,11 @@
   return File.getCommentForDecl(D);
 }
 
+Optional<BasicDeclLocs>
+SerializedASTFile::getBasicLocsForDecl(const Decl *D) const {
+  return File.getBasicDeclLocsForDecl(D);
+}
+
 Optional<StringRef>
 SerializedASTFile::getGroupNameForDecl(const Decl *D) const {
   return File.getGroupNameForDecl(D);
diff --git a/lib/Serialization/SourceInfoFormat.h b/lib/Serialization/SourceInfoFormat.h
new file mode 100644
index 0000000..d4b7f45
--- /dev/null
+++ b/lib/Serialization/SourceInfoFormat.h
@@ -0,0 +1,97 @@
+//===--- SourceInfoFormat.h - Format swiftsourceinfo files ---*- c++ -*---===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2019 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file Contains various constants and helper types to deal with serialized
+/// source information (.swiftsourceinfo files).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SERIALIZATION_SOURCEINFOFORMAT_H
+#define SWIFT_SERIALIZATION_SOURCEINFOFORMAT_H
+
+#include "llvm/Bitcode/RecordLayout.h"
+
+namespace swift {
+namespace serialization {
+
+using llvm::BCArray;
+using llvm::BCBlob;
+using llvm::BCFixed;
+using llvm::BCGenericRecordLayout;
+using llvm::BCRecordLayout;
+using llvm::BCVBR;
+
+/// Magic number for serialized source info files.
+const unsigned char SWIFTSOURCEINFO_SIGNATURE[] = { 0xF0, 0x9F, 0x8F, 0x8E };
+
+/// Serialized sourceinfo format major version number.
+///
+/// Increment this value when making a backwards-incompatible change, i.e. where
+/// an \e old compiler will \e not be able to read the new format. This should
+/// be rare. When incrementing this value, reset SWIFTSOURCEINFO_VERSION_MINOR to 0.
+///
+/// See docs/StableBitcode.md for information on how to make
+/// backwards-compatible changes using the LLVM bitcode format.
+const uint16_t SWIFTSOURCEINFO_VERSION_MAJOR = 1;
+
+/// Serialized swiftsourceinfo format minor version number.
+///
+/// Increment this value when making a backwards-compatible change that might be
+/// interesting to test for. A backwards-compatible change is one where an \e
+/// old compiler can read the new format without any problems (usually by
+/// ignoring new information).
+const uint16_t SWIFTSOURCEINFO_VERSION_MINOR = 1; // Last change: skipping 0 for testing purposes
+
+/// The hash seed used for the string hashes(llvm::djbHash) in a .swiftsourceinfo file.
+const uint32_t SWIFTSOURCEINFO_HASH_SEED = 5387;
+
+/// The record types within the DECL_LOCS block.
+///
+/// Though we strive to keep the format stable, breaking the format of
+/// .swiftsourceinfo doesn't have consequences as serious as breaking the format
+/// of .swiftdoc, because .swiftsourceinfo file is for local development use only.
+///
+/// When changing this block, backwards-compatible changes are prefered.
+/// You may need to update the version when you do so. See docs/StableBitcode.md
+/// for information on how to make backwards-compatible changes using the LLVM
+/// bitcode format.
+///
+/// \sa DECL_LOCS_BLOCK_ID
+namespace decl_locs_block {
+  enum RecordKind {
+    BASIC_DECL_LOCS = 1,
+    DECL_USRS,
+    TEXT_DATA,
+  };
+
+  using BasicDeclLocsLayout = BCRecordLayout<
+    BASIC_DECL_LOCS, // record ID
+    BCBlob           // an array of fixed size location data
+  >;
+
+  using DeclUSRSLayout = BCRecordLayout<
+    DECL_USRS,         // record ID
+    BCVBR<16>,         // table offset within the blob (an llvm::OnDiskHashTable)
+    BCBlob             // map from actual USR to USR Id
+  >;
+
+  using TextDataLayout = BCRecordLayout<
+    TEXT_DATA,        // record ID
+    BCBlob            // a list of 0-terminated string segments
+  >;
+
+} // namespace sourceinfo_block
+
+} // end namespace serialization
+} // end namespace swift
+
+#endif
diff --git a/lib/Syntax/RawSyntax.cpp b/lib/Syntax/RawSyntax.cpp
index 3323902..25b2474 100644
--- a/lib/Syntax/RawSyntax.cpp
+++ b/lib/Syntax/RawSyntax.cpp
@@ -329,6 +329,8 @@
                         OwnedString Text, ArrayRef<TriviaPiece> LeadingTrivia,
                         ArrayRef<TriviaPiece> TrailingTrivia) {
   ID.AddInteger(unsigned(TokKind));
+  ID.AddInteger(LeadingTrivia.size());
+  ID.AddInteger(TrailingTrivia.size());
   switch (TokKind) {
 #define TOKEN_DEFAULT(NAME) case tok::NAME:
 #define PUNCTUATOR(NAME, X) TOKEN_DEFAULT(NAME)
diff --git a/lib/Syntax/Syntax.cpp b/lib/Syntax/Syntax.cpp
index 850fb9e..6f15143 100644
--- a/lib/Syntax/Syntax.cpp
+++ b/lib/Syntax/Syntax.cpp
@@ -98,6 +98,12 @@
   return Syntax {Root, ChildData.get()};
 }
 
+Optional<Syntax> Syntax::getPreviousNode() const {
+  if (auto prev = getData().getPreviousNode())
+    return Syntax(Root, prev.get());
+  return None;
+}
+
 Optional<TokenSyntax> Syntax::getFirstToken() const {
   if (auto tok = getData().getFirstToken())
     return TokenSyntax(Root, tok.get());
diff --git a/lib/Syntax/SyntaxData.cpp b/lib/Syntax/SyntaxData.cpp
index 8dd30f0..c31a451 100644
--- a/lib/Syntax/SyntaxData.cpp
+++ b/lib/Syntax/SyntaxData.cpp
@@ -85,6 +85,8 @@
 }
 
 RC<SyntaxData> SyntaxData::getFirstToken() const {
+  if (getRaw()->isMissing())
+    return nullptr;
   if (getRaw()->isToken()) {
     // Get a reference counted version of this
     assert(hasParent() && "The syntax tree should not conisist only of the root");
@@ -106,6 +108,8 @@
 }
 
 RC<SyntaxData> SyntaxData::getLastToken() const {
+  if (getRaw()->isMissing())
+    return nullptr;
   if (getRaw()->isToken()) {
     // Get a reference counted version of this
     assert(hasParent() && "The syntax tree should not conisist only of the root");
diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp
index 33328b1..c71bc38 100644
--- a/stdlib/public/runtime/Demangle.cpp
+++ b/stdlib/public/runtime/Demangle.cpp
@@ -68,7 +68,7 @@
       return genericArgsList;
     };
   
-  for (auto component : reversed(descriptorPath)) {
+  for (auto component : llvm::reverse(descriptorPath)) {
     switch (auto kind = component->getKind()) {
     case ContextDescriptorKind::Module: {
       assert(node == nullptr && "module should be top level");
diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp
index aeee082..712c0af 100644
--- a/stdlib/public/runtime/HeapObject.cpp
+++ b/stdlib/public/runtime/HeapObject.cpp
@@ -72,6 +72,19 @@
 #endif
 }
 
+// Call the appropriate implementation of the `name` function, passing `args`
+// to the call. This checks for an override in the function pointer. If an
+// override is present, it calls that override. Otherwise it directly calls
+// the default implementation. This allows the compiler to inline the default
+// implementation and avoid the performance penalty of indirecting through
+// the function pointer in the common case.
+#define CALL_IMPL(name, args) do { \
+    if (SWIFT_UNLIKELY(_ ## name != _ ## name ## _)) \
+      return _ ## name args; \
+    return _ ## name ## _ args; \
+} while(0)
+
+
 static HeapObject *_swift_allocObject_(HeapMetadata const *metadata,
                                        size_t requiredSize,
                                        size_t requiredAlignmentMask) {
@@ -95,9 +108,7 @@
 HeapObject *swift::swift_allocObject(HeapMetadata const *metadata,
                                      size_t requiredSize,
                                      size_t requiredAlignmentMask) {
-  if (SWIFT_UNLIKELY(_swift_allocObject != _swift_allocObject_))
-    return _swift_allocObject(metadata, requiredSize, requiredAlignmentMask);
-  return _swift_allocObject_(metadata, requiredSize, requiredAlignmentMask);
+  CALL_IMPL(swift_allocObject, (metadata, requiredSize, requiredAlignmentMask));
 }
 
 HeapObject *(*swift::_swift_allocObject)(HeapMetadata const *metadata,
@@ -305,9 +316,7 @@
 }
 
 HeapObject *swift::swift_retain(HeapObject *object) {
-  if (SWIFT_UNLIKELY(_swift_retain != _swift_retain_))
-    return _swift_retain(object);
-  return _swift_retain_(object);
+  CALL_IMPL(swift_retain, (object));
 }
 
 HeapObject *(*swift::_swift_retain)(HeapObject *object) = _swift_retain_;
@@ -327,9 +336,7 @@
 }
 
 HeapObject *swift::swift_retain_n(HeapObject *object, uint32_t n) {
-  if (SWIFT_UNLIKELY(_swift_retain_n != _swift_retain_n_))
-    return _swift_retain_n(object, n);
-  return _swift_retain_n_(object, n);
+  CALL_IMPL(swift_retain_n, (object, n));
 }
 
 HeapObject *(*swift::_swift_retain_n)(HeapObject *object, uint32_t n) =
@@ -349,9 +356,7 @@
 }
 
 void swift::swift_release(HeapObject *object) {
-  if (SWIFT_UNLIKELY(_swift_release != _swift_release_))
-    _swift_release(object);
-  _swift_release_(object);
+  CALL_IMPL(swift_release, (object));
 }
 
 void (*swift::_swift_release)(HeapObject *object) = _swift_release_;
@@ -369,9 +374,7 @@
 }
 
 void swift::swift_release_n(HeapObject *object, uint32_t n) {
-  if (SWIFT_UNLIKELY(_swift_release_n != _swift_release_n_))
-    return _swift_release_n(object, n);
-  return _swift_release_n_(object, n);
+  CALL_IMPL(swift_release_n, (object, n));
 }
 
 void (*swift::_swift_release_n)(HeapObject *object, uint32_t n) =
@@ -509,9 +512,7 @@
 }
 
 HeapObject *swift::swift_tryRetain(HeapObject *object) {
-  if (SWIFT_UNLIKELY(_swift_tryRetain != _swift_tryRetain_))
-    return _swift_tryRetain(object);
-  return _swift_tryRetain_(object);
+  CALL_IMPL(swift_tryRetain, (object));
 }
 
 HeapObject *(*swift::_swift_tryRetain)(HeapObject *object) = _swift_tryRetain_;
diff --git a/stdlib/toolchain/Compatibility50/ProtocolConformance.cpp b/stdlib/toolchain/Compatibility50/ProtocolConformance.cpp
index a9ab153..446a69c 100644
--- a/stdlib/toolchain/Compatibility50/ProtocolConformance.cpp
+++ b/stdlib/toolchain/Compatibility50/ProtocolConformance.cpp
@@ -20,6 +20,7 @@
 #include "Overrides.h"
 #include "../../public/runtime/Private.h"
 #include "swift/Basic/Lazy.h"
+#include <dlfcn.h>
 #include <mach-o/dyld.h>
 #include <mach-o/getsect.h>
 #include <objc/runtime.h>
@@ -89,13 +90,25 @@
   _dyld_register_func_for_add_image(addImageCallback);
 }
 
+static const Metadata *getObjCClassMetadata(const ClassMetadata *c) {
+  // Look up swift_getObjCClassMetadata dynamically. This handles the case
+  // where the main executable can't link against libswiftCore.dylib because
+  // it will be loaded dynamically from a location that isn't known at build
+  // time.
+  using FPtr = const Metadata *(*)(const ClassMetadata *);
+  FPtr func = SWIFT_LAZY_CONSTANT(
+    reinterpret_cast<FPtr>(dlsym(RTLD_DEFAULT, "swift_getObjCClassMetadata")));
+
+  return func(c);
+}
+
 // Clone of private helper swift::_swiftoverride_class_getSuperclass
 // for use in the override implementation.
 static const Metadata *_swift50override_class_getSuperclass(
                                                     const Metadata *theClass) {
   if (const ClassMetadata *classType = theClass->getClassObject()) {
     if (classHasSuperclass(classType))
-      return getMetadataForClass(classType->Superclass);
+      return getObjCClassMetadata(classType->Superclass);
   }
   
   if (const ForeignClassMetadata *foreignClassType
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3b3af20..c6124ac 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -208,7 +208,7 @@
 
     # NOTE create a stub BlocksRuntime library that can be used for the
     # reflection tests
-    file(WRITE ${test_bin_dir}/BlocksRuntime.c
+    file(WRITE ${test_bin_dir}/Inputs/BlocksRuntime.c
       "void
 #if defined(_WIN32)
 __declspec(dllexport)
@@ -223,7 +223,7 @@
       ARCHITECTURE ${ARCH}
       SDK ${SDK}
       INSTALL_IN_COMPONENT dev
-      ${test_bin_dir}/BlocksRuntime.c)
+      ${test_bin_dir}/Inputs/BlocksRuntime.c)
     set_target_properties(BlocksRuntimeStub${VARIANT_SUFFIX} PROPERTIES
       ARCHIVE_OUTPUT_DIRECTORY ${test_bin_dir}
       LIBRARY_OUTPUT_DIRECTORY ${test_bin_dir}
diff --git a/test/Constraints/bridging.swift b/test/Constraints/bridging.swift
index 1897172..f6ef698 100644
--- a/test/Constraints/bridging.swift
+++ b/test/Constraints/bridging.swift
@@ -285,7 +285,8 @@
 
 // <rdar://problem/20029786> Swift compiler sometimes suggests changing "as!" to "as?!"
 func rdar20029786(_ ns: NSString?) {
-  var s: String = ns ?? "str" as String as String // expected-error{{cannot convert value of type 'NSString?' to expected argument type 'String?'}}{{21-21= as String?}}
+  var s: String = ns ?? "str" as String as String // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}} {{19-19=(}} {{50-50=) as String}}
+  // expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'NSString'}} {{50-50= as NSString}}
   var s2 = ns ?? "str" as String as String // expected-error {{cannot convert value of type 'String' to expected argument type 'NSString'}}{{43-43= as NSString}}
 
   let s3: NSString? = "str" as String? // expected-error {{cannot convert value of type 'String?' to specified type 'NSString?'}}{{39-39= as NSString?}}
diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift
index 4c7f011..012aa0f 100644
--- a/test/Constraints/closures.swift
+++ b/test/Constraints/closures.swift
@@ -870,7 +870,7 @@
 struct rdar43866352<Options> {
   func foo() {
     let callback: (inout Options) -> Void
-    callback = { (options: Options) in } // expected-error {{cannot assign value of type '(inout Options) -> ()' to type '(inout _) -> Void'}}
+    callback = { (options: Options) in } // expected-error {{cannot assign value of type '(Options) -> ()' to type '(inout Options) -> Void'}}
   }
 }
 
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index 7a5d54e..05401f7 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -522,6 +522,7 @@
 // expected-error@-1 {{passing value of type 'Int' to an inout parameter requires explicit '&'}}
 let _: Color = .frob(1, b: i)  // expected-error {{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{28-28=&}}
 let _: Color = .frob(1, &d) // expected-error {{missing argument label 'b:' in call}}
+// expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}}
 let _: Color = .frob(1, b: &d) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
 var someColor : Color = .red // expected-error {{enum type 'Color' has no case 'red'; did you mean 'Red'}}
 someColor = .red  // expected-error {{enum type 'Color' has no case 'red'; did you mean 'Red'}}
diff --git a/test/Constraints/enum_cases.swift b/test/Constraints/enum_cases.swift
index 2f7bb06..e4f1bb7 100644
--- a/test/Constraints/enum_cases.swift
+++ b/test/Constraints/enum_cases.swift
@@ -104,7 +104,8 @@
 
 struct Foo_32551313 {
   static func bar() -> E_32551313<(String, Foo_32551313?), (String, String)>? {
-    return E_32551313.Left("", Foo_32551313()) // expected-error {{extra argument in call}}
+    return E_32551313.Left("", Foo_32551313()) // expected-error {{enum case 'Left' expects a single parameter of type 'L' [with L = (String, Foo_32551313?)]}}
+    // expected-note@-1 {{did you mean to pass a tuple?}} {{28-28=(}} {{46-46=)}}
   }
 }
 
diff --git a/test/Constraints/keypath.swift b/test/Constraints/keypath.swift
index e7dc872..e224618 100644
--- a/test/Constraints/keypath.swift
+++ b/test/Constraints/keypath.swift
@@ -82,3 +82,23 @@
 func testFoo<T: Foo>(_: T) {
   let _: X<T> = .init(foo: \.optBar!.optWibble?.boolProperty)
 }
+
+// rdar://problem/56131416
+
+enum Rdar56131416 {
+  struct Pass<T> {}
+  static func f<T, U>(_ value: T, _ prop: KeyPath<T, U>) -> Pass<U> { fatalError() }
+
+  struct Fail<T> {}
+  static func f<T, U>(_ value: T, _ transform: (T) -> U) -> Fail<U> { fatalError() }
+  
+  static func takesCorrectType(_: Pass<UInt>) {}
+}
+
+func rdar56131416() {
+  // This call should not be ambiguous.
+  let result = Rdar56131416.f(1, \.magnitude) // no-error
+  
+  // This type should be selected correctly.
+  Rdar56131416.takesCorrectType(result)
+}
diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift
index da32b25..c7f183e 100644
--- a/test/Constraints/tuple_arguments.swift
+++ b/test/Constraints/tuple_arguments.swift
@@ -69,12 +69,12 @@
 
 do {
   generic(3)
-  generic(3, 4) // expected-error {{extra argument in call}}
+  generic(3, 4) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{11-11=(}} {{15-15=)}}
   generic((3))
   generic((3, 4))
 
   genericLabeled(x: 3)
-  genericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+  genericLabeled(x: 3, 4) // expected-error {{global function 'genericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{20-20=(}} {{25-25=)}}
   genericLabeled(x: (3))
   genericLabeled(x: (3, 4))
 
@@ -92,7 +92,7 @@
   let d = (a, b)
 
   generic(a)
-  generic(a, b) // expected-error {{extra argument in call}}
+  generic(a, b) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{11-11=(}} {{15-15=)}}
   generic((a))
   generic(c)
   generic((a, b))
@@ -114,7 +114,7 @@
   var d = (a, b)
 
   generic(a)
-  generic(a, b) // expected-error {{extra argument in call}}
+  generic(a, b) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{11-11=(}} {{15-15=)}}
   generic((a))
   generic(c)
   generic((a, b))
@@ -256,12 +256,12 @@
   let s = Concrete()
 
   s.generic(3)
-  s.generic(3, 4) // expected-error {{extra argument in call}}
+  s.generic(3, 4) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{13-13=(}} {{17-17=)}}
   s.generic((3))
   s.generic((3, 4))
 
   s.genericLabeled(x: 3)
-  s.genericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+  s.genericLabeled(x: 3, 4) // expected-error {{instance method 'genericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{22-22=(}} {{27-27=)}}
   s.genericLabeled(x: (3))
   s.genericLabeled(x: (3, 4))
 
@@ -281,7 +281,7 @@
   let d = (a, b)
 
   s.generic(a)
-  s.generic(a, b) // expected-error {{extra argument in call}}
+  s.generic(a, b) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{13-13=(}} {{17-17=)}}
   s.generic((a))
   s.generic((a, b))
   s.generic(d)
@@ -304,7 +304,7 @@
   var d = (a, b)
 
   s.generic(a)
-  s.generic(a, b) // expected-error {{extra argument in call}}
+  s.generic(a, b) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{13-13=(}} {{17-17=)}}
   s.generic((a))
   s.generic((a, b))
   s.generic(d)
@@ -390,12 +390,12 @@
   var s = Concrete()
 
   s.mutatingGeneric(3)
-  s.mutatingGeneric(3, 4) // expected-error {{extra argument in call}}
+  s.mutatingGeneric(3, 4) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{21-21=(}} {{25-25=)}}
   s.mutatingGeneric((3))
   s.mutatingGeneric((3, 4))
 
   s.mutatingGenericLabeled(x: 3)
-  s.mutatingGenericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+  s.mutatingGenericLabeled(x: 3, 4) // expected-error {{instance method 'mutatingGenericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{30-30=(}} {{35-35=)}}
   s.mutatingGenericLabeled(x: (3))
   s.mutatingGenericLabeled(x: (3, 4))
 
@@ -415,7 +415,7 @@
   let d = (a, b)
 
   s.mutatingGeneric(a)
-  s.mutatingGeneric(a, b) // expected-error {{extra argument in call}}
+  s.mutatingGeneric(a, b) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{21-21=(}} {{25-25=)}}
   s.mutatingGeneric((a))
   s.mutatingGeneric((a, b))
   s.mutatingGeneric(d)
@@ -438,7 +438,7 @@
   var d = (a, b)
 
   s.mutatingGeneric(a)
-  s.mutatingGeneric(a, b) // expected-error {{extra argument in call}}
+  s.mutatingGeneric(a, b) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{21-21=(}} {{25-25=)}}
   s.mutatingGeneric((a))
   s.mutatingGeneric((a, b))
   s.mutatingGeneric(d)
@@ -929,10 +929,10 @@
 }
 
 do {
-  _ = GenericInit(3, 4) // expected-error {{extra argument in call}}
+  _ = GenericInit(3, 4) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{19-19=(}} {{23-23=)}}
   _ = GenericInit((3, 4))
 
-  _ = GenericInitLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+  _ = GenericInitLabeled(x: 3, 4) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{28-28=(}} {{33-33=)}}
   _ = GenericInitLabeled(x: (3, 4))
 
   _ = GenericInitTwo(3, 4)
@@ -967,7 +967,7 @@
   let b = 4
   let c = (a, b)
 
-  _ = GenericInit(a, b) // expected-error {{extra argument in call}}
+  _ = GenericInit(a, b) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{19-19=(}} {{23-23=)}}
   _ = GenericInit((a, b))
   _ = GenericInit(c)
 
@@ -1003,7 +1003,7 @@
   var b = 4
   var c = (a, b)
 
-  _ = GenericInit(a, b) // expected-error {{extra argument in call}}
+  _ = GenericInit(a, b) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{19-19=(}} {{23-23=)}}
   _ = GenericInit((a, b))
   _ = GenericInit(c)
 
@@ -1060,7 +1060,7 @@
   _ = s1[(3.0, 4.0)]
 
   let s1a  = GenericSubscriptLabeled<(Double, Double)>()
-  _ = s1a [x: 3.0, 4.0] // expected-error {{subscript expects a single parameter of type '(Double, Double)'}} {{12-12=(}} {{23-23=)}}
+  _ = s1a [x: 3.0, 4.0] // expected-error {{subscript expects a single parameter of type '(Double, Double)'}} {{14-14=(}} {{23-23=)}}
   _ = s1a [x: (3.0, 4.0)]
 
   let s2 = GenericSubscriptTwo<Double>()
@@ -1072,7 +1072,7 @@
   _ = s3[(3.0, 4.0)]
 
   let s3a = GenericSubscriptLabeledTuple<Double>()
-  _ = s3a[x: 3.0, 4.0] // expected-error {{subscript expects a single parameter of type '(Double, Double)'}} {{11-11=(}} {{22-22=)}}
+  _ = s3a[x: 3.0, 4.0] // expected-error {{subscript expects a single parameter of type '(Double, Double)'}} {{13-13=(}} {{22-22=)}}
   _ = s3a[x: (3.0, 4.0)]
 }
 
@@ -1127,12 +1127,12 @@
 }
 
 do {
-  _ = GenericEnum.one(3, 4) // expected-error {{extra argument in call}}
+  _ = GenericEnum.one(3, 4) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{23-23=(}} {{27-27=)}}
   _ = GenericEnum.one((3, 4))
 
-  _ = GenericEnum.labeled(x: 3, 4) // expected-error {{extra argument in call}}
+  _ = GenericEnum.labeled(x: 3, 4) // expected-error {{enum case 'labeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{29-29=(}} {{34-34=)}}
   _ = GenericEnum.labeled(x: (3, 4))
-  _ = GenericEnum.labeled(3, 4) // expected-error {{extra argument in call}}
+  _ = GenericEnum.labeled(3, 4) // expected-error {{enum case 'labeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{27-27=(}} {{31-31=)}}
   _ = GenericEnum.labeled((3, 4)) // expected-error {{missing argument label 'x:' in call}}
 
   _ = GenericEnum.two(3, 4)
@@ -1163,7 +1163,7 @@
   let b = 4
   let c = (a, b)
 
-  _ = GenericEnum.one(a, b) // expected-error {{extra argument in call}}
+  _ = GenericEnum.one(a, b) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{23-23=(}} {{27-27=)}}
   _ = GenericEnum.one((a, b))
   _ = GenericEnum.one(c)
 
@@ -1199,7 +1199,7 @@
   var b = 4
   var c = (a, b)
 
-  _ = GenericEnum.one(a, b) // expected-error {{extra argument in call}}
+  _ = GenericEnum.one(a, b) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{23-23=(}} {{27-27=)}}
   _ = GenericEnum.one((a, b))
   _ = GenericEnum.one(c)
 
@@ -1262,10 +1262,10 @@
 
   let sTwo = GenericConforms<(Double, Double)>()
 
-  sTwo.requirement(3.0, 4.0) // expected-error {{instance method 'requirement' expects a single parameter of type '(Double, Double)'}} {{20-20=(}} {{28-28=)}}
+  sTwo.requirement(3.0, 4.0) // expected-error {{instance method 'requirement' expects a single parameter of type 'GenericConforms<(Double, Double)>.Element' (aka '(Double, Double)')}} {{20-20=(}} {{28-28=)}}
   sTwo.requirement((3.0, 4.0))
 
-  sTwo.requirementLabeled(x: 3.0, 4.0) // expected-error {{instance method 'requirementLabeled' expects a single parameter of type '(Double, Double)'}}
+  sTwo.requirementLabeled(x: 3.0, 4.0) // expected-error {{instance method 'requirementLabeled' expects a single parameter of type 'GenericConforms<(Double, Double)>.Element' (aka '(Double, Double)')}} {{29-29=(}} {{38-38=)}}
   sTwo.requirementLabeled(x: (3.0, 4.0))
 }
 
@@ -1289,7 +1289,7 @@
 
   let sTwo = GenericConforms<(Double, Double)>()
 
-  sTwo.requirement(a, b) // expected-error {{instance method 'requirement' expects a single parameter of type '(Double, Double)'}} {{20-20=(}} {{24-24=)}}
+  sTwo.requirement(a, b) // expected-error {{instance method 'requirement' expects a single parameter of type 'GenericConforms<(Double, Double)>.Element' (aka '(Double, Double)')}} {{20-20=(}} {{24-24=)}}
   sTwo.requirement((a, b))
   sTwo.requirement(d)
 }
@@ -1314,7 +1314,7 @@
 
   var sTwo = GenericConforms<(Double, Double)>()
 
-  sTwo.requirement(a, b) // expected-error {{instance method 'requirement' expects a single parameter of type '(Double, Double)'}} {{20-20=(}} {{24-24=)}}
+  sTwo.requirement(a, b) // expected-error {{instance method 'requirement' expects a single parameter of type 'GenericConforms<(Double, Double)>.Element' (aka '(Double, Double)')}} {{20-20=(}} {{24-24=)}}
   sTwo.requirement((a, b))
   sTwo.requirement(d)
 }
diff --git a/test/DebugInfo/compiler-flags-macosx.swift b/test/DebugInfo/compiler-flags-macosx.swift
index 302c41a..8dd85c5 100644
--- a/test/DebugInfo/compiler-flags-macosx.swift
+++ b/test/DebugInfo/compiler-flags-macosx.swift
@@ -4,9 +4,9 @@
 
 // RUN: %swiftc_driver %s -emit-ir -g -Xfrontend -disable-legacy-type-info -target x86_64-apple-macosx10.10 -parse-stdlib -module-name scratch -o - | %FileCheck %s
 // RUN: env RC_DEBUG_OPTIONS=1 %swiftc_driver %s -emit-ir -g -Xfrontend -disable-legacy-type-info -target x86_64-apple-macosx10.10 -parse-stdlib -module-name scratch -o - | %FileCheck --check-prefix CHECK-VAR-SET %s
-// CHECK:               !DICompileUnit({{.*}} producer: "{{(Apple )?Swift version [^"]+}}"
+// CHECK:               !DICompileUnit({{.*}} producer: "{{[^"]*Swift version [^"]+}}"
 // CHECK-NOT:                          flags: "
-// CHECK-VAR-SET:       !DICompileUnit({{.*}}producer: "{{(Apple )?Swift version [^"]+}}"
+// CHECK-VAR-SET:       !DICompileUnit({{.*}}producer: "{{[^"]*Swift version [^"]+}}"
 // CHECK-VAR-SET-SAME:                 flags: "
 // CHECK-VAR-SET-NOT:                  "
 // CHECK-VAR-SET-SAME:                 -resource-dir 
diff --git a/test/DebugInfo/compiler-flags.swift b/test/DebugInfo/compiler-flags.swift
index c83b0f8..65bc9ae 100644
--- a/test/DebugInfo/compiler-flags.swift
+++ b/test/DebugInfo/compiler-flags.swift
@@ -4,11 +4,11 @@
 
 // RUN: %target-swiftc_driver %s -emit-ir -debug-info-store-invocation -g -o - | %FileCheck %s
 // RUN: %target-swiftc_driver %s -emit-ir -debug-info-store-invocation -sdk "/Weird Location/SDK" -g -o - | %FileCheck --check-prefix CHECK-EXPLICIT %s
-// CHECK:          !DICompileUnit({{.*}}producer: "{{(Apple )?Swift version [^"]+}}"
+// CHECK:          !DICompileUnit({{.*}}producer: "{{[^"]*Swift version [^"]+}}"
 // CHECK-SAME:                    flags: "
 // CHECK-NOT:                     "
 // CHECK-SAME:                    -resource-dir 
-// CHECK-EXPLICIT: !DICompileUnit({{.*}}producer: "{{(Apple )?Swift version [^"]+}}"
+// CHECK-EXPLICIT: !DICompileUnit({{.*}}producer: "{{[^"]*Swift version [^"]+}}"
 // CHECK-EXPLICIT-SAME:           flags: "
 // CHECK-EXPLICIT-NOT:            "
 // CHECK-EXPLICIT-SAME:           -sdk \22/Weird Location/SDK\22
diff --git a/test/Driver/sourceinfo_file.swift b/test/Driver/sourceinfo_file.swift
index 9fd5cce..bd406d4 100644
--- a/test/Driver/sourceinfo_file.swift
+++ b/test/Driver/sourceinfo_file.swift
@@ -1,14 +1,14 @@
 // RUN: %empty-directory(%t)
-// RUN: mkdir -p %t/build/Private
-// RUN: %swiftc_driver -driver-print-jobs -emit-module %s -emit-module-path %t/build/sourceinfo_file.swiftmodule -module-name sourceinfo_file | %FileCheck %s -check-prefix CHECK-PRIVATE
+// RUN: mkdir -p %t/build/Project
+// RUN: %swiftc_driver -driver-print-jobs -emit-module %s -emit-module-path %t/build/sourceinfo_file.swiftmodule -module-name sourceinfo_file | %FileCheck %s -check-prefix CHECK-PROJECT
 
-// CHECK-PRIVATE: build{{/|\\\\}}Private{{/|\\\\}}sourceinfo_file.swiftsourceinfo
+// CHECK-PROJECT: build{{/|\\\\}}Project{{/|\\\\}}sourceinfo_file.swiftsourceinfo
 
 // RUN: %empty-directory(%t/build)
-// RUN: %swiftc_driver -driver-print-jobs -emit-module %s -emit-module-path %t/build/sourceinfo_file.swiftmodule -module-name sourceinfo_file | %FileCheck %s -check-prefix CHECK-NOPRIVATE
+// RUN: %swiftc_driver -driver-print-jobs -emit-module %s -emit-module-path %t/build/sourceinfo_file.swiftmodule -module-name sourceinfo_file | %FileCheck %s -check-prefix CHECK-NOPROJECT
 
-// CHECK-NOPRIVATE-NOT: Private/sourceinfo_file.swiftsourceinfo
-// CHECK-NOPRIVATE: build{{/|\\\\}}sourceinfo_file.swiftsourceinfo
+// CHECK-NOPROJECT-NOT: Project/sourceinfo_file.swiftsourceinfo
+// CHECK-NOPROJECT: build{{/|\\\\}}sourceinfo_file.swiftsourceinfo
 
 // RUN: %empty-directory(%t/build)
 // RUN: %swiftc_driver -driver-print-jobs -emit-module %s -emit-module-path %t/build/sourceinfo_file.swiftmodule -module-name sourceinfo_file -emit-module-source-info-path %t/build/DriverPath.swiftsourceinfo | %FileCheck %s -check-prefix CHECK-DRIVER-OPT
diff --git a/test/IDE/coloring.swift b/test/IDE/coloring.swift
index 821af3a..c46a10d 100644
--- a/test/IDE/coloring.swift
+++ b/test/IDE/coloring.swift
@@ -271,10 +271,39 @@
   foo(Float())
 }
 
-// CHECK: <object-literal>#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)</object-literal>
+// Check cases where an ObjectLiteralExpr appears in the AST
+//
 #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
-// CHECK: test(<object-literal>#imageLiteral(resourceName: "test")</object-literal>, test: <int>0</int>)
+// CHECK: <object-literal>#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)</object-literal>
 test(#imageLiteral(resourceName: "test"), test: 0)
+// CHECK: test(<object-literal>#imageLiteral(resourceName: "test")</object-literal>, test: <int>0</int>)
+
+// Check best-effort fallback handling when no ObjectLiteralExpr appears in the
+// AST.
+//
+_: Foo = #colorLiteral(red: 1.0, green: 0, blue: 1.0, alpha: 1.0)
+// CHECK: <kw>_</kw>: Foo = <object-literal>#colorLiteral(red: 1.0, green: 0, blue: 1.0, alpha: 1.0)</object-literal>
+_ = [#imageLiteral(resourceName: "foo.png")] + ;
+// CHECK: <kw>_</kw> = [<object-literal>#imageLiteral(resourceName: "foo.png")</object-literal>] + ;
+import let bad = #fileLiteral(resourceName: "foo.txt")
+// CHECK: <kw>import</kw> <kw>let</kw> bad = <object-literal>#fileLiteral(resourceName: "foo.txt")</object-literal>
+import let fixme = #fileLiteral(badArg: 65);
+// CHECK: <kw>import</kw> <kw>let</kw> fixme = <kw>#fileLiteral</kw>(badArg: <int>65</int>);
+let x = #colorLiteral(red: 1.0 / 2.0, green: 0.1 + 0.2, blue: 0.5, alpha: 0.5)
+// CHECK: <kw>let</kw> x = <object-literal>#colorLiteral(red: 1.0 / 2.0, green: 0.1 + 0.2, blue: 0.5, alpha: 0.5)</object-literal>
+
+// Some editors (including Xcode) don't support multi-line object literals well, so
+// check we don't report them regardless of whether they exist in the AST or not.
+//
+_: Foo = #colorLiteral(red: 1.0, green: 0,
+// CHECK: <kw>_</kw>: Foo = <kw>#colorLiteral</kw>(red: <float>1.0</float>, green: <int>0</int>,
+blue: 1.0, alpha: 1.0)
+// CHECK: blue: <float>1.0</float>, alpha: <float>1.0</float>)
+// CHECK: <kw>let</kw> x = <kw>#colorLiteral</kw>(red: <float>1.0</float>, green: <float>1.0</float>,
+let x = #colorLiteral(red: 1.0, green: 1.0,
+// CHECK: blue: <float>1.0</float>, alpha: <float>1.0</float>)
+blue: 1.0, alpha: 1.0)
+
 
 class GenC<T1,T2> {}
 
diff --git a/test/IDE/comment_attach.swift b/test/IDE/comment_attach.swift
index 17e914f..602d80b 100644
--- a/test/IDE/comment_attach.swift
+++ b/test/IDE/comment_attach.swift
@@ -293,10 +293,10 @@
 // CHECK-NEXT: comment_attach.swift:166:6: Enum/decl_enum_1 RawComment=[/// decl_enum_1 Aaa.\n]
 // CHECK-NEXT: comment_attach.swift:168:8: EnumElement/decl_enum_1.Case1 RawComment=[/// Case1 Aaa.\n]
 // CHECK-NEXT: comment_attach.swift:171:8: EnumElement/decl_enum_1.Case2 RawComment=[/// Case2 Aaa.\n]
-// CHECK-NEXT: Param/decl_enum_1.<anonymous> RawComment=none BriefComment=none DocCommentAsXML=none
+// CHECK-NEXT: Param/<anonymous> RawComment=none BriefComment=none DocCommentAsXML=none
 // CHECK-NEXT: comment_attach.swift:174:8: EnumElement/decl_enum_1.Case3 RawComment=[/// Case3 Aaa.\n]
-// CHECK-NEXT: Param/decl_enum_1.<anonymous> RawComment=none BriefComment=none DocCommentAsXML=none
-// CHECK-NEXT: Param/decl_enum_1.<anonymous> RawComment=none BriefComment=none DocCommentAsXML=none
+// CHECK-NEXT: Param/<anonymous> RawComment=none BriefComment=none DocCommentAsXML=none
+// CHECK-NEXT: Param/<anonymous> RawComment=none BriefComment=none DocCommentAsXML=none
 // CHECK-NEXT: comment_attach.swift:177:8: EnumElement/decl_enum_1.Case4 RawComment=[/// Case4 Case5 Aaa.\n]
 // CHECK-NEXT: comment_attach.swift:177:15: EnumElement/decl_enum_1.Case5 RawComment=[/// Case4 Case5 Aaa.\n]
 // CHECK-NEXT: comment_attach.swift:181:7: Class/decl_class_1 RawComment=[/// decl_class_1 Aaa.\n]
diff --git a/test/IDE/complete_call_arg.swift b/test/IDE/complete_call_arg.swift
index 050118e..5170466 100644
--- a/test/IDE/complete_call_arg.swift
+++ b/test/IDE/complete_call_arg.swift
@@ -714,6 +714,7 @@
     .create2(1, #^IMPLICIT_MEMBER_ARRAY_1_SECOND^#
     // Same as IMPLICIT_MEMBER_SECOND.
   ])
+  func sync() {}
   Receiver(arg1: 12, arg2: [
     .create2(1, arg3: 2, #^IMPLICIT_MEMBER_ARRAY_1_SKIPPED^#
     // Same as IMPLICIT_MEMBER_SKIPPED.
diff --git a/test/IDE/complete_default_arguments.swift b/test/IDE/complete_default_arguments.swift
index 20f6300..5e798cc 100644
--- a/test/IDE/complete_default_arguments.swift
+++ b/test/IDE/complete_default_arguments.swift
@@ -19,7 +19,7 @@
 //
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_1 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_2 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT_INTCONTEXT
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_3 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_3 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT_INTCONTEXT
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_4 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT_INTCONTEXT
 
 func freeFuncWithDefaultArgs1(
diff --git a/test/IRGen/big_types_corner_cases.swift b/test/IRGen/big_types_corner_cases.swift
index 07a1836..d51ed3d 100644
--- a/test/IRGen/big_types_corner_cases.swift
+++ b/test/IRGen/big_types_corner_cases.swift
@@ -346,3 +346,11 @@
         return try body(query)
     }
 }
+
+public func foo() -> Optional<(a: Int?, b: Bool, c: (Int?)->BigStruct?)> {
+  return nil
+}
+
+public func dontAssert() {
+  let _ = foo()
+}
diff --git a/test/IRGen/retroactive_conformance_path.swift b/test/IRGen/retroactive_conformance_path.swift
new file mode 100644
index 0000000..3c596cc
--- /dev/null
+++ b/test/IRGen/retroactive_conformance_path.swift
@@ -0,0 +1,42 @@
+// RUN: %empty-directory(%t) 
+// RUN: %target-build-swift -module-name=test %s -o %t/a.out
+// RUN: %target-run %t/a.out | %FileCheck %s
+// REQUIRES: executable_test
+// REQUIRES: CPU=arm64 || CPU=x86_64
+
+// Check that the ASTMangler does not crash when mangling a retroactive conformance
+// and also do a executable test to make sure the code works as expected.
+
+extension Result: RandomAccessCollection, BidirectionalCollection, Collection, Sequence where Success: RandomAccessCollection, Success.Index == Int {
+  public typealias Element = Result<Success.Element, Failure>
+  public typealias Index = Int
+  public var startIndex: Int {
+    switch self {
+      case .success(let array):
+        return array.startIndex
+      case .failure:
+        return 0
+    }
+  }
+   public var endIndex: Int {
+    switch self {
+      case .success(let array):
+        return array.endIndex
+      case .failure:
+        return 1
+    }
+   }
+   public subscript(position: Int) -> Result<Success.Element, Failure> {
+    switch self {
+    case .success(let array):
+      return .success(array[position])
+    case .failure(let error):
+      return .failure(error)
+    }
+   }
+}
+
+let coll: [Int] = [4, 8, 15, 16, 23, 42]
+let result: Result<[Int], Error> = .success(coll)
+// CHECK: success(15)
+print(result[2])
diff --git a/test/NameBinding/scope_map_lookup_extension_extension.swift b/test/NameBinding/scope_map_lookup_extension_extension.swift
new file mode 100644
index 0000000..9c71705
--- /dev/null
+++ b/test/NameBinding/scope_map_lookup_extension_extension.swift
@@ -0,0 +1,6 @@
+// Ensure scope construction does not crash on this illegal code
+// RUN: not %target-swift-frontend -typecheck %s 2> %t.errors
+// RUN: %FileCheck %s <%t.errors
+// CHECK-NOT: Program arguments:
+private extension String {
+  private extension String
diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift
index 888de00..398dfb5 100644
--- a/test/Parse/recovery.swift
+++ b/test/Parse/recovery.swift
@@ -511,7 +511,7 @@
 
 
 struct ErrorInFunctionSignatureResultArrayType11 { // expected-note{{in declaration of 'ErrorInFunctionSignatureResultArrayType11'}}
-  func foo() -> Int[(a){a++}] { // expected-error {{consecutive declarations on a line must be separated by ';'}} {{21-21=;}} expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} expected-error {{expected '{' in body of function declaration}} expected-error {{expected declaration}}
+  func foo() -> Int[(a){a++}] { // expected-error {{consecutive declarations on a line must be separated by ';'}} {{20-20=;}} expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} expected-error {{expected '{' in body of function declaration}} expected-error {{expected declaration}}
   }
 }
 
diff --git a/test/SILGen/Inputs/property_wrapper_defs.swift b/test/SILGen/Inputs/property_wrapper_defs.swift
index 934254d..19ed7ba 100644
--- a/test/SILGen/Inputs/property_wrapper_defs.swift
+++ b/test/SILGen/Inputs/property_wrapper_defs.swift
@@ -16,3 +16,7 @@
 		set { self = newValue }
 	}
 }
+
+public class UsesMyPublished {
+  @MyPublished public var foo: Int = 17
+}
diff --git a/test/SILGen/Inputs/vtables_multifile_2.swift b/test/SILGen/Inputs/vtables_multifile_2.swift
index 1776233..7d15cee 100644
--- a/test/SILGen/Inputs/vtables_multifile_2.swift
+++ b/test/SILGen/Inputs/vtables_multifile_2.swift
@@ -69,7 +69,7 @@
 // VTable thunks for methods of Base redispatch to methods of Derived
 // --
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod1yyFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyFTV : $@convention(method) (@guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod1yyFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyFTV : $@convention(method) (@guaranteed Derived) -> () {
 // CHECK: bb0(%0 : @guaranteed $Derived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %0 : $Derived, #Derived.privateMethod1!1 : (Derived) -> () -> (), $@convention(method) (@guaranteed Derived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0) : $@convention(method) (@guaranteed Derived) -> ()
@@ -77,7 +77,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod2yyyXlSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyyXlFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod2yyyXlSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyyXlFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> () {
 // CHECK: bb0(%0 : @guaranteed $Optional<AnyObject>, %1 : @guaranteed $Derived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $Derived, #Derived.privateMethod2!1 : (Derived) -> (AnyObject?) -> (), $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0, %1) : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> ()
@@ -85,7 +85,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed Derived) -> () {
 // CHECK: bb0(%0 : $Int, %1 : @guaranteed $Derived):
 // CHECK-NEXT:  [[ARG:%.*]] = enum $Optional<Int>, #Optional.some!enumelt.1, %0 : $Int
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $Derived, #Derived.privateMethod3!1 : (Derived) -> (Int?) -> (), $@convention(method) (Optional<Int>, @guaranteed Derived) -> ()
@@ -94,7 +94,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed Derived) -> () {
 // CHECK: bb0(%0 : $*Int, %1 : @guaranteed $Derived):
 // CHECK-NEXT:  [[ARG:%.*]] = load [trivial] %0 : $*Int
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $Derived, #Derived.privateMethod4!1 : (Derived) -> (Int) -> (), $@convention(method) (Int, @guaranteed Derived) -> ()
@@ -114,4 +114,4 @@
 // CHECK-NEXT:  #Derived.privateMethod3!1: (Derived) -> (Int?) -> () : @$s17vtables_multifile12OtherDerivedC14privateMethod3yySiSgF [override]        // OtherDerived.privateMethod3(_:)
 // CHECK-NEXT:  #Derived.privateMethod4!1: (Derived) -> (Int) -> () : @$s17vtables_multifile12OtherDerivedC14privateMethod4yySiF [override]   // OtherDerived.privateMethod4(_:)
 // CHECK-NEXT:  #OtherDerived.deinit!deallocator.1: @$s17vtables_multifile12OtherDerivedCfD   // OtherDerived.__deallocating_deinit
-// CHECK-NEXT:}
\ No newline at end of file
+// CHECK-NEXT:}
diff --git a/test/SILGen/dynamic.swift b/test/SILGen/dynamic.swift
index bbf4476..df139fd 100644
--- a/test/SILGen/dynamic.swift
+++ b/test/SILGen/dynamic.swift
@@ -512,7 +512,7 @@
 // so after re-abstracting the signature we must dispatch to the dynamic
 // thunk.
 
-// CHECK-LABEL: sil private [ossa] @$s7dynamic15ConcreteDerivedC6methodyySiFAA11GenericBaseCADyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed ConcreteDerived) -> ()
+// CHECK-LABEL: sil private [thunk] [ossa] @$s7dynamic15ConcreteDerivedC6methodyySiFAA11GenericBaseCADyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed ConcreteDerived) -> ()
 // CHECK: bb0(%0 : $*Int, %1 : @guaranteed $ConcreteDerived):
 // CHECK-NEXT:  [[VALUE:%.*]] = load [trivial] %0 : $*Int
 // CHECK:       [[DYNAMIC_THUNK:%.*]] = function_ref @$s7dynamic15ConcreteDerivedC6methodyySiFTD : $@convention(method) (Int, @guaranteed ConcreteDerived) -> ()
diff --git a/test/SILGen/property_wrappers.swift b/test/SILGen/property_wrappers.swift
index e5a8802..856c3c6 100644
--- a/test/SILGen/property_wrappers.swift
+++ b/test/SILGen/property_wrappers.swift
@@ -495,6 +495,29 @@
   }
 }
 
+// rdar://problem/55982409 - crash due to improperly inferred 'final'
+@propertyWrapper
+public struct MyWrapper<T> {
+  public var wrappedValue: T
+  public var projectedValue: Self { self }
+  public init(wrappedValue: T) { self.wrappedValue = wrappedValue }
+}
+
+open class TestMyWrapper {
+  public init() {}
+  @MyWrapper open var useMyWrapper: Int? = nil
+}
+
+// rdar://problem/54352235 - crash due to reference to private backing var
+extension UsesMyPublished {
+  // CHECK-LABEL: sil hidden [ossa] @$s21property_wrapper_defs15UsesMyPublishedC0A9_wrappersE6setFooyySiF : $@convention(method) (Int, @guaranteed UsesMyPublished) -> ()
+  // CHECK: class_method %1 : $UsesMyPublished, #UsesMyPublished.foo!setter.1
+  // CHECK-NOT: assign_by_wrapper
+  // CHECK: return
+  func setFoo(_ x: Int) {
+    foo = x
+  }
+}
 
 // CHECK-LABEL: sil_vtable ClassUsingWrapper {
 // CHECK-NEXT:  #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg   // ClassUsingWrapper.x.getter
@@ -503,3 +526,6 @@
 // CHECK-NEXT:  #ClassUsingWrapper.init!allocator.1: (ClassUsingWrapper.Type) -> () -> ClassUsingWrapper : @$s17property_wrappers17ClassUsingWrapperCACycfC
 // CHECK-NEXT: #ClassUsingWrapper.deinit!deallocator.1: @$s17property_wrappers17ClassUsingWrapperCfD
 // CHECK-NEXT:  }
+
+// CHECK-LABEL: sil_vtable [serialized] TestMyWrapper
+// CHECK: #TestMyWrapper.$useMyWrapper!getter.1
diff --git a/test/SILGen/property_wrappers_library_evolution.swift b/test/SILGen/property_wrappers_library_evolution.swift
new file mode 100644
index 0000000..09f750c
--- /dev/null
+++ b/test/SILGen/property_wrappers_library_evolution.swift
@@ -0,0 +1,10 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -o %t -enable-library-evolution %S/Inputs/property_wrapper_defs.swift
+// RUN: %target-swift-emit-silgen -primary-file %s -I %t -enable-library-evolution
+import property_wrapper_defs
+
+// rdar://problem/55995892
+// This is a crash that occurs only with -enable-library-evolution.
+
+public enum E { case a }
+struct M { @MyPublished private var e = E.a }
diff --git a/test/SILGen/vtable_thunks.swift b/test/SILGen/vtable_thunks.swift
index fad2c18..4f02d7e 100644
--- a/test/SILGen/vtable_thunks.swift
+++ b/test/SILGen/vtable_thunks.swift
@@ -142,7 +142,7 @@
 // This test is incorrect in semantic SIL today. But it will be fixed in
 // forthcoming commits.
 //
-// CHECK-LABEL: sil private [ossa] @$s13vtable_thunks1DC3iuo{{[_0-9a-zA-Z]*}}FTV
+// CHECK-LABEL: sil private [thunk] [ossa] @$s13vtable_thunks1DC3iuo{{[_0-9a-zA-Z]*}}FTV
 // CHECK: bb0([[X:%.*]] : @guaranteed $B, [[Y:%.*]] : @guaranteed $Optional<B>, [[Z:%.*]] : @guaranteed $B, [[W:%.*]] : @guaranteed $D):
 // CHECK:   [[WRAP_X:%.*]] = enum $Optional<B>, #Optional.some!enumelt.1, [[X]] : $B
 // CHECK:   [[Y_COPY:%.*]] = copy_value [[Y]]
@@ -160,7 +160,7 @@
 // CHECK:   [[WRAP_RES:%.*]] = enum $Optional<B>, {{.*}} [[RES]]
 // CHECK:   return [[WRAP_RES]]
 
-// CHECK-LABEL: sil private [ossa] @$s13vtable_thunks1DC1g{{[_0-9a-zA-Z]*}}FTV
+// CHECK-LABEL: sil private [thunk] [ossa] @$s13vtable_thunks1DC1g{{[_0-9a-zA-Z]*}}FTV
 // TODO: extra copies here
 // CHECK:         [[WRAPPED_X_ADDR:%.*]] = init_enum_data_addr [[WRAP_X_ADDR:%.*]] :
 // CHECK:         copy_addr [take] {{%.*}} to [initialization] [[WRAPPED_X_ADDR]]
@@ -228,11 +228,11 @@
   override func map() -> (S?) -> () -> Noot {}
 }
 
-// CHECK-LABEL: sil private [ossa] @$s13vtable_thunks3BarC3foo{{[_0-9a-zA-Z]*}}FTV : $@convention(method) (@guaranteed @callee_guaranteed (Int) -> Int, @guaranteed Bar) -> @owned Optional<@callee_guaranteed (Int) -> Int>
+// CHECK-LABEL: sil private [thunk] [ossa] @$s13vtable_thunks3BarC3foo{{[_0-9a-zA-Z]*}}FTV : $@convention(method) (@guaranteed @callee_guaranteed (Int) -> Int, @guaranteed Bar) -> @owned Optional<@callee_guaranteed (Int) -> Int>
 // CHECK:         [[IMPL:%.*]] = function_ref @$s13vtable_thunks3BarC3foo{{[_0-9a-zA-Z]*}}F
 // CHECK:         apply [[IMPL]]
 
-// CHECK-LABEL: sil private [ossa] @$s13vtable_thunks4NootC4flip{{[_0-9a-zA-Z]*}}FTV
+// CHECK-LABEL: sil private [thunk] [ossa] @$s13vtable_thunks4NootC4flip{{[_0-9a-zA-Z]*}}FTV
 // CHECK:         [[IMPL:%.*]] = function_ref @$s13vtable_thunks4NootC4flip{{[_0-9a-zA-Z]*}}F
 // CHECK:         [[INNER:%.*]] = apply %1(%0)
 // CHECK:         [[THUNK:%.*]] = function_ref @$s13vtable_thunks1SVIegd_ACSgIegd_TR
@@ -244,7 +244,7 @@
 // CHECK:         [[OUTER:%.*]] = enum $Optional<S>, #Optional.some!enumelt.1, [[INNER]] : $S
 // CHECK:         return [[OUTER]] : $Optional<S>
 
-// CHECK-LABEL: sil private [ossa] @$s13vtable_thunks4NootC3map{{[_0-9a-zA-Z]*}}FTV
+// CHECK-LABEL: sil private [thunk] [ossa] @$s13vtable_thunks4NootC3map{{[_0-9a-zA-Z]*}}FTV
 // CHECK:         [[IMPL:%.*]] = function_ref @$s13vtable_thunks4NootC3map{{[_0-9a-zA-Z]*}}F
 // CHECK:         [[INNER:%.*]] = apply %1(%0)
 // CHECK:         [[THUNK:%.*]] = function_ref @$s13vtable_thunks1SVSgAA4NootCIego_Iegyo_AcA3AapCSgIego_Iegyo_TR
diff --git a/test/SILGen/vtable_thunks_reabstraction_modify.swift b/test/SILGen/vtable_thunks_reabstraction_modify.swift
index a521cd1..d8c6409 100644
--- a/test/SILGen/vtable_thunks_reabstraction_modify.swift
+++ b/test/SILGen/vtable_thunks_reabstraction_modify.swift
@@ -15,7 +15,7 @@
   }
 }
 
-// CHECK-LABEL: sil private [ossa] @$s34vtable_thunks_reabstraction_modify12DerivedClassC8callbackyxSicvMAA04BaseF0CADyq_xcvMTV : $@yield_once @convention(method) <Result> (@guaranteed DerivedClass<Result>) -> @yields @inout @callee_guaranteed (@in_guaranteed Int) -> @out Result {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s34vtable_thunks_reabstraction_modify12DerivedClassC8callbackyxSicvMAA04BaseF0CADyq_xcvMTV : $@yield_once @convention(method) <Result> (@guaranteed DerivedClass<Result>) -> @yields @inout @callee_guaranteed (@in_guaranteed Int) -> @out Result {
 // CHECK: [[DERIVED:%.*]] = function_ref @$s34vtable_thunks_reabstraction_modify12DerivedClassC8callbackyxSicvM : $@yield_once @convention(method) <τ_0_0> (@guaranteed DerivedClass<τ_0_0>) -> @yields @inout @callee_guaranteed (Int) -> @out τ_0_0
 // CHECK: ([[RESULT_BUF:%.*]], [[TOKEN:%.*]]) = begin_apply [[DERIVED]]<Result>(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed DerivedClass<τ_0_0>) -> @yields @inout @callee_guaranteed (Int) -> @out τ_0_0
 // CHECK: [[OUTER_RESULT_BUF:%.*]] = alloc_stack $@callee_guaranteed (@in_guaranteed Int) -> @out Result
@@ -32,4 +32,4 @@
 // CHECK: store [[THUNK]] to [init] [[RESULT_BUF]] : $*@callee_guaranteed (Int) -> @out Result
 // CHECK: dealloc_stack [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out Result
 // CHECK: end_apply [[TOKEN]]
-// CHECK: return
\ No newline at end of file
+// CHECK: return
diff --git a/test/SILGen/vtables_multifile.swift b/test/SILGen/vtables_multifile.swift
index dbef5bf..9a19262 100644
--- a/test/SILGen/vtables_multifile.swift
+++ b/test/SILGen/vtables_multifile.swift
@@ -49,7 +49,7 @@
 // vtable slot for the more visible method.
 // --
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod1yyFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyFTV : $@convention(method) (@guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod1yyFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyFTV : $@convention(method) (@guaranteed Derived) -> () {
 // CHECK: bb0(%0 : @guaranteed $Derived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %0 : $Derived, #Derived.privateMethod1!1 : (Derived) -> () -> (), $@convention(method) (@guaranteed Derived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0) : $@convention(method) (@guaranteed Derived) -> ()
@@ -57,7 +57,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod2yyyXlSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyyXlFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod2yyyXlSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyyXlFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> () {
 // CHECK: bb0(%0 : @guaranteed $Optional<AnyObject>, %1 : @guaranteed $Derived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $Derived, #Derived.privateMethod2!1 : (Derived) -> (AnyObject?) -> (), $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0, %1) : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed Derived) -> ()
@@ -65,7 +65,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed Derived) -> () {
 // CHECK: bb0(%0 : $Int, %1 : @guaranteed $Derived):
 // CHECK-NEXT:  [[ARG:%.*]] = enum $Optional<Int>, #Optional.some!enumelt.1, %0 : $Int
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $Derived, #Derived.privateMethod3!1 : (Derived) -> (Int?) -> (), $@convention(method) (Optional<Int>, @guaranteed Derived) -> ()
@@ -74,7 +74,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile7DerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed Derived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile7DerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed Derived) -> () {
 // CHECK: bb0(%0 : $*Int, %1 : @guaranteed $Derived):
 // CHECK-NEXT:  [[ARG:%.*]] = load [trivial] %0 : $*Int
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $Derived, #Derived.privateMethod4!1 : (Derived) -> (Int) -> (), $@convention(method) (Int, @guaranteed Derived) -> ()
@@ -88,7 +88,7 @@
 // so it overrides both with thunks that dispatch to methods of MoreDerived.
 // --
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod1yyFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyFTV : $@convention(method) (@guaranteed MoreDerived) -> ()
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod1yyFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyFTV : $@convention(method) (@guaranteed MoreDerived) -> ()
 // CHECK: bb0(%0 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %0 : $MoreDerived, #MoreDerived.privateMethod1!1 : (MoreDerived) -> () -> (), $@convention(method) (@guaranteed MoreDerived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0) : $@convention(method) (@guaranteed MoreDerived) -> ()
@@ -96,7 +96,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod2yyyXlSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyyXlFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod2yyyXlSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyyXlFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : @guaranteed $Optional<AnyObject>, %1 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $MoreDerived, #MoreDerived.privateMethod2!1 : (MoreDerived) -> (AnyObject?) -> (), $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0, %1) : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> ()
@@ -104,7 +104,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : $Int, %1 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[ARG:%.*]] = enum $Optional<Int>, #Optional.some!enumelt.1, %0 : $Int
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $MoreDerived, #MoreDerived.privateMethod3!1 : (MoreDerived) -> (Int?) -> (), $@convention(method) (Optional<Int>, @guaranteed MoreDerived) -> ()
@@ -113,7 +113,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : $*Int, %1 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[ARG:%.*]] = load [trivial] %0 : $*Int
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $MoreDerived, #MoreDerived.privateMethod4!1 : (MoreDerived) -> (Int) -> (), $@convention(method) (Int, @guaranteed MoreDerived) -> ()
@@ -126,7 +126,7 @@
 // Thunks override methods of Derived as well.
 // --
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod1yyFAA0D0CADyyFTV : $@convention(method) (@guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod1yyFAA0D0CADyyFTV : $@convention(method) (@guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %0 : $MoreDerived, #MoreDerived.privateMethod1!1 : (MoreDerived) -> () -> (), $@convention(method) (@guaranteed MoreDerived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0) : $@convention(method) (@guaranteed MoreDerived) -> ()
@@ -134,7 +134,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod2yyyXlSgFAA0D0CADyyAEFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod2yyyXlSgFAA0D0CADyyAEFTV : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : @guaranteed $Optional<AnyObject>, %1 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $MoreDerived, #MoreDerived.privateMethod2!1 : (MoreDerived) -> (AnyObject?) -> (), $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0, %1) : $@convention(method) (@guaranteed Optional<AnyObject>, @guaranteed MoreDerived) -> ()
@@ -142,7 +142,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: il private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod3yySiSgFAA0D0CADyyAEFTV : $@convention(method) (Optional<Int>, @guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod3yySiSgFAA0D0CADyyAEFTV : $@convention(method) (Optional<Int>, @guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : $Optional<Int>, %1 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $MoreDerived, #MoreDerived.privateMethod3!1 : (MoreDerived) -> (Int?) -> (), $@convention(method) (Optional<Int>, @guaranteed MoreDerived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0, %1) : $@convention(method) (Optional<Int>, @guaranteed MoreDerived) -> ()
@@ -150,7 +150,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod4yySiFAA0D0CADyySiFTV : $@convention(method) (Int, @guaranteed MoreDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile11MoreDerivedC14privateMethod4yySiFAA0D0CADyySiFTV : $@convention(method) (Int, @guaranteed MoreDerived) -> () {
 // CHECK: bb0(%0 : $Int, %1 : @guaranteed $MoreDerived):
 // CHECK-NEXT:  [[METHOD:%.*]] = class_method %1 : $MoreDerived, #MoreDerived.privateMethod4!1 : (MoreDerived) -> (Int) -> (), $@convention(method) (Int, @guaranteed MoreDerived) -> ()
 // CHECK-NEXT:  apply [[METHOD]](%0, %1) : $@convention(method) (Int, @guaranteed MoreDerived) -> ()
@@ -163,7 +163,7 @@
 // visible.
 // --
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile12FinalDerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed FinalDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile12FinalDerivedC14privateMethod3yySiSgFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyySiFTV : $@convention(method) (Int, @guaranteed FinalDerived) -> () {
 // CHECK: bb0(%0 : $Int, %1 : @guaranteed $FinalDerived):
 // CHECK-NEXT:  [[ARG:%.*]] = enum $Optional<Int>, #Optional.some!enumelt.1, %0 : $Int // user: %4
 // CHECK:       [[METHOD:%.*]] = function_ref @$s17vtables_multifile12FinalDerivedC14privateMethod3yySiSgF : $@convention(method) (Optional<Int>, @guaranteed FinalDerived) -> ()
@@ -172,7 +172,7 @@
 // CHECK-NEXT:  return [[RESULT]] : $()
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil private [ossa] @$s17vtables_multifile12FinalDerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed FinalDerived) -> () {
+// CHECK-LABEL: sil private [thunk] [ossa] @$s17vtables_multifile12FinalDerivedC14privateMethod4yySiFAA4BaseCAD33_63E5F2521A3C787F5F9EFD57FB9237EALLyyxFTV : $@convention(method) (@in_guaranteed Int, @guaranteed FinalDerived) -> () {
 // CHECK: bb0(%0 : $*Int, %1 : @guaranteed $FinalDerived):
 // CHECK-NEXT:  [[ARG:%.*]] = load [trivial] %0 : $*Int
 // CHECK:       [[METHOD:%.*]] = function_ref @$s17vtables_multifile12FinalDerivedC14privateMethod4yySiF : $@convention(method) (Int, @guaranteed FinalDerived) -> ()
diff --git a/test/SILOptimizer/constant_evaluator_skip_test.sil b/test/SILOptimizer/constant_evaluator_skip_test.sil
index eda794b..83a52da 100644
--- a/test/SILOptimizer/constant_evaluator_skip_test.sil
+++ b/test/SILOptimizer/constant_evaluator_skip_test.sil
@@ -93,7 +93,7 @@
   %10 = builtin "cmp_slt_Int32"(%8 : $Builtin.Int32, %9 : $Builtin.Int32) : $Builtin.Int1
   cond_br %10, bb2, bb3
     // CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: branch depends on non-constant value produced by an unevaluated instructions
-    // CHECK: {{.*}}: note: value mutable by an unevaluated instruction is not a constant
+    // CHECK: {{.*}}: note: result of an unevaluated instruction is not a constant
 bb2:
   br bb4
 
diff --git a/test/SILOptimizer/constant_evaluator_test.sil b/test/SILOptimizer/constant_evaluator_test.sil
index ff36c9c..5d1ea31 100644
--- a/test/SILOptimizer/constant_evaluator_test.sil
+++ b/test/SILOptimizer/constant_evaluator_test.sil
@@ -449,7 +449,7 @@
 sil hidden @interpretAndDiagnoseNonConstantVars : $@convention(thin) (Int) -> () {
 bb0(%0 : $Int):
   %4 = struct_extract %0 : $Int, #Int._value
-    // CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: cannot evaluate expression as constant here
+    // CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: encountered use of a variable not tracked by the evaluator
   %10 = tuple ()
   return %10 : $()
 }
diff --git a/test/SILOptimizer/di_property_wrappers.swift b/test/SILOptimizer/di_property_wrappers.swift
index 0c65a4e..46e5337 100644
--- a/test/SILOptimizer/di_property_wrappers.swift
+++ b/test/SILOptimizer/di_property_wrappers.swift
@@ -422,6 +422,57 @@
   // CHECK-NEXT: .. init Wrapper2<Int>(wrappedValue: 17)
 }
 
+// SR-11477
+
+@propertyWrapper
+struct SR_11477_W {
+  let name: String
+
+  init(name: String = "DefaultParamInit") {
+    self.name = name
+  }
+
+  var wrappedValue: Int {
+    get { return 0 }
+  }
+}
+
+@propertyWrapper
+ struct SR_11477_W1 {
+   let name: String
+
+   init() {
+     self.name = "Init"
+   }
+
+   init(name: String = "DefaultParamInit") {
+     self.name = name
+   }
+
+   var wrappedValue: Int {
+     get { return 0 }
+   }
+ }
+
+struct SR_11477_C {
+  @SR_11477_W var property: Int
+  @SR_11477_W1 var property1: Int
+
+  init() {}
+  func foo() { print(_property.name) }
+  func foo1() { print(_property1.name) }
+}
+
+func testWrapperInitWithDefaultArg() {
+  // CHECK: ## InitWithDefaultArg
+  print("\n## InitWithDefaultArg")
+  let use = SR_11477_C()
+  
+  use.foo()
+  use.foo1()
+  // CHECK-NEXT: DefaultParamInit
+  // CHECK-NEXT: Init
+}
 
 testIntStruct()
 testIntClass()
@@ -431,3 +482,4 @@
 testOptIntStruct()
 testDefaultNilOptIntStruct()
 testComposed()
+testWrapperInitWithDefaultArg()
diff --git a/test/SILOptimizer/di_property_wrappers_errors.swift b/test/SILOptimizer/di_property_wrappers_errors.swift
index d4d507c..e1422c0 100644
--- a/test/SILOptimizer/di_property_wrappers_errors.swift
+++ b/test/SILOptimizer/di_property_wrappers_errors.swift
@@ -46,3 +46,23 @@
   } // expected-error{{return from initializer without initializing all stored properties}}
   // expected-note@-1{{'self.wrapped' not initialized}}  
 }
+
+// SR_11477
+
+@propertyWrapper
+struct SR_11477_W {
+  let name: String
+
+  init<T: ExpressibleByIntegerLiteral>(_ value: T = 0) {
+    self.name = "Init"
+  }
+
+  var wrappedValue: Int {
+    get { return 0 }
+  }
+}
+
+struct SR_11477_S {
+  @SR_11477_W var foo: Int
+  init() {} // expected-error {{return from initializer without initializing all stored properties}} expected-note {{'self.foo' not initialized}}
+}
diff --git a/test/SILOptimizer/ownership_model_eliminator.sil b/test/SILOptimizer/ownership_model_eliminator.sil
index 1682a91..b17a8af 100644
--- a/test/SILOptimizer/ownership_model_eliminator.sil
+++ b/test/SILOptimizer/ownership_model_eliminator.sil
@@ -321,7 +321,7 @@
 
 // CHECK-LABEL: sil [canonical] @test_simplify_instruction : $@convention(thin) (@owned Builtin.NativeObject, Builtin.Int32) -> @owned Builtin.NativeObject {
 // CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject,
-// CHECK-NEXT:   return [[ARG]]
+// CHECK:   return [[ARG]]
 // CHECK: } // end sil function 'test_simplify_instruction'
 sil [canonical] [ossa] @test_simplify_instruction : $@convention(thin) (@owned Builtin.NativeObject, Builtin.Int32) -> @owned Builtin.NativeObject {
 bb0(%0 : @owned $Builtin.NativeObject, %1 : $Builtin.Int32):
@@ -329,3 +329,16 @@
   (%3, %4) = destructure_tuple %2 : $(Builtin.NativeObject, Builtin.Int32)
   return %3 : $Builtin.NativeObject
 }
+
+// Just make sure that we do not crash on this function.
+//
+// CHECK-LABEL: sil @do_not_crash_due_to_debug_value_use : $@convention(thin) (Builtin.Int32, Builtin.Int32) -> () {
+// CHECK: } // end sil function 'do_not_crash_due_to_debug_value_use'
+sil [ossa] @do_not_crash_due_to_debug_value_use : $@convention(thin) (Builtin.Int32, Builtin.Int32) -> () {
+bb0(%0a : $Builtin.Int32, %0b : $Builtin.Int32):
+  %0 = tuple(%0a : $Builtin.Int32, %0b : $Builtin.Int32)
+  (%1, %2) = destructure_tuple %0 : $(Builtin.Int32, Builtin.Int32)
+  debug_value %0 : $(Builtin.Int32, Builtin.Int32), let, name "myName2"
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/Serialization/Inputs/comments-batch/File1.swift b/test/Serialization/Inputs/comments-batch/File1.swift
new file mode 100644
index 0000000..7c9059e
--- /dev/null
+++ b/test/Serialization/Inputs/comments-batch/File1.swift
@@ -0,0 +1,2 @@
+/// Comment in File1
+public func FuncFromFile1() {}
\ No newline at end of file
diff --git a/test/Serialization/Inputs/comments-batch/File2.swift b/test/Serialization/Inputs/comments-batch/File2.swift
new file mode 100644
index 0000000..f42a2e8
--- /dev/null
+++ b/test/Serialization/Inputs/comments-batch/File2.swift
@@ -0,0 +1,2 @@
+/// Comment in File2
+public func FuncFromFile2() {}
\ No newline at end of file
diff --git a/test/Serialization/Inputs/comments-batch/File3.swift b/test/Serialization/Inputs/comments-batch/File3.swift
new file mode 100644
index 0000000..89a12ff
--- /dev/null
+++ b/test/Serialization/Inputs/comments-batch/File3.swift
@@ -0,0 +1,2 @@
+/// Comment in File3
+public func FuncFromFile3() {}
\ No newline at end of file
diff --git a/test/Serialization/Inputs/comments-batch/File4.swift b/test/Serialization/Inputs/comments-batch/File4.swift
new file mode 100644
index 0000000..16917c5
--- /dev/null
+++ b/test/Serialization/Inputs/comments-batch/File4.swift
@@ -0,0 +1,2 @@
+/// Comment in File4
+public func FuncFromFile4() {}
\ No newline at end of file
diff --git a/test/Serialization/Inputs/comments-batch/File5.swift b/test/Serialization/Inputs/comments-batch/File5.swift
new file mode 100644
index 0000000..793b825
--- /dev/null
+++ b/test/Serialization/Inputs/comments-batch/File5.swift
@@ -0,0 +1,2 @@
+/// Comment in File5
+public func FuncFromFile5() {}
\ No newline at end of file
diff --git a/test/Serialization/Inputs/def_comments.swift b/test/Serialization/Inputs/def_comments.swift
index 98ce6f3..69cd450 100644
--- a/test/Serialization/Inputs/def_comments.swift
+++ b/test/Serialization/Inputs/def_comments.swift
@@ -1,3 +1,31 @@
 /// second_decl_class_1 Aaa.
 public class second_decl_class_1 {
 }
+
+public struct second_decl_struct_1 {
+    public var instanceVar: Int {
+        get { return 1 }
+        set {}
+    }
+    public enum NestedEnum {}
+    public typealias NestedTypealias = Int
+}
+
+public enum second_decl_enum_1 {
+    case Case1
+    case Case2(Int)
+}
+
+public class second_decl_class_2 {
+    public init() {}
+}
+
+public protocol second_decl_protocol_1 {
+    associatedtype NestedTypealias
+    subscript(i: Int) -> Double { get set }
+}
+
+public var (decl_var_2, decl_var_3): (Int, Float) = (1, 1.0)
+
+#sourceLocation(file:"NonExistingSource.swift", line:100000)
+public func functionAfterPoundSourceLoc() {}
diff --git a/test/Serialization/comments-batch-mode.swift b/test/Serialization/comments-batch-mode.swift
new file mode 100644
index 0000000..2929590
--- /dev/null
+++ b/test/Serialization/comments-batch-mode.swift
@@ -0,0 +1,13 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -enable-batch-mode -emit-module -emit-module-doc -emit-module-path %t/Foo.swiftmodule %S/Inputs/comments-batch/File1.swift %S/Inputs/comments-batch/File2.swift %S/Inputs/comments-batch/File3.swift %S/Inputs/comments-batch/File4.swift %S/Inputs/comments-batch/File5.swift -module-name Foo -emit-module-source-info-path %t/Foo.swiftsourceinfo -emit-module-doc-path %t/Foo.swiftdoc
+// RUN: %target-swift-ide-test -print-module-comments -module-to-print=Foo -source-filename %s -I %t | %FileCheck %s
+
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -wmo -emit-module -emit-module-doc -emit-module-path %t/Foo.swiftmodule %S/Inputs/comments-batch/File1.swift %S/Inputs/comments-batch/File2.swift %S/Inputs/comments-batch/File3.swift %S/Inputs/comments-batch/File4.swift %S/Inputs/comments-batch/File5.swift -module-name Foo -emit-module-source-info-path %t/Foo.swiftsourceinfo -emit-module-doc-path %t/Foo.swiftdoc
+// RUN: %target-swift-ide-test -print-module-comments -module-to-print=Foo -source-filename %s -I %t | %FileCheck %s
+
+// CHECK: Inputs/comments-batch/File1.swift:2:13: Func/FuncFromFile1 RawComment=[/// Comment in File1\n]
+// CHECK: Inputs/comments-batch/File2.swift:2:13: Func/FuncFromFile2 RawComment=[/// Comment in File2\n]
+// CHECK: Inputs/comments-batch/File3.swift:2:13: Func/FuncFromFile3 RawComment=[/// Comment in File3\n]
+// CHECK: Inputs/comments-batch/File4.swift:2:13: Func/FuncFromFile4 RawComment=[/// Comment in File4\n]
+// CHECK: Inputs/comments-batch/File5.swift:2:13: Func/FuncFromFile5 RawComment=[/// Comment in File5\n]
diff --git a/test/Serialization/comments-framework.swift b/test/Serialization/comments-framework.swift
index 2c0d446..dbce0ec 100644
--- a/test/Serialization/comments-framework.swift
+++ b/test/Serialization/comments-framework.swift
@@ -1,7 +1,8 @@
 // RUN: %empty-directory(%t)
 // RUN: %empty-directory(%t/comments.framework/Modules/comments.swiftmodule)
+// RUN: %empty-directory(%t/comments.framework/Modules/comments.swiftmodule/Project)
 
-// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.framework/Modules/comments.swiftmodule/%target-swiftmodule-name -emit-module-doc-path %t/comments.framework/Modules/comments.swiftmodule/%target-swiftdoc-name %s
+// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.framework/Modules/comments.swiftmodule/%target-swiftmodule-name -emit-module-doc-path %t/comments.framework/Modules/comments.swiftmodule/%target-swiftdoc-name -emit-module-source-info-path %t/comments.framework/Modules/comments.swiftmodule/Project/%target-swiftsourceinfo-name %s
 // RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -source-filename %s -F %t | %FileCheck %s
 
 // RUN: cp -r %t/comments.framework/Modules/comments.swiftmodule %t/comments.swiftmodule
@@ -23,8 +24,8 @@
   public func decl_func_3() {}
 }
 
-// CHECK: Class/first_decl_class_1 RawComment=[/// first_decl_class_1 Aaa.\n]
-// CHECK: Func/first_decl_class_1.decl_func_1 RawComment=[/// decl_func_1 Aaa.\n]
-// CHECK: Func/first_decl_class_1.decl_func_2 RawComment=[/**\n   * decl_func_3 Aaa.\n   */]
-// CHECK: Func/first_decl_class_1.decl_func_3 RawComment=[/// decl_func_3 Aaa.\n/** Bbb. */]
+// CHECK: comments-framework.swift:12:14: Class/first_decl_class_1 RawComment=[/// first_decl_class_1 Aaa.\n]
+// CHECK: comments-framework.swift:15:15: Func/first_decl_class_1.decl_func_1 RawComment=[/// decl_func_1 Aaa.\n]
+// CHECK: comments-framework.swift:20:15: Func/first_decl_class_1.decl_func_2 RawComment=[/**\n   * decl_func_3 Aaa.\n   */]
+// CHECK: comments-framework.swift:24:15: Func/first_decl_class_1.decl_func_3 RawComment=[/// decl_func_3 Aaa.\n/** Bbb. */]
 
diff --git a/test/Serialization/comments-hidden.swift b/test/Serialization/comments-hidden.swift
index e4b6580..bb8bfa5 100644
--- a/test/Serialization/comments-hidden.swift
+++ b/test/Serialization/comments-hidden.swift
@@ -14,6 +14,13 @@
 // RUN: %FileCheck %s -check-prefix=TESTING < %t.testing.txt
 // RUN: %FileCheck %s -check-prefix=TESTING-NEGATIVE < %t.testing.txt
 
+// Test the case when we have .swiftsourceinfo
+//
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -enable-testing -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s
+// RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -source-filename %s -I %t > %t.testing.txt
+// RUN: %FileCheck %s -check-prefix=SOURCE-LOC < %t.testing.txt
+
 /// PublicClass Documentation
 public class PublicClass {
   /// Public Function Documentation
@@ -73,4 +80,9 @@
 // TESTING: InternalClass Documentation
 // TESTING: Internal Function Documentation
 
-
+// SOURCE-LOC: comments-hidden.swift:37:15: Func/PublicClass.__UnderscoredPublic RawComment=none BriefComment=none DocCommentAsXML=none
+// SOURCE-LOC: comments-hidden.swift:39:10: Constructor/PublicClass.init RawComment=none BriefComment=none DocCommentAsXML=none
+// SOURCE-LOC: comments-hidden.swift:41:10: Subscript/PublicClass.subscript RawComment=none BriefComment=none DocCommentAsXML=none
+// SOURCE-LOC: comments-hidden.swift:43:10: Constructor/PublicClass.init RawComment=none BriefComment=none DocCommentAsXML=none
+// SOURCE-LOC: comments-hidden.swift:45:10: Subscript/PublicClass.subscript RawComment=none BriefComment=none DocCommentAsXML=none
+// SOURCE-LOC: comments-hidden.swift:50:15: Func/-= RawComment=none BriefComment=none DocCommentAsXML=none
diff --git a/test/Serialization/comments.swift b/test/Serialization/comments.swift
index 1a3d589..9e06002 100644
--- a/test/Serialization/comments.swift
+++ b/test/Serialization/comments.swift
@@ -1,19 +1,21 @@
 // Test the case when we have a single file in a module.
 //
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc %s
+// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s
 // RUN: llvm-bcanalyzer %t/comments.swiftmodule | %FileCheck %s -check-prefix=BCANALYZER
 // RUN: llvm-bcanalyzer %t/comments.swiftdoc | %FileCheck %s -check-prefix=BCANALYZER
+// RUN: llvm-bcanalyzer %t/comments.swiftsourceinfo | %FileCheck %s -check-prefix=BCANALYZER
 // RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -source-filename %s -I %t | %FileCheck %s -check-prefix=FIRST
 
 // Test the case when we have a multiple files in a module.
 //
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/first.swiftmodule -emit-module-doc -emit-module-doc-path %t/first.swiftdoc -primary-file %s %S/Inputs/def_comments.swift
-// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/second.swiftmodule -emit-module-doc -emit-module-doc-path %t/second.swiftdoc %s -primary-file %S/Inputs/def_comments.swift
-// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc %t/first.swiftmodule %t/second.swiftmodule
+// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/first.swiftmodule -emit-module-doc -emit-module-doc-path %t/first.swiftdoc -primary-file %s %S/Inputs/def_comments.swift -emit-module-source-info-path %t/first.swiftsourceinfo
+// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/second.swiftmodule -emit-module-doc -emit-module-doc-path %t/second.swiftdoc %s -primary-file %S/Inputs/def_comments.swift -emit-module-source-info-path %t/second.swiftsourceinfo
+// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc %t/first.swiftmodule %t/second.swiftmodule -emit-module-source-info-path %t/comments.swiftsourceinfo
 // RUN: llvm-bcanalyzer %t/comments.swiftmodule | %FileCheck %s -check-prefix=BCANALYZER
 // RUN: llvm-bcanalyzer %t/comments.swiftdoc | %FileCheck %s -check-prefix=BCANALYZER
+// RUN: llvm-bcanalyzer %t/comments.swiftsourceinfo | %FileCheck %s -check-prefix=BCANALYZER
 // RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -source-filename %s -I %t > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=FIRST < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=SECOND < %t.printed.txt
@@ -58,14 +60,41 @@
 /// Comment for no member extension
 extension first_decl_class_1 : P1 {}
 
-// FIRST: Class/first_decl_generic_class_1 RawComment=[/// first_decl_generic_class_1 Aaa.\n]
-// FIRST: Destructor/first_decl_generic_class_1.deinit RawComment=[/// deinit of first_decl_generic_class_1 Aaa.\n]
-// FIRST: Class/first_decl_class_1 RawComment=[/// first_decl_class_1 Aaa.\n]
-// FIRST: Func/first_decl_class_1.decl_func_1 RawComment=[/// decl_func_1 Aaa.\n]
-// FIRST: Func/first_decl_class_1.decl_func_2 RawComment=[/**\n   * decl_func_3 Aaa.\n   */]
-// FIRST: Func/first_decl_class_1.decl_func_3 RawComment=[/// decl_func_3 Aaa.\n/** Bbb. */]
+// FIRST: comments.swift:26:14: Class/first_decl_generic_class_1 RawComment=[/// first_decl_generic_class_1 Aaa.\n]
+// FIRST: comments.swift:28:3: Destructor/first_decl_generic_class_1.deinit RawComment=[/// deinit of first_decl_generic_class_1 Aaa.\n]
+// FIRST: comments.swift:33:14: Class/first_decl_class_1 RawComment=[/// first_decl_class_1 Aaa.\n]
+// FIRST: comments.swift:36:15: Func/first_decl_class_1.decl_func_1 RawComment=[/// decl_func_1 Aaa.\n]
+// FIRST: comments.swift:41:15: Func/first_decl_class_1.decl_func_2 RawComment=[/**\n   * decl_func_3 Aaa.\n   */]
+// FIRST: comments.swift:45:15: Func/first_decl_class_1.decl_func_3 RawComment=[/// decl_func_3 Aaa.\n/** Bbb. */]
 
-// SECOND: Extension/ RawComment=[/// Comment for bar1\n] BriefComment=[Comment for bar1]
-// SECOND: Extension/ RawComment=[/// Comment for bar2\n] BriefComment=[Comment for bar2]
-// SECOND: Extension/ RawComment=[/// Comment for no member extension\n] BriefComment=[Comment for no member extension]
-// SECOND: Class/second_decl_class_1 RawComment=[/// second_decl_class_1 Aaa.\n]
+// SECOND: comments.swift:49:1: Extension/ RawComment=[/// Comment for bar1\n] BriefComment=[Comment for bar1]
+// SECOND: comments.swift:54:1: Extension/ RawComment=[/// Comment for bar2\n] BriefComment=[Comment for bar2]
+// SECOND: comments.swift:61:1: Extension/ RawComment=[/// Comment for no member extension\n] BriefComment=[Comment for no member extension]
+// SECOND: Inputs/def_comments.swift:2:14: Class/second_decl_class_1 RawComment=[/// second_decl_class_1 Aaa.\n]
+// SECOND: Inputs/def_comments.swift:5:15: Struct/second_decl_struct_1
+// SECOND: Inputs/def_comments.swift:7:9: Accessor/second_decl_struct_1.<getter for second_decl_struct_1.instanceVar>
+// SECOND: Inputs/def_comments.swift:8:9: Accessor/second_decl_struct_1.<setter for second_decl_struct_1.instanceVar>
+// SECOND: Inputs/def_comments.swift:10:17: Enum/second_decl_struct_1.NestedEnum
+// SECOND: Inputs/def_comments.swift:11:22: TypeAlias/second_decl_struct_1.NestedTypealias
+// SECOND: Inputs/def_comments.swift:14:13: Enum/second_decl_enum_1
+// SECOND: Inputs/def_comments.swift:15:10: EnumElement/second_decl_enum_1.Case1
+// SECOND: Inputs/def_comments.swift:16:10: EnumElement/second_decl_enum_1.Case2
+// SECOND: Inputs/def_comments.swift:20:12: Constructor/second_decl_class_2.init
+// SECOND: Inputs/def_comments.swift:23:17: Protocol/second_decl_protocol_1
+// SECOND: Inputs/def_comments.swift:24:20: AssociatedType/second_decl_protocol_1.NestedTypealias
+// SECOND: Inputs/def_comments.swift:25:5: Subscript/second_decl_protocol_1.subscript
+// SECOND: Inputs/def_comments.swift:25:35: Accessor/second_decl_protocol_1.<getter for second_decl_protocol_1.subscript>
+// SECOND: Inputs/def_comments.swift:25:39: Accessor/second_decl_protocol_1.<setter for second_decl_protocol_1.subscript>
+// SECOND: Inputs/def_comments.swift:28:13: Var/decl_var_2 RawComment=none BriefComment=none DocCommentAsXML=none
+// SECOND: Inputs/def_comments.swift:28:25: Var/decl_var_3 RawComment=none BriefComment=none DocCommentAsXML=none
+// SECOND: Inputs/def_comments.swift:28:25: Var/decl_var_3 RawComment=none BriefComment=none DocCommentAsXML=none
+// SECOND: NonExistingSource.swift:100000:13: Func/functionAfterPoundSourceLoc
+
+// Test the case when we have to import via a .swiftinterface file.
+//
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/Hidden)
+// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/Hidden/comments.swiftmodule -emit-module-interface-path %t/comments.swiftinterface -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s -enable-library-evolution -swift-version 5
+// RUN: llvm-bcanalyzer %t/comments.swiftdoc | %FileCheck %s -check-prefix=BCANALYZER
+// RUN: llvm-bcanalyzer %t/comments.swiftsourceinfo | %FileCheck %s -check-prefix=BCANALYZER
+// RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -source-filename %s -I %t -swift-version 5 | %FileCheck %s -check-prefix=FIRST
diff --git a/test/SourceKit/CodeExpand/code-expand.swift b/test/SourceKit/CodeExpand/code-expand.swift
index 1313be8..950bd9e 100644
--- a/test/SourceKit/CodeExpand/code-expand.swift
+++ b/test/SourceKit/CodeExpand/code-expand.swift
@@ -90,7 +90,9 @@
 func f1() {
   bar(a : {}}, <#T##d: () -> ()##() -> ()#>)
 }
-// CHECK: bar(a : {}}, <#T##d: () -> ()##() -> ()#>)
+// CHECK: bar(a : {}) {
+// CHECK-NEXT: <#code#>
+// CHECK-NEXT: }
 
 foo(withDuration: 1, animations: <#T##() -> Void#>)
 
diff --git a/test/Syntax/Outputs/round_trip_invalid.swift.withkinds b/test/Syntax/Outputs/round_trip_invalid.swift.withkinds
index 648fe36..bfa790a 100644
--- a/test/Syntax/Outputs/round_trip_invalid.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_invalid.swift.withkinds
@@ -20,4 +20,4 @@
 enum E <MemberDeclBlock>{<MemberDeclListItem><ProtocolDecl>
 protocol P <MemberDeclBlock>{<MemberDeclListItem><ExtensionDecl>
 extension <SimpleTypeIdentifier>P </SimpleTypeIdentifier><MemberDeclBlock>{<MemberDeclListItem><InitializerDecl><DeclModifier>
-public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: (<TupleTypeElement><SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TupleTypeElement>|| String)</FunctionParameter>)</ParameterClause></InitializerDecl></MemberDeclListItem></MemberDeclBlock></ExtensionDecl></MemberDeclListItem></MemberDeclBlock></ProtocolDecl></MemberDeclListItem></MemberDeclBlock></EnumDecl></MemberDeclListItem></MemberDeclBlock></StructDecl></MemberDeclListItem></MemberDeclBlock></ClassDecl></CodeBlock></FunctionDecl>
+public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <TupleType>(<TupleTypeElement><SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TupleTypeElement><TupleTypeElement></TupleTypeElement>|| String)</TupleType></FunctionParameter>)</ParameterClause></InitializerDecl></MemberDeclListItem></MemberDeclBlock></ExtensionDecl></MemberDeclListItem></MemberDeclBlock></ProtocolDecl></MemberDeclListItem></MemberDeclBlock></EnumDecl></MemberDeclListItem></MemberDeclBlock></StructDecl></MemberDeclListItem></MemberDeclBlock></ClassDecl></CodeBlock></FunctionDecl>
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index b04eb9e..36aa776 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -548,11 +548,11 @@
 struct ReadModify <MemberDeclBlock>{<MemberDeclListItem><VariableDecl>
   var <PatternBinding><IdentifierPattern>st0 </IdentifierPattern><InitializerClause>= <TupleExpr>(<TupleExprElement><StringLiteralExpr>"<StringSegment>a</StringSegment>"</StringLiteralExpr>, </TupleExprElement><TupleExprElement><StringLiteralExpr>"<StringSegment>b</StringSegment>"</StringLiteralExpr></TupleExprElement>)</TupleExpr></InitializerClause></PatternBinding></VariableDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl>
   var <PatternBinding><IdentifierPattern>rm0</IdentifierPattern><TypeAnnotation>: <TupleType>(<TupleTypeElement><SimpleTypeIdentifier>String</SimpleTypeIdentifier>, </TupleTypeElement><TupleTypeElement><SimpleTypeIdentifier>String</SimpleTypeIdentifier></TupleTypeElement>) </TupleType></TypeAnnotation><AccessorBlock>{<AccessorDecl>
-    _read <CodeBlock>{ <YieldStmt>yield <YieldList>(<TupleExpr>(<TupleExprElement><StringLiteralExpr>"<StringSegment>a</StringSegment>"</StringLiteralExpr>, </TupleExprElement><TupleExprElement><StringLiteralExpr>"<StringSegment>b</StringSegment>"</StringLiteralExpr></TupleExprElement>)</TupleExpr>) </YieldList></YieldStmt>}</CodeBlock></AccessorDecl><AccessorDecl>
+    _read <CodeBlock>{ <YieldStmt>yield <YieldList>(<TupleExprElement><TupleExpr>(<TupleExprElement><StringLiteralExpr>"<StringSegment>a</StringSegment>"</StringLiteralExpr>, </TupleExprElement><TupleExprElement><StringLiteralExpr>"<StringSegment>b</StringSegment>"</StringLiteralExpr></TupleExprElement>)</TupleExpr></TupleExprElement>) </YieldList></YieldStmt>}</CodeBlock></AccessorDecl><AccessorDecl>
     _modify <CodeBlock>{ <YieldStmt>yield <InOutExpr>&<IdentifierExpr>st0 </IdentifierExpr></InOutExpr></YieldStmt>}</CodeBlock></AccessorDecl>
   }</AccessorBlock></PatternBinding></VariableDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl>
   var <PatternBinding><IdentifierPattern>rm1</IdentifierPattern><TypeAnnotation>: <TupleType>(<TupleTypeElement><SimpleTypeIdentifier>String</SimpleTypeIdentifier>, </TupleTypeElement><TupleTypeElement><SimpleTypeIdentifier>String</SimpleTypeIdentifier></TupleTypeElement>) </TupleType></TypeAnnotation><AccessorBlock>{<AccessorDecl>
-    _read <CodeBlock>{ <YieldStmt>yield <YieldList>(<IdentifierExpr>st0</IdentifierExpr>) </YieldList></YieldStmt>}</CodeBlock></AccessorDecl>
+    _read <CodeBlock>{ <YieldStmt>yield <YieldList>(<TupleExprElement><IdentifierExpr>st0</IdentifierExpr></TupleExprElement>) </YieldList></YieldStmt>}</CodeBlock></AccessorDecl>
   }</AccessorBlock></PatternBinding></VariableDecl></MemberDeclListItem>
 }</MemberDeclBlock></StructDecl><StructDecl><CustomAttribute>
 
@@ -562,9 +562,9 @@
 
 func foo<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><PoundSourceLocation>
 
-#sourceLocation()</PoundSourceLocation>
+#sourceLocation()</PoundSourceLocation><StringLiteralExpr>
 
-"<StringSegment>abc </StringSegment>\( } )<StringSegment> def</StringSegment>"<PoundAssertStmt>
+"<StringSegment>abc </StringSegment><ExpressionSegment>\( <TupleExprElement></TupleExprElement>} )</ExpressionSegment><StringSegment> def</StringSegment>"</StringLiteralExpr><PoundAssertStmt>
 
 #assert(<BooleanLiteralExpr>true</BooleanLiteralExpr>)</PoundAssertStmt><PoundAssertStmt>
 #assert(<BooleanLiteralExpr>false</BooleanLiteralExpr>)</PoundAssertStmt><PoundAssertStmt>
diff --git a/test/attr/attr_autoclosure.swift b/test/attr/attr_autoclosure.swift
index e30fb83..10bb792 100644
--- a/test/attr/attr_autoclosure.swift
+++ b/test/attr/attr_autoclosure.swift
@@ -274,3 +274,10 @@
   func biz_5(_ fn: @escaping () -> (() -> Int)) { fiz(fn) } // Can't forward in Swift >= 5 mode
   // expected-error@-1 {{add () to forward @autoclosure parameter}} {{57-57=()}}
 }
+
+func test_autoclosure_with_generic_argument_mismatch() {
+  struct S<T> {} // expected-note {{arguments to generic parameter 'T' ('String' and 'Int') are expected to be equal}}
+  func foo(_: @autoclosure () -> S<Int>) {}
+
+  foo(S<String>()) // expected-error {{cannot convert value of type 'S<String>' to expected argument type 'S<Int>'}}
+}
diff --git a/test/decl/ext/extensions.swift b/test/decl/ext/extensions.swift
index 1dd8801..b4eab44 100644
--- a/test/decl/ext/extensions.swift
+++ b/test/decl/ext/extensions.swift
@@ -126,7 +126,7 @@
 }
 
 // Class-constrained extension where protocol does not impose class requirement
-// SR-11298
+
 protocol DoesNotImposeClassReq_1 {}
 	
 class JustAClass: DoesNotImposeClassReq_1 {
@@ -140,8 +140,8 @@
   }
 }
 	
-let instanceOfJustAClass = JustAClass()
-instanceOfJustAClass.wrappingProperty = "" // Okay
+let instanceOfJustAClass = JustAClass() // expected-note {{change 'let' to 'var' to make it mutable}}
+instanceOfJustAClass.wrappingProperty = "" // expected-error {{cannot assign to property: 'instanceOfJustAClass' is a 'let' constant}}
 
 protocol DoesNotImposeClassReq_2 {
   var property: String { get set }
@@ -150,7 +150,7 @@
 extension DoesNotImposeClassReq_2 where Self : AnyObject {
   var wrappingProperty: String {
     get { property }
-    set { property = newValue } // expected-error {{cannot assign to property: 'self' is immutable}}
+    set { property = newValue } // Okay
   }
 }
 
diff --git a/test/decl/func/default-values.swift b/test/decl/func/default-values.swift
index d06285f..123f657 100644
--- a/test/decl/func/default-values.swift
+++ b/test/decl/func/default-values.swift
@@ -132,8 +132,14 @@
 func inoutFuncWithDefaultArg2(x: inout Int = bLiteral) {} // expected-error {{cannot provide default value to inout parameter 'x'}}
 func inoutFuncWithDefaultArg3(x: inout Int = aLiteral) {} // expected-error {{cannot provide default value to inout parameter 'x'}}
 func inoutFuncWithDefaultArg4(x: inout Int = &aLiteral) {} // expected-error {{cannot provide default value to inout parameter 'x'}}
+// expected-error@-1 {{use of extraneous '&'}}
+
 func inoutFuncWithDefaultArg5(x: inout Int = &bLiteral) {} // expected-error {{cannot provide default value to inout parameter 'x'}}
+// expected-error@-1 {{use of extraneous '&'}}
+
 func inoutFuncWithDefaultArg6(x: inout Int = #file) {} // expected-error {{cannot provide default value to inout parameter 'x'}}
+// expected-error@-1 {{default argument value of type 'String' cannot be converted to type 'Int'}}
+
 func inoutFuncWithDefaultArg7(_: inout Int = 1) {} // expected-error {{cannot provide default value to inout parameter '_'}}
 
 // SE-0242 - Test that memberwise constructor generates default values
diff --git a/test/decl/func/dynamic_self.swift b/test/decl/func/dynamic_self.swift
index 447fa6a..0203c5f1e 100644
--- a/test/decl/func/dynamic_self.swift
+++ b/test/decl/func/dynamic_self.swift
@@ -386,8 +386,7 @@
 
   convenience init(string: String) {
     self.init(factory: Factory(_string: string))
-    // expected-error@-1 {{incorrect argument label in call (have 'factory:', expected '_string:')}}
-    // FIXME: Bogus diagnostic
+    // expected-error@-1 {{cannot convert value of type 'Factory' to expected argument type 'Self'}}
   }
 }
 
diff --git a/test/decl/protocol/req/associated_type_inference.swift b/test/decl/protocol/req/associated_type_inference.swift
index 36665f5..7003c21 100644
--- a/test/decl/protocol/req/associated_type_inference.swift
+++ b/test/decl/protocol/req/associated_type_inference.swift
@@ -150,7 +150,7 @@
 struct XSubP0c : SubscriptP0 {
 // expected-error@-1 {{type 'XSubP0c' does not conform to protocol 'SubscriptP0'}}
   subscript (i: Index) -> Element { get { } }
-  // expected-error@-1 {{reference to invalid associated type 'Index' of type 'XSubP0c'}}
+  // expected-error@-1 {{reference to invalid associated type 'Element' of type 'XSubP0c'}}
 }
 
 struct XSubP0d : SubscriptP0 {
diff --git a/test/decl/var/property_wrappers.swift b/test/decl/var/property_wrappers.swift
index 0b1d4b1..31e7e98 100644
--- a/test/decl/var/property_wrappers.swift
+++ b/test/decl/var/property_wrappers.swift
@@ -235,8 +235,9 @@
   @Wrapper(stored: 17)
   var x2: Double
 
-  @Wrapper(stored: 17)
-  var x3 = 42 // expected-error{{extra argument 'wrappedValue' in call}}
+  @Wrapper(stored: 17) // expected-error {{initializer expects a single parameter of type 'T' [with T = (wrappedValue: Int, stored: Int)]}}
+  // expected-note@-1 {{did you mean to pass a tuple?}}
+  var x3 = 42
 
   @Wrapper(stored: 17)
   var x4
@@ -1723,3 +1724,68 @@
     // ...
   }
 }
+
+// SR-11477
+
+// Two initializers that can default initialize the wrapper //
+
+@propertyWrapper
+struct SR_11477_W1 { // Okay
+  let name: String
+
+  init() {
+    self.name = "Init"
+  }
+
+  init(name: String = "DefaultParamInit") {
+    self.name = name
+  }
+
+  var wrappedValue: Int {
+    get { return 0 }
+  }
+}
+
+// Two initializers with default arguments that can default initialize the wrapper //
+
+@propertyWrapper
+struct SR_11477_W2 { // Okay
+  let name: String
+
+  init(anotherName: String = "DefaultParamInit1") {
+    self.name = anotherName
+  }
+
+  init(name: String = "DefaultParamInit2") {
+    self.name = name
+  }
+
+  var wrappedValue: Int {
+    get { return 0 }
+  }
+}
+
+// Single initializer that can default initialize the wrapper //
+
+@propertyWrapper
+struct SR_11477_W3 { // Okay
+  let name: String
+
+  init() {
+    self.name = "Init"
+  }
+
+  var wrappedValue: Int {
+    get { return 0 }
+  }
+}
+
+// rdar://problem/56213175 - backward compatibility issue with Swift 5.1,
+// which unconditionally skipped protocol members.
+protocol ProtocolWithWrapper {
+  associatedtype Wrapper = Float // expected-note{{associated type 'Wrapper' declared here}}
+}
+
+struct UsesProtocolWithWrapper: ProtocolWithWrapper {
+  @Wrapper var foo: Int // expected-warning{{ignoring associated type 'Wrapper' in favor of module-scoped property wrapper 'Wrapper'; please qualify the reference with 'property_wrappers'}}{{4-4=property_wrappers.}}
+}
diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift
index 501f5c8..b24049f 100644
--- a/test/expr/expressions.swift
+++ b/test/expr/expressions.swift
@@ -774,6 +774,7 @@
   // ?? should have higher precedence than logical operators like || and comparisons.
   if cond || (a ?? 42 > 0) {}  // Ok.
   if (cond || a) ?? 42 > 0 {}  // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
+  // expected-error@-1:12 {{cannot convert value of type 'Bool' to expected argument type 'Int?'}}
   if (cond || a) ?? (42 > 0) {}  // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
 
   if cond || a ?? 42 > 0 {}    // Parses as the first one, not the others.
@@ -781,7 +782,8 @@
 
   // ?? should have lower precedence than range and arithmetic operators.
   let r1 = r ?? (0...42) // ok
-  let r2 = (r ?? 0)...42 // not ok: expected-error {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
+  let r2 = (r ?? 0)...42 // not ok: expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
+  // expected-error@-1 {{argument type 'ClosedRange<Int>' does not conform to expected type 'Comparable'}}
   let r3 = r ?? 0...42 // parses as the first one, not the second.
   
   
@@ -851,6 +853,7 @@
 // <rdar://problem/20802757> Compiler crash in default argument & inout expr
 var g20802757 = 2
 func r20802757(_ z: inout Int = &g20802757) { // expected-error {{cannot provide default value to inout parameter 'z'}}
+  // expected-error@-1 {{use of extraneous '&'}}
   print(z)
 }
 
diff --git a/test/expr/postfix/dot/init_ref_delegation.swift b/test/expr/postfix/dot/init_ref_delegation.swift
index 66553ff..8400d62 100644
--- a/test/expr/postfix/dot/init_ref_delegation.swift
+++ b/test/expr/postfix/dot/init_ref_delegation.swift
@@ -549,10 +549,9 @@
 
 func sr10670() {
   struct S {
-    init(_ x: inout String) {}
-    init(_ x: inout [Int]) {}
+    init(_ x: inout String) {} // expected-note {{candidate expects in-out value of type 'String' for parameter #1}}
+    init(_ x: inout [Int]) {}  // expected-note {{candidate expects in-out value of type '[Int]' for parameter #1}}
   }
   var a = 0
-  S.init(&a) // expected-error {{cannot invoke 'S.Type.init' with an argument list of type '(inout Int)'}}
-  // expected-note@-1 {{overloads for 'S.Type.init' exist with these partially matching parameter lists: (inout String), (inout [Int])}}
+  S.init(&a) // expected-error {{no exact matches in call to initializer}}
 }
diff --git a/test/expr/primary/keypath/keypath-objc.swift b/test/expr/primary/keypath/keypath-objc.swift
index 27f638d..a3bee67 100644
--- a/test/expr/primary/keypath/keypath-objc.swift
+++ b/test/expr/primary/keypath/keypath-objc.swift
@@ -134,7 +134,7 @@
 func testParseErrors() {
   let _: String = #keyPath; // expected-error{{expected '(' following '#keyPath'}}
   let _: String = #keyPath(123; // expected-error{{expected property or type name within '#keyPath(...)'}}
-  let _: String = #keyPath(a.123; // expected-error{{expected property or type name within '#keyPath(...)'}}
+  let _: String = #keyPath(a.123; // expected-error{{expected property or type name within '#keyPath(...)'}} expected-error {{use of unresolved identifier 'a'}}
   let _: String = #keyPath(A(b:c:d:).propSet); // expected-error{{an Objective-C key path cannot reference a declaration with a compound name}} expected-error{{unresolved identifier 'propSet'}}
   let _: String = #keyPath(A.propString; // expected-error{{expected ')' to complete '#keyPath' expression}}
     // expected-note@-1{{to match this opening '('}}
diff --git a/test/lit.cfg b/test/lit.cfg
index b42ba26..fd1c59f 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -178,8 +178,8 @@
                                           execute_external=not use_lit_shell)
 
 # suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.swift', '.ll', '.sil', '.gyb', '.m', '.swiftinterface',
-                   '.test-sh']
+config.suffixes = ['.swift', '.ll', '.sil', '.gyb', '.m', '.c',
+                   '.swiftinterface', '.test-sh']
 
 # excludes: A list of directories to exclude from the testsuite. The 'Inputs'
 # subdirectories contain auxiliary inputs for various tests in their parent
@@ -1645,6 +1645,7 @@
 
 config.substitutions.append(('%target-swiftmodule-name', run_cpu + '.swiftmodule'))
 config.substitutions.append(('%target-swiftdoc-name', run_cpu + '.swiftdoc'))
+config.substitutions.append(('%target-swiftsourceinfo-name', run_cpu + '.swiftsourceinfo'))
 
 config.substitutions.append(('%target-object-format', config.target_object_format))
 config.substitutions.append(('%{target-shared-library-prefix}', config.target_shared_library_prefix))
@@ -1698,5 +1699,12 @@
         config.available_features.add("LinuxDistribution=" + distributor + '-' + release)
         lit_config.note('Running tests on %s-%s' % (distributor, release))
 
+# Copy environment variables specified in --param copy_env=..., overriding
+# anything computed here. It's assumed that the person setting this knows what
+# they're doing.
+copy_env = lit_config.params.get('copy_env', None)
+if copy_env is not None:
+  for key in copy_env.split(':'):
+    config.environment[key] = os.environ[key]
 
 lit_config.note("Available features: " + ", ".join(sorted(config.available_features)))
diff --git a/test/stdlib/Compatibility50Linking.c b/test/stdlib/Compatibility50Linking.c
new file mode 100644
index 0000000..806da27
--- /dev/null
+++ b/test/stdlib/Compatibility50Linking.c
@@ -0,0 +1,13 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-clang %s -all_load %test-resource-dir/%target-sdk-name/libswiftCompatibility50.a -lobjc -o %t/main
+// RUN: %target-run %t/main
+// REQUIRES: objc_interop
+// REQUIRES: executable_test
+
+// The compatibility library needs to have no build-time dependencies on
+// libswiftCore so it can be linked into a program that doesn't link
+// libswiftCore, but will load it at runtime, such as xctest.
+//
+// Test this by linking it into a plain C program and making sure it builds.
+
+int main(void) {}
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
index 0ec93db..fafc035 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
@@ -814,8 +814,8 @@
       ArgNames = ArgNames.slice(1);
     }
 
-    if (auto typeRepr = param->getTypeLoc().getTypeRepr()) {
-      SourceRange TypeRange = param->getTypeLoc().getSourceRange();
+    if (auto typeRepr = param->getTypeRepr()) {
+      SourceRange TypeRange = typeRepr->getSourceRange();
       if (auto InOutTyR = dyn_cast_or_null<InOutTypeRepr>(typeRepr))
         TypeRange = InOutTyR->getBase()->getSourceRange();
       if (TypeRange.isInvalid())
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp b/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
index 34cae41..3882f07 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
@@ -184,7 +184,7 @@
     // documentation file.
     // FIXME: refactor the frontend to provide an easy way to figure out the
     // correct filename here.
-    auto FUnit = Loader->loadAST(*Mod, None, std::move(Buf), nullptr,
+    auto FUnit = Loader->loadAST(*Mod, None, std::move(Buf), nullptr, nullptr,
                                  /*isFramework*/false,
                                  /*treatAsPartialModule*/false);
 
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index 22d0514..827ce50 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -902,7 +902,7 @@
 }
 
 bool SwiftLangSupport::printUSR(const ValueDecl *D, llvm::raw_ostream &OS) {
-  return ide::printDeclUSR(D, OS);
+  return ide::printValueDeclUSR(D, OS);
 }
 
 bool SwiftLangSupport::printDeclTypeUSR(const ValueDecl *D, llvm::raw_ostream &OS) {
@@ -947,9 +947,9 @@
       OS << "<#T##";
 
     paramTy = paramTy.subst(substMap);
-    if (paramTy->hasError() && param->getTypeLoc().hasLocation()) {
+    if (paramTy->hasError() && param->getTypeRepr()) {
       // Fallback to 'TypeRepr' printing.
-      param->getTypeLoc().getTypeRepr()->print(OS);
+      param->getTypeRepr()->print(OS);
     } else {
       paramTy.print(OS);
     }
diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
index 96f732d..f6d2102 100644
--- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
+++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
@@ -983,7 +983,7 @@
 static StringRef calculateUsr(SDKContext &Ctx, ValueDecl *VD) {
   llvm::SmallString<64> SS;
   llvm::raw_svector_ostream OS(SS);
-  if (!ide::printDeclUSR(VD, OS)) {
+  if (!ide::printValueDeclUSR(VD, OS)) {
     return Ctx.buffer(SS.str());
   }
   return StringRef();
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 33d0b4c..d8d9dc49 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -2510,6 +2510,18 @@
     }
   }
 
+  void printSerializedLoc(Decl *D) {
+    auto moduleLoc = cast<FileUnit>(D->getDeclContext()->getModuleScopeContext())->
+      getBasicLocsForDecl(D);
+    if (!moduleLoc.hasValue())
+      return;
+    if (!moduleLoc->Loc.isValid())
+      return;
+    OS << moduleLoc->SourceFilePath
+       << ":" << moduleLoc->Loc.Line
+       << ":" << moduleLoc->Loc.Column << ": ";
+  }
+
   bool walkToDeclPre(Decl *D) override {
     if (D->isImplicit())
       return true;
@@ -2518,8 +2530,10 @@
       SourceLoc Loc = D->getLoc();
       if (Loc.isValid()) {
         auto LineAndColumn = SM.getLineAndColumn(Loc);
-        OS << SM.getDisplayNameForLoc(VD->getLoc())
+        OS << SM.getDisplayNameForLoc(Loc)
            << ":" << LineAndColumn.first << ":" << LineAndColumn.second << ": ";
+      } else {
+        printSerializedLoc(D);
       }
       OS << Decl::getKindName(VD->getKind()) << "/";
       printDeclName(VD);
@@ -2535,8 +2549,10 @@
       SourceLoc Loc = D->getLoc();
       if (Loc.isValid()) {
         auto LineAndColumn = SM.getLineAndColumn(Loc);
-        OS << SM.getDisplayNameForLoc(D->getLoc())
+        OS << SM.getDisplayNameForLoc(Loc)
         << ":" << LineAndColumn.first << ":" << LineAndColumn.second << ": ";
+      } else {
+        printSerializedLoc(D);
       }
       OS << Decl::getKindName(D->getKind()) << "/";
       OS << " ";
@@ -2803,7 +2819,7 @@
   void printUSR(const ValueDecl *VD, SourceLoc Loc) {
     printLoc(Loc);
     OS << ' ';
-    if (ide::printDeclUSR(VD, OS))
+    if (ide::printValueDeclUSR(VD, OS))
       OS << "ERROR:no-usr";
     OS << '\n';
   }
@@ -2889,7 +2905,7 @@
     std::string USR;
     {
       llvm::raw_string_ostream OS(USR);
-      printDeclUSR(VD, OS);
+      printValueDeclUSR(VD, OS);
     }
 
     std::string error;
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index 0b0daa4..edd0cc8 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -1,6 +1,5 @@
 add_swift_unittest(SwiftASTTests
   ArithmeticEvaluator.cpp
-  # SWIFT_ENABLE_TENSORFLOW
   IndexSubsetTests.cpp
   DiagnosticConsumerTests.cpp
   SourceLocTests.cpp
diff --git a/unittests/AST/IndexSubsetTests.cpp b/unittests/AST/IndexSubsetTests.cpp
index 7e3c1cd..0be306d 100644
--- a/unittests/AST/IndexSubsetTests.cpp
+++ b/unittests/AST/IndexSubsetTests.cpp
@@ -1,4 +1,4 @@
-//===------------------ IndexSubsetTests.cpp -----------------------===//
+//===--------------------- IndexSubsetTests.cpp ---------------------------===//
 //
 // This source file is part of the Swift.org open source project
 //
@@ -10,7 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "swift/AST/AutoDiff.h"
 #include "swift/AST/IndexSubset.h"
 #include "TestContext.h"
 #include "gtest/gtest.h"
@@ -49,58 +48,45 @@
 
 TEST(IndexSubset, Equality) {
   TestContext ctx;
-  EXPECT_EQ(IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {0}),
-            IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {0}));
-  EXPECT_EQ(IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {0, 2, 4}),
-            IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {0, 2, 4}));
-  EXPECT_EQ(IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {}),
-            IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {}));
-  EXPECT_NE(IndexSubset::get(ctx.Ctx, /*capacity*/ 1,
-                                     /*indices*/ {}),
-            IndexSubset::get(ctx.Ctx, /*capacity*/ 0,
-                                     /*indices*/ {}));
-  EXPECT_NE(IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {0}),
-            IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {}));
+  EXPECT_EQ(IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {0}),
+            IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {0}));
+  EXPECT_EQ(IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {0, 2, 4}),
+            IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {0, 2, 4}));
+  EXPECT_EQ(IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {}),
+            IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {}));
+  EXPECT_NE(IndexSubset::get(ctx.Ctx, /*capacity*/ 1, /*indices*/ {}),
+            IndexSubset::get(ctx.Ctx, /*capacity*/ 0, /*indices*/ {}));
+  EXPECT_NE(IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {0}),
+            IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {}));
 }
 
 TEST(IndexSubset, Initializers) {
   TestContext ctx;
   // Default init.
   EXPECT_EQ(IndexSubset::getDefault(ctx.Ctx, /*capacity*/ 5,
-                                            /*includeAll*/ true),
+                                    /*includeAll*/ true),
             IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                     /*indices*/ {0, 1, 2, 3, 4}));
+                             /*indices*/ {0, 1, 2, 3, 4}));
   EXPECT_EQ(IndexSubset::getDefault(ctx.Ctx, /*capacity*/ 5,
-                                            /*includeAll*/ false),
+                                    /*includeAll*/ false),
             IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {}));
   EXPECT_EQ(IndexSubset::getDefault(ctx.Ctx, /*capacity*/ 0,
-                                            /*includeAll*/ true),
-            IndexSubset::get(ctx.Ctx, /*capacity*/ 0,
-                                     /*indices*/ {}));
+                                    /*includeAll*/ true),
+            IndexSubset::get(ctx.Ctx, /*capacity*/ 0, /*indices*/ {}));
   EXPECT_EQ(IndexSubset::getDefault(ctx.Ctx, /*capacity*/ 0,
-                                            /*includeAll*/ false),
+                                    /*includeAll*/ false),
             IndexSubset::get(ctx.Ctx, /*capacity*/ 0, /*indices*/ {}));
   // Bit vector init.
   {
     llvm::SmallBitVector bitVec(6);
     bitVec.set(1, 4);
     EXPECT_EQ(IndexSubset::get(ctx.Ctx, bitVec),
-              IndexSubset::get(ctx.Ctx, /*capacity*/ 6,
-                                       /*indices*/ {1, 2, 3}));
+              IndexSubset::get(ctx.Ctx, /*capacity*/ 6, /*indices*/ {1, 2, 3}));
   }
   {
     llvm::SmallBitVector bitVec(0);
     EXPECT_EQ(IndexSubset::get(ctx.Ctx, bitVec),
-              IndexSubset::get(ctx.Ctx, /*capacity*/ 0,
-                                       /*indices*/ {}));
+              IndexSubset::get(ctx.Ctx, /*capacity*/ 0, /*indices*/ {}));
   }
   // String init.
   EXPECT_EQ(IndexSubset::getFromString(ctx.Ctx, "SSSSS"),
@@ -118,7 +104,7 @@
 TEST(IndexSubset, Bits) {
   TestContext ctx;
   auto *indices1 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                            /*indices*/ {0, 2, 4});
+                                    /*indices*/ {0, 2, 4});
   EXPECT_EQ(indices1->getNumBitWords(), 1u);
   EXPECT_EQ(indices1->getCapacity(), 5u);
   EXPECT_TRUE(indices1->contains(0));
@@ -128,7 +114,7 @@
   EXPECT_TRUE(indices1->contains(4));
 
   auto *indices2 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                            /*indices*/ {1, 3});
+                                    /*indices*/ {1, 3});
   EXPECT_EQ(indices2->getNumBitWords(), 1u);
   EXPECT_EQ(indices2->getCapacity(), 5u);
   EXPECT_FALSE(indices2->contains(0));
@@ -143,7 +129,7 @@
   // Test 1
   {
     auto *indices1 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                              /*indices*/ {0, 2, 4});
+                                      /*indices*/ {0, 2, 4});
     // Check forward iteration.
     EXPECT_EQ(indices1->findFirst(), 0);
     EXPECT_EQ(indices1->findNext(0), 2);
@@ -162,7 +148,7 @@
   // Test 2
   {
     auto *indices2 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                              /*indices*/ {1, 3});
+                                      /*indices*/ {1, 3});
     // Check forward iteration.
     EXPECT_EQ(indices2->findFirst(), 1);
     EXPECT_EQ(indices2->findNext(1), 3);
@@ -181,11 +167,10 @@
 TEST(IndexSubset, SupersetAndSubset) {
   TestContext ctx;
   auto *indices1 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                            /*indices*/ {0, 2, 4});
+                                    /*indices*/ {0, 2, 4});
   EXPECT_TRUE(indices1->isSupersetOf(indices1));
   EXPECT_TRUE(indices1->isSubsetOf(indices1));
-  auto *indices2 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5,
-                                            /*indices*/ {2});
+  auto *indices2 = IndexSubset::get(ctx.Ctx, /*capacity*/ 5, /*indices*/ {2});
   EXPECT_TRUE(indices2->isSupersetOf(indices2));
   EXPECT_TRUE(indices2->isSubsetOf(indices2));
 
@@ -202,7 +187,6 @@
   EXPECT_EQ(indices1->adding(3, ctx.Ctx),
             IndexSubset::get(ctx.Ctx, 5, {0, 2, 3, 4}));
 }
-
 TEST(IndexSubset, Lowering) {
   TestContext testCtx;
   auto &C = testCtx.Ctx;
diff --git a/unittests/FrontendTool/ModuleLoadingTests.cpp b/unittests/FrontendTool/ModuleLoadingTests.cpp
index 5c643ad..de3d95a 100644
--- a/unittests/FrontendTool/ModuleLoadingTests.cpp
+++ b/unittests/FrontendTool/ModuleLoadingTests.cpp
@@ -108,11 +108,12 @@
 
     std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
     std::unique_ptr<llvm::MemoryBuffer> moduleDocBuffer;
+    std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoBuffer;
 
     auto error =
       loader->findModuleFilesInDirectory({moduleName, SourceLoc()}, tempDir,
-        "Library.swiftmodule", "Library.swiftdoc",
-        &moduleBuffer, &moduleDocBuffer);
+        "Library.swiftmodule", "Library.swiftdoc", "Library.swiftsourceinfo",
+        &moduleBuffer, &moduleDocBuffer, &moduleSourceInfoBuffer);
     ASSERT_FALSE(error);
     ASSERT_FALSE(diags.hadAnyError());
 
diff --git a/utils/build-script-impl b/utils/build-script-impl
index a41821c..8d46792 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -2156,6 +2156,17 @@
         -DINTERNAL_INSTALL_PREFIX="local"
     )
 
+    if [[ "$(uname -s)" == "Linux" ]] ; then
+        if [[ $(is_cmake_debuginfo_build_type "${LLVM_BUILD_TYPE}") ]] ; then
+            # On Linux build LLVM and subprojects with -gsplit-dwarf which is more
+            # space/time efficient than -g on that platform.
+            llvm_cmake_options=(
+                "${llvm_cmake_options[@]}"
+                -DLLVM_USE_SPLIT_DWARF:BOOL=YES
+            )
+        fi
+    fi
+
     if [[ "${DARWIN_TOOLCHAIN_VERSION}" ]] ; then
         swift_cmake_options=(
             "${swift_cmake_options[@]}"
diff --git a/utils/gyb_syntax_support/CompletionOnlyNodes.py b/utils/gyb_syntax_support/CompletionOnlyNodes.py
index d1bd1b7..e95b753 100644
--- a/utils/gyb_syntax_support/CompletionOnlyNodes.py
+++ b/utils/gyb_syntax_support/CompletionOnlyNodes.py
@@ -4,7 +4,21 @@
 # These nodes are used only in code completion.
 
 COMPLETIONONLY_NODES = [
-    # type
+    # Expression.
+    Node('CodeCompletionExpr', kind='Expr',
+         children=[
+             Child('Base', kind='Expr', is_optional=True),
+             Child('PeriodOrParen', kind='Token',
+                   token_choices=[
+                       'PeriodToken',
+                       'PrefixPeriodToken',
+                       'LeftParenToken',
+                   ],
+                   is_optional=True),
+             Child('CodeCompletionToken', kind='Token'),
+         ]),
+
+    # Type.
     Node('CodeCompletionType', kind='Type',
          children=[
              Child('Base', kind='Type', is_optional=True),
diff --git a/utils/gyb_syntax_support/ExprNodes.py b/utils/gyb_syntax_support/ExprNodes.py
index c9a63e2..5fa31fa 100644
--- a/utils/gyb_syntax_support/ExprNodes.py
+++ b/utils/gyb_syntax_support/ExprNodes.py
@@ -218,8 +218,12 @@
     Node('TupleExprElement', kind='Syntax',
          traits=['WithTrailingComma'],
          children=[
-             Child('Label', kind='IdentifierToken',
-                   is_optional=True),
+             Child('Label', kind='Token',
+                   is_optional=True,
+                   token_choices=[
+                       'IdentifierToken',
+                       'WildcardToken'
+                   ]),
              Child('Colon', kind='ColonToken',
                    is_optional=True),
              Child('Expression', kind='Expr'),
@@ -503,6 +507,8 @@
     Node('ObjcNamePiece', kind='Syntax',
          children=[
              Child('Name', kind='IdentifierToken'),
+             Child('DeclNameArguments', kind='DeclNameArguments',
+                   is_optional=True),
              Child('Dot', kind='PeriodToken', is_optional=True),
          ]),
 
@@ -554,6 +560,8 @@
              Child('Arguments', kind='TupleExprElementList',
                    collection_element_name='Argument'),
              Child('RightParen', kind='RightParenToken'),
+             Child('TrailingClosure', kind='ClosureExpr',
+                   is_optional=True),
          ]),
 
     # quote-expr -> '#quote' '(' expr ')'
diff --git a/utils/gyb_syntax_support/StmtNodes.py b/utils/gyb_syntax_support/StmtNodes.py
index 6d860ab..cf71d0a 100644
--- a/utils/gyb_syntax_support/StmtNodes.py
+++ b/utils/gyb_syntax_support/StmtNodes.py
@@ -153,9 +153,8 @@
     Node('YieldList', kind='Syntax',
          children=[
              Child('LeftParen', kind='LeftParenToken'),
-             Child('ElementList', kind='ExprList',
+             Child('ElementList', kind='TupleExprElementList',
                    collection_element_name='Element'),
-             Child('TrailingComma', kind='CommaToken', is_optional=True),
              Child('RightParen', kind='RightParenToken'),
          ]),
 
diff --git a/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py b/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py
index 211913d..802c9f7 100644
--- a/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py
+++ b/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py
@@ -28,7 +28,7 @@
             'build', host_target, self, self.args)
 
     def test(self, host_target):
-        if self.args.test and self.args.test_sourcekitlsp:
+        if self.args.test_sourcekitlsp:
             indexstoredb.run_build_script_helper(
                 'test', host_target, self, self.args)
 
diff --git a/utils/update_checkout/update-checkout-config.json b/utils/update_checkout/update-checkout-config.json
index 15f8083..2e89fc5 100644
--- a/utils/update_checkout/update-checkout-config.json
+++ b/utils/update_checkout/update-checkout-config.json
@@ -59,7 +59,7 @@
         "swift-format": {
             "remote": { "id": "apple/swift-format" } },
         "llvm-project": {
-            "remote": { "id": "apple/llvm-project-v2" } }
+            "remote": { "id": "apple/llvm-project-v3" } }
     },
     "default-branch-scheme": "master",
     "branch-schemes": {
@@ -469,30 +469,30 @@
         "tensorflow": {
             "aliases": ["tensorflow"],
             "repos": {
-                "llvm": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
+                "llvm": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
                 "clang": "0c249864907e436c81b75007c2f9f251d0326c29",
                 "swift": "tensorflow",
                 "lldb": "ca0b2a68f586098c96073e062b19bc0f87a998c6",
-                "cmark": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "llbuild": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "swiftpm": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
+                "cmark": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "llbuild": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "swiftpm": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
                 "swift-syntax": "adc26e4473d53e6b3e1b7945aca495595f07cc41",
-                "swift-stress-tester": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "compiler-rt": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "swift-corelibs-xctest": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "swift-corelibs-foundation": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "swift-corelibs-libdispatch": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "swift-integration-tests": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "swift-xcode-playground-support": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
+                "swift-stress-tester": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "compiler-rt": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "swift-corelibs-xctest": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "swift-corelibs-foundation": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "swift-corelibs-libdispatch": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "swift-integration-tests": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "swift-xcode-playground-support": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
                 "ninja": "release",
                 "icu": "release-61-1",
-                "clang-tools-extra": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "libcxx": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
+                "clang-tools-extra": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "libcxx": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
                 "tensorflow": "7c7d924821a8b1b20433c2f3f484bbd409873a84",
                 "tensorflow-swift-apis": "f4f88d924d71eedb0709e26d0d5e4b7cfe94d830",
                 "tensorflow-swift-quote": "62c0a88dc64a201497a66cbbc087c0c7771edabc",
-                "indexstore-db": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a",
-                "sourcekit-lsp": "swift-DEVELOPMENT-SNAPSHOT-2019-10-08-a"
+                "indexstore-db": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a",
+                "sourcekit-lsp": "swift-DEVELOPMENT-SNAPSHOT-2019-10-13-a"
             }
         }
     }
diff --git a/validation-test/compiler_crashers_2_fixed/0209-rdar45590743.swift b/validation-test/compiler_crashers_2_fixed/0209-rdar45590743.swift
new file mode 100644
index 0000000..43ef1e9
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0209-rdar45590743.swift
@@ -0,0 +1,10 @@
+// RUN: not %target-swift-frontend -typecheck %s
+
+// rdar://problem/45590743 used to crash
+class Base {
+  var x = 0
+}
+
+class Derived : Base {
+  override var x = Derived().x
+}
diff --git a/validation-test/compiler_crashers_fixed/28723-unreachable-executed-at-swift-lib-sema-csdiag-cpp-4012.swift b/validation-test/compiler_crashers_fixed/28723-unreachable-executed-at-swift-lib-sema-csdiag-cpp-4012.swift
index 3443962..19e5766 100644
--- a/validation-test/compiler_crashers_fixed/28723-unreachable-executed-at-swift-lib-sema-csdiag-cpp-4012.swift
+++ b/validation-test/compiler_crashers_fixed/28723-unreachable-executed-at-swift-lib-sema-csdiag-cpp-4012.swift
@@ -5,6 +5,8 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
+// rdar://56144412
+// XFAIL: asserts
 // RUN: not %target-swift-frontend %s -emit-ir
 func t(UInt=__FUNCTION__
 func&t(