Merge pull request #12766 from xedin/fix-tuple-type-metadata-reader

diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index cd38cde..9e8b509 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -1744,6 +1744,9 @@
   }
 }
 
+/// Canonical ordering for dependent types.
+int compareDependentTypes(Type type1, Type type2);
+
 } // end namespace swift
 
 #endif
diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h
index b6b7171..96f2d3e 100644
--- a/include/swift/AST/Pattern.h
+++ b/include/swift/AST/Pattern.h
@@ -170,8 +170,9 @@
 
   /// Return true if this pattern (or a subpattern) is refutable.
   bool isRefutablePattern() const;
-  
-  
+
+  bool isNeverDefaultInitializable() const;
+
   /// \brief Mark all vardecls in this pattern as having non-pattern initial
   /// values bound into them.
   void markHasNonPatternBindingInit() {
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 8a13c45..10ca863 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -1716,12 +1716,10 @@
   ArrayRef<Type> getGenericArgs() const { return GenericArgs; }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    RecursiveTypeProperties properties;
-    Profile(ID, TheDecl, Parent, GenericArgs, properties);
+    Profile(ID, TheDecl, Parent, GenericArgs);
   }
   static void Profile(llvm::FoldingSetNodeID &ID, NominalTypeDecl *TheDecl,
-                      Type Parent, ArrayRef<Type> GenericArgs,
-                      RecursiveTypeProperties &properties);
+                      Type Parent, ArrayRef<Type> GenericArgs);
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const TypeBase *T) {
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index f2a56bf..1ed4bcb 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -47,6 +47,8 @@
 class SingleValueInstruction;
 class MultipleValueInstruction;
 class MultipleValueInstructionResult;
+class DestructureTupleInst;
+class DestructureStructInst;
 class NonValueInstruction;
 class SILBasicBlock;
 class SILBuilder;
@@ -7274,6 +7276,11 @@
   static bool classof(const SILNode *N) {
     return N->getKind() == SILNodeKind::DestructureStructResult;
   }
+
+  DestructureStructInst *getParent();
+  const DestructureStructInst *getParent() const {
+    return const_cast<DestructureStructResult *>(this)->getParent();
+  }
 };
 
 /// Instruction that takes in a struct value and splits the struct into the
@@ -7300,6 +7307,12 @@
   }
 };
 
+// Out of line to work around forward declaration issues.
+inline DestructureStructInst *DestructureStructResult::getParent() {
+  auto *Parent = MultipleValueInstructionResult::getParent();
+  return cast<DestructureStructInst>(Parent);
+}
+
 /// A result for the destructure_tuple instruction. See documentation for
 /// destructure_tuple for more information.
 class DestructureTupleResult final : public MultipleValueInstructionResult {
@@ -7312,6 +7325,11 @@
   static bool classof(const SILNode *N) {
     return N->getKind() == SILNodeKind::DestructureTupleResult;
   }
+
+  DestructureTupleInst *getParent();
+  const DestructureTupleInst *getParent() const {
+    return const_cast<DestructureTupleResult *>(this)->getParent();
+  }
 };
 
 /// Instruction that takes in a tuple value and splits the tuple into the
@@ -7338,6 +7356,12 @@
   }
 };
 
+// Out of line to work around forward declaration issues.
+inline DestructureTupleInst *DestructureTupleResult::getParent() {
+  auto *Parent = MultipleValueInstructionResult::getParent();
+  return cast<DestructureTupleInst>(Parent);
+}
+
 } // end swift namespace
 
 //===----------------------------------------------------------------------===//
diff --git a/include/swift/Syntax/SyntaxParsingContext.h b/include/swift/Syntax/SyntaxParsingContext.h
index 3f8580d..002f9b0 100644
--- a/include/swift/Syntax/SyntaxParsingContext.h
+++ b/include/swift/Syntax/SyntaxParsingContext.h
@@ -13,7 +13,8 @@
 #ifndef SWIFT_SYNTAX_PARSING_CONTEXT_H
 #define SWIFT_SYNTAX_PARSING_CONTEXT_H
 
- #include "swift/Syntax/Syntax.h"
+#include "swift/Basic/SourceLoc.h"
+#include "swift/Syntax/Syntax.h"
 
 namespace swift {
   class SourceLoc;
@@ -25,19 +26,28 @@
   struct RawSyntax;
   enum class SyntaxKind;
 
+enum class SyntaxContextKind: uint8_t{
+  Expr,
+  Decl,
+  Stmt,
+};
+
 /// The handler for parser to generate libSyntax entities.
 struct RawSyntaxInfo {
-  /// Start location of this syntax node.
-  SourceLoc StartLoc;
-
-  /// The number of tokens belong to the syntax node.
-  unsigned TokCount;
+  /// Start and end location of this syntax node.
+  SourceRange SyntaxRange;
 
   /// The raw node.
   RC<RawSyntax> RawNode;
+  RawSyntaxInfo(RC<RawSyntax> RawNode): RawNode(RawNode) {}
   RawSyntaxInfo(SourceLoc StartLoc, RC<RawSyntax> RawNode):
-    RawSyntaxInfo(StartLoc, 1, RawNode) {}
-  RawSyntaxInfo(SourceLoc StartLoc, unsigned TokCount, RC<RawSyntax> RawNode);
+    SyntaxRange(StartLoc), RawNode(RawNode) {}
+  RawSyntaxInfo(SourceRange SyntaxRange, RC<RawSyntax> RawNode):
+    SyntaxRange(SyntaxRange), RawNode(RawNode) {}
+
+  bool isImplicit() const { return SyntaxRange.isInvalid(); }
+  SourceLoc getStartLoc() const { return SyntaxRange.Start; }
+  SourceLoc getEndLoc() const { return SyntaxRange.End; }
 
   template <typename SyntaxNode>
   SyntaxNode makeSyntax() const { return make<SyntaxNode>(RawNode); }
@@ -46,6 +56,7 @@
   RC<RawSyntaxNode> getRaw() const {
     return RC<RawSyntaxNode>(cast<RawSyntaxNode>(RawNode));
   }
+  void brigeWithContext(SyntaxContextKind Kind);
 };
 
 enum class SyntaxParsingContextKind: uint8_t {
@@ -96,11 +107,6 @@
   };
 };
 
-enum class SyntaxContextKind: uint8_t{
-  Expr,
-  Decl,
-};
-
 // The base class for contexts that are created from a parent context.
 // The stack instance will set the context holder when the context
 // is firstly created and reset the context holder to the parent when
@@ -108,10 +114,21 @@
 class SyntaxParsingContextChild: public SyntaxParsingContext {
   SyntaxParsingContext *Parent;
   SyntaxParsingContext *&ContextHolder;
-  const SyntaxContextKind Kind;
+  Optional<SyntaxContextKind> Kind;
+  Optional<SyntaxKind> KnownSyntax;
+  void makeNodeWhole(SyntaxKind Kind);
+  SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
+                            Optional<SyntaxContextKind> Kind,
+                            Optional<SyntaxKind> KnownSyntax);
 public:
   SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
-                            SyntaxContextKind Kind);
+    SyntaxContextKind Kind): SyntaxParsingContextChild(ContextHolder,
+                                                       Kind, None) {}
+
+  SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
+    SyntaxKind KnownSyntax): SyntaxParsingContextChild(ContextHolder,
+                             None, KnownSyntax) {};
+
   ~SyntaxParsingContextChild();
   void makeNode(SyntaxKind Kind) override;
   void addTokenSyntax(SourceLoc Loc) override;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 256fbb2..314321f 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3190,15 +3190,12 @@
 
 void BoundGenericType::Profile(llvm::FoldingSetNodeID &ID,
                                NominalTypeDecl *TheDecl, Type Parent,
-                               ArrayRef<Type> GenericArgs,
-                               RecursiveTypeProperties &properties) {
+                               ArrayRef<Type> GenericArgs) {
   ID.AddPointer(TheDecl);
   ID.AddPointer(Parent.getPointer());
-  if (Parent) properties |= Parent->getRecursiveProperties();
   ID.AddInteger(GenericArgs.size());
   for (Type Arg : GenericArgs) {
     ID.AddPointer(Arg.getPointer());
-    properties |= Arg->getRecursiveProperties();
   }
 }
 
@@ -3224,8 +3221,12 @@
 
   ASTContext &C = TheDecl->getDeclContext()->getASTContext();
   llvm::FoldingSetNodeID ID;
+  BoundGenericType::Profile(ID, TheDecl, Parent, GenericArgs);
   RecursiveTypeProperties properties;
-  BoundGenericType::Profile(ID, TheDecl, Parent, GenericArgs, properties);
+  if (Parent) properties |= Parent->getRecursiveProperties();
+  for (Type Arg : GenericArgs) {
+    properties |= Arg->getRecursiveProperties();
+  }
 
   auto arena = getArena(properties);
 
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8bcf7c1..d276857 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1187,10 +1187,10 @@
 
 // @NSManaged properties never get default initialized, nor do debugger
 // variables and immutable properties.
-bool isNeverDefaultInitializable(const Pattern *p) {
+bool Pattern::isNeverDefaultInitializable() const {
   bool result = false;
 
-  p->forEachVariable([&](const VarDecl *var) {
+  forEachVariable([&](const VarDecl *var) {
     if (var->getAttrs().hasAttribute<NSManagedAttr>())
       return;
 
@@ -1209,7 +1209,7 @@
   if (entry.getInit())
     return true;
 
-  if (isNeverDefaultInitializable(entry.getPattern()))
+  if (entry.getPattern()->isNeverDefaultInitializable())
     return false;
 
   // If the pattern is typed as optional (or tuples thereof), it is
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index df269f0..4aada77 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -193,18 +193,6 @@
 }
 
 #pragma mark GraphViz visualization
-static int compareDependentTypes(PotentialArchetype * const* pa,
-                                 PotentialArchetype * const* pb,
-                                 bool outermost);
-
-static int compareDependentTypes(PotentialArchetype * const* pa,
-                                 PotentialArchetype * const* pb) {
-  return compareDependentTypes(pa, pb, /*outermost=*/true);
-}
-
-static int compareDependentTypes(Type type1, Type type2,
-                                 bool outermost = true);
-
 namespace {
   /// A node in the equivalence class, used for visualization.
   struct EquivalenceClassVizNode {
@@ -1967,13 +1955,14 @@
   // within that equivalence class.
   llvm::SmallDenseMap<EquivalenceClass *, AssociatedTypeDecl *> nestedTypes;
 
-  PotentialArchetype *bestGenericParam = nullptr;
+  Type bestGenericParam;
   for (auto member : members) {
     // If the member is a generic parameter, keep the best generic parameter.
     if (member->isGenericParam()) {
+      Type genericParamType = member->getDependentType(genericParams);
       if (!bestGenericParam ||
-          compareDependentTypes(&member, &bestGenericParam) < 0)
-        bestGenericParam = member;
+          compareDependentTypes(genericParamType, bestGenericParam) < 0)
+        bestGenericParam = genericParamType;
       continue;
     }
 
@@ -2003,7 +1992,7 @@
 
   // If we found a generic parameter, return that.
   if (bestGenericParam)
-    return bestGenericParam->getDependentType(genericParams);
+    return bestGenericParam;
 
   // Determine the best anchor among the parent equivalence classes.
   Type bestParentAnchor;
@@ -2486,35 +2475,11 @@
   return result;
 }
 
-/// Whether there are any concrete type declarations in the potential archetype.
-static bool hasConcreteDecls(const PotentialArchetype *pa) {
-  auto parent = pa->getParent();
-  if (!parent) return false;
-
-  if (pa->getConcreteTypeDecl())
-    return true;
-
-  return hasConcreteDecls(parent);
-}
-
 /// Canonical ordering for dependent types.
-static int compareDependentTypes(Type type1, Type type2,
-                                 bool outermost) {
+int swift::compareDependentTypes(Type type1, Type type2) {
   // Fast-path check for equality.
   if (type1->isEqual(type2)) return 0;
 
-  if (outermost) {
-    // If there are any unresolved dependent member types in a type,
-    // it's an indication of a reference to a concrete, non-associated-type
-    // declaration. We prefer the type without such declarations.
-    bool hasConcreteDecls1 =
-      static_cast<bool>(type1->findUnresolvedDependentMemberType());
-    bool hasConcreteDecls2 =
-      static_cast<bool>(type2->findUnresolvedDependentMemberType());
-    if (hasConcreteDecls1 != hasConcreteDecls2)
-      return hasConcreteDecls1 ? +1 : -1;
-  }
-
   // Ordering is as follows:
   // - Generic params
   auto gp1 = type1->getAs<GenericTypeParamType>();
@@ -2532,8 +2497,7 @@
 
   // - by base, so t_0_n.`P.T` < t_1_m.`P.T`
   if (int compareBases =
-        compareDependentTypes(depMemTy1->getBase(), depMemTy2->getBase(),
-                              /*outermost=*/false))
+        compareDependentTypes(depMemTy1->getBase(), depMemTy2->getBase()))
     return compareBases;
 
   // - by name, so t_n_m.`P.T` < t_n_m.`P.U`
@@ -2558,86 +2522,6 @@
   return 0;
 }
 
-/// Canonical ordering for dependent types in generic signatures.
-static int compareDependentTypes(PotentialArchetype * const* pa,
-                                 PotentialArchetype * const* pb,
-                                 bool outermost) {
-  auto a = *pa, b = *pb;
-
-  // Fast-path check for equality.
-  if (a == b)
-    return 0;
-
-  // If one has concrete declarations somewhere but the other does not,
-  // prefer the one without concrete declarations.
-  if (outermost) {
-    bool aHasConcreteDecls = hasConcreteDecls(a);
-    bool bHasConcreteDecls = hasConcreteDecls(b);
-    if (aHasConcreteDecls != bHasConcreteDecls)
-      return aHasConcreteDecls ? +1 : -1;
-  }
-
-  // Ordering is as follows:
-  // - Generic params
-  if (a->isGenericParam() && b->isGenericParam())
-    return a->getGenericParamKey() < b->getGenericParamKey() ? -1 : +1;
-
-  // A generic parameter is always ordered before a nested type.
-  if (a->isGenericParam() != b->isGenericParam())
-    return a->isGenericParam() ? -1 : +1;
-
-  // - Dependent members
-  auto ppa = a->getParent();
-  auto ppb = b->getParent();
-
-  // - by base, so t_0_n.`P.T` < t_1_m.`P.T`
-  if (int compareBases = compareDependentTypes(&ppa, &ppb, /*outermost=*/false))
-    return compareBases;
-
-  // Types that are equivalent to concrete types follow types that are still
-  // type parameters.
-  if (a->isConcreteType() != b->isConcreteType())
-    return a->isConcreteType() ? +1 : -1;
-
-  // Concrete types must be ordered *after* everything else, to ensure they
-  // don't become representatives in the case where a concrete type is equated
-  // with an associated type.
-  if (a->getParent() && b->getParent() &&
-      !!a->getConcreteTypeDecl() != !!b->getConcreteTypeDecl())
-    return a->getConcreteTypeDecl() ? +1 : -1;
-
-  // - by name, so t_n_m.`P.T` < t_n_m.`P.U`
-  if (int compareNames = a->getNestedName().str().compare(
-                                                      b->getNestedName().str()))
-    return compareNames;
-
-  if (auto *aa = a->getResolvedAssociatedType()) {
-    if (auto *ab = b->getResolvedAssociatedType()) {
-      if (int result = compareAssociatedTypes(aa, ab))
-        return result;
-    } else {
-      // A resolved archetype is always ordered before an unresolved one.
-      return -1;
-    }
-  } else {
-    // A resolved archetype is always ordered before an unresolved one.
-    if (b->getResolvedAssociatedType())
-      return +1;
-  }
-
-  // Make sure concrete type declarations are properly ordered, to avoid
-  // crashers.
-  if (auto *aa = a->getConcreteTypeDecl()) {
-    auto *ab = b->getConcreteTypeDecl();
-    assert(ab != nullptr && "Should have handled this case above");
-
-    if (int result = TypeDecl::compare(aa, ab))
-      return result;
-  }
-
-  llvm_unreachable("potential archetype total order failure");
-}
-
 namespace {
   /// Function object used to suppress conflict diagnoses when we know we'll
   /// see them again later.
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 25e4c19..aa7059c 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -22,12 +22,15 @@
 #include "swift/Parse/Lexer.h"
 #include "swift/Parse/CodeCompletionCallbacks.h"
 #include "swift/Subsystems.h"
+#include "swift/Syntax/TokenSyntax.h"
+#include "swift/Syntax/SyntaxParsingContext.h"
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/SaveAndRestore.h"
 
 using namespace swift;
+using namespace swift::syntax;
 
 /// isStartOfStmt - Return true if the current token starts a statement.
 ///
@@ -223,7 +226,7 @@
 ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
                                      BraceItemListKind Kind,
                                      BraceItemListKind ConditionalBlockKind) {
-  
+  SyntaxParsingContextChild StmtListContext(SyntaxContext, SyntaxKind::StmtList);
   bool IsTopLevel = (Kind == BraceItemListKind::TopLevelCode) ||
                     (Kind == BraceItemListKind::TopLevelLibrary);
   bool isActiveConditionalBlock =
@@ -259,6 +262,7 @@
          Tok.isNot(tok::kw_sil_default_witness_table) &&
          (isConditionalBlock ||
           !isTerminatorForBraceItemListKind(Kind, Entries))) {
+    SyntaxParsingContextChild StmtContext(SyntaxContext, SyntaxContextKind::Stmt);
     if (Kind == BraceItemListKind::TopLevelLibrary &&
         skipExtraTopLevelRBraces())
       continue;
@@ -489,7 +493,7 @@
 }
 
 ParserResult<Stmt> Parser::parseStmt() {
-
+  SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxContextKind::Stmt);
   // Note that we're parsing a statement.
   StructureMarkerRAII ParsingStmt(*this, Tok.getLoc(),
                                   StructureMarkerKind::Statement);
@@ -586,15 +590,19 @@
     if (Tok.isNot(tok::l_brace))
       return nullptr;
   }
+  SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxKind::CodeBlock);
   SourceLoc LBLoc = consumeToken(tok::l_brace);
+  LocalContext.addTokenSyntax(LBLoc);
 
   SmallVector<ASTNode, 16> Entries;
   SourceLoc RBLoc;
 
   ParserStatus Status = parseBraceItems(Entries, BraceItemListKind::Brace,
                                         BraceItemListKind::Brace);
-  parseMatchingToken(tok::r_brace, RBLoc,
-                     diag::expected_rbrace_in_brace_stmt, LBLoc);
+  if (!parseMatchingToken(tok::r_brace, RBLoc,
+                          diag::expected_rbrace_in_brace_stmt, LBLoc)) {
+    LocalContext.addTokenSyntax(RBLoc);
+  }
 
   return makeParserResult(Status,
                           BraceStmt::create(Context, LBLoc, Entries, RBLoc));
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 2c906f8..a5d5c6d 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -68,7 +68,7 @@
     SourceManager &SourceMgr = SF.getASTContext().SourceMgr;
     unsigned BufferID = SourceMgr.findBufferContainingLoc(AFD->getLoc());
     Parser TheParser(BufferID, SF, nullptr, &ParserState);
-
+    TheParser.SyntaxContext->disable();
     std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
     if (CodeCompletionFactory) {
       CodeCompletion.reset(
@@ -102,6 +102,9 @@
     SourceMgr.findBufferContainingLoc(ParserState.getDelayedDeclLoc());
   Parser TheParser(BufferID, SF, nullptr, &ParserState);
 
+  // Disable libSyntax creation in the delayed parsing.
+  TheParser.SyntaxContext->disable();
+
   std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
   if (CodeCompletionFactory) {
     CodeCompletion.reset(
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index d85cf71..d610be8 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -446,14 +446,12 @@
 }
 
 /// Given an RValue of aggregate type, compute the values of the elements by
-/// emitting a series of tuple_element instructions.
+/// emitting a destructure.
 static void getScalarizedElements(SILValue V,
                                   SmallVectorImpl<SILValue> &ElementVals,
                                   SILLocation Loc, SILBuilder &B) {
-  TupleType *TT = V->getType().castTo<TupleType>();
-  for (auto Index : indices(TT->getElements())) {
-    ElementVals.push_back(B.emitTupleExtract(Loc, V, Index));
-  }
+  auto *DTI = B.createDestructureTuple(Loc, V);
+  copy(DTI->getResults(), std::back_inserter(ElementVals));
 }
 
 /// Scalarize a load down to its subelements.  If NewLoads is specified, this
@@ -562,6 +560,8 @@
   void addElementUses(unsigned BaseEltNo, SILType UseTy, SILInstruction *User,
                       DIUseKind Kind);
   void collectTupleElementUses(TupleElementAddrInst *TEAI, unsigned BaseEltNo);
+  void collectDestructureTupleResultUses(DestructureTupleResult *DTR,
+                                         unsigned BaseEltNo);
   void collectStructElementUses(StructElementAddrInst *SEAI,
                                 unsigned BaseEltNo);
 };
@@ -611,6 +611,33 @@
   collectUses(TEAI, BaseEltNo);
 }
 
+/// Given a destructure_tuple, compute the new BaseEltNo implicit in the
+/// selected member, and recursively add uses of the instruction.
+void ElementUseCollector::collectDestructureTupleResultUses(
+    DestructureTupleResult *DTR, unsigned BaseEltNo) {
+
+  // If we're walking into a tuple within a struct or enum, don't adjust the
+  // BaseElt.  The uses hanging off the tuple_element_addr are going to be
+  // counted as uses of the struct or enum itself.
+  if (InStructSubElement || InEnumSubElement)
+    return collectUses(DTR, BaseEltNo);
+
+  assert(!IsSelfOfNonDelegatingInitializer && "self doesn't have tuple type");
+
+  // tuple_element_addr P, 42 indexes into the current tuple element.
+  // Recursively process its uses with the adjusted element number.
+  unsigned FieldNo = DTR->getIndex();
+  auto T = DTR->getParent()->getOperand()->getType();
+  if (T.is<TupleType>()) {
+    for (unsigned i = 0; i != FieldNo; ++i) {
+      SILType EltTy = T.getTupleElementType(i);
+      BaseEltNo += getElementCountRec(Module, EltTy, false);
+    }
+  }
+
+  collectUses(DTR, BaseEltNo);
+}
+
 void ElementUseCollector::collectStructElementUses(StructElementAddrInst *SEAI,
                                                    unsigned BaseEltNo) {
   // Generally, we set the "InStructSubElement" flag and recursively process
@@ -1024,8 +1051,15 @@
     // Now that we've scalarized some stuff, recurse down into the newly created
     // element address computations to recursively process it.  This can cause
     // further scalarization.
-    for (auto EltPtr : ElementAddrs)
-      collectTupleElementUses(cast<TupleElementAddrInst>(EltPtr), BaseEltNo);
+    for (SILValue EltPtr : ElementAddrs) {
+      if (auto *TEAI = dyn_cast<TupleElementAddrInst>(EltPtr)) {
+        collectTupleElementUses(TEAI, BaseEltNo);
+        continue;
+      }
+
+      auto *DTRI = cast<DestructureTupleResult>(EltPtr);
+      collectDestructureTupleResultUses(DTRI, BaseEltNo);
+    }
   }
 }
 
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index f63bf23..55aa7a8 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4127,8 +4127,25 @@
             TC.checkTypeModifyingDeclAttributes(var);
 
           // Decide whether we should suppress default initialization.
-          if (!PBD->isDefaultInitializable(i))
-            continue;
+          //
+          // Note: Swift 4 had a bug where properties with a desugared optional
+          // type like Optional<Int> had a half-way behavior where sometimes
+          // they behave like they are default initialized, and sometimes not.
+          //
+          // In Swift 5 mode, use the right condition here, and only default
+          // initialize properties with a sugared Optional type.
+          //
+          // (The restriction to sugared types only comes because we don't have
+          // the iterative declaration checker yet; so in general, we cannot
+          // look at the type of a property at all, and can only look at the
+          // TypeRepr, because we haven't validated the property yet.)
+          if (TC.Context.isSwiftVersionAtLeast(5)) {
+            if (!PBD->isDefaultInitializable(i))
+              continue;
+          } else {
+            if (PBD->getPattern(i)->isNeverDefaultInitializable())
+              continue;
+          }
 
           auto type = PBD->getPattern(i)->getType();
           if (auto defaultInit = buildDefaultInitializer(TC, type)) {
@@ -8540,16 +8557,20 @@
 
   // Bail out if we're validating one of our constructors already; we'll
   // revisit the issue later.
-  bool alreadyValidatingCtor = false;
-  for (auto member : decl->getMembers()) {
-    if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
-      validateDecl(ctor);
-      if (!ctor->hasValidSignature())
-        alreadyValidatingCtor = true;
+  if (isa<ClassDecl>(decl)) {
+    bool alreadyValidatingCtor = false;
+    for (auto member : decl->getMembers()) {
+      if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
+        validateDecl(ctor);
+        if (!ctor->hasValidSignature())
+          alreadyValidatingCtor = true;
+      }
     }
+    if (alreadyValidatingCtor)
+      return;
   }
-  if (alreadyValidatingCtor)
-    return;
+
+  decl->setAddedImplicitInitializers();
 
   // Check whether there is a user-declared constructor or an instance
   // variable.
@@ -8558,7 +8579,6 @@
   bool SuppressMemberwiseInitializer = false;
   bool FoundSynthesizedInit = false;
   bool FoundDesignatedInit = false;
-  decl->setAddedImplicitInitializers();
 
   // Before we look for constructors, we need to make sure that all synthesized
   // initializers are properly synthesized.
@@ -8600,6 +8620,9 @@
         FoundDesignatedInit = true;
       }
 
+      if (isa<StructDecl>(decl))
+        continue;
+
       if (!ctor->isInvalid())
         initializerParamTypes.insert(getInitializerParamType(ctor));
 
@@ -8816,8 +8839,7 @@
     if (auto ref = conformsToProtocol(targetType, protocol, target,
                                       ConformanceCheckFlags::Used,
                                       SourceLoc())) {
-      if (auto *conformance =
-          dyn_cast_or_null<NormalProtocolConformance>(ref->getConcrete())) {
+      if (auto *conformance = ref->getConcrete()->getRootNormalConformance()) {
         if (conformance->isIncomplete()) {
           // Check conformance, forcing synthesis.
           //
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 9f90a4b..f53508b 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -3628,6 +3628,11 @@
       if (genericDecl->getGenericParams())
         continue;
 
+    // Skip typealiases with an unbound generic type as their underlying type.
+    if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(candidate.first))
+      if (typeAliasDecl->getDeclaredInterfaceType()->is<UnboundGenericType>())
+        continue;
+
     // Check this type against the protocol requirements.
     if (auto checkResult = checkTypeWitness(TC, DC, Proto, assocType,
                                             candidate.second)) {
diff --git a/lib/Syntax/RawSyntax.cpp b/lib/Syntax/RawSyntax.cpp
index 6a6c2b3..1c80bee 100644
--- a/lib/Syntax/RawSyntax.cpp
+++ b/lib/Syntax/RawSyntax.cpp
@@ -29,6 +29,7 @@
   case SyntaxKind::SourceFile:
   case SyntaxKind::TopLevelCodeDecl:
   case SyntaxKind::ExpressionStmt:
+  case SyntaxKind::DeclarationStmt:
     return true;
   default:
     return false;
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index 236c1d5..eb8e495 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -43,17 +43,21 @@
   return Scratch;
 }
 
-static unsigned countTokens(ArrayRef<RawSyntaxInfo> AllNodes) {
-  return std::accumulate(AllNodes.begin(), AllNodes.end(), 0,
-    [](unsigned Sum, const RawSyntaxInfo &Info) { return Sum + Info.TokCount; });
+static SourceRange getNodesRange(ArrayRef<RawSyntaxInfo> RawNodes) {
+  SourceLoc StartLoc, EndLoc;
+  for (auto Info: RawNodes) {
+    if (Info.isImplicit())
+      continue;
+    if (StartLoc.isInvalid()) {
+      StartLoc = Info.getStartLoc();
+    }
+    EndLoc = Info.getEndLoc();
+  }
+  assert(StartLoc.isValid() == EndLoc.isValid());
+  return SourceRange(StartLoc, EndLoc);
 }
 } // End of anonymous namespace
 
-RawSyntaxInfo::RawSyntaxInfo(SourceLoc StartLoc, unsigned TokCount,
-  RC<RawSyntax> RawNode): StartLoc(StartLoc), TokCount(TokCount), RawNode(RawNode) {
-    assert(StartLoc.isValid());
-}
-
 struct SyntaxParsingContext::ContextInfo {
   bool Enabled;
 private:
@@ -66,8 +70,8 @@
 
   ArrayRef<RawSyntaxInfo>::const_iterator findTokenAt(SourceLoc Loc) {
     for (auto It = Tokens.begin(); It != Tokens.end(); It ++) {
-      assert(It->TokCount == 1);
-      if (It->StartLoc == Loc)
+      assert(It->getStartLoc() == It->getEndLoc());
+      if (It->getStartLoc() == Loc)
         return It;
     }
     llvm_unreachable("cannot find the token on the given location");
@@ -98,8 +102,9 @@
   ArrayRef<RawSyntaxInfo> getPendingSyntax() const { return PendingSyntax; };
 
   void addPendingSyntax(RawSyntaxInfo Info) {
-    assert(PendingSyntax.empty() || PendingSyntax.back().StartLoc.
-           getOpaquePointerValue() < Info.StartLoc.getOpaquePointerValue());
+    assert(Info.isImplicit() || PendingSyntax.empty() ||
+           PendingSyntax.back().getStartLoc().getOpaquePointerValue() <
+             Info.getStartLoc().getOpaquePointerValue());
     PendingSyntax.push_back(Info);
   }
 
@@ -139,16 +144,21 @@
       // If no remaining syntax nodes, add the token.
       Results.emplace_back(Tok);
       It ++;
-    } else if (CurSyntax->StartLoc == Tok.StartLoc) {
+    } else if (CurSyntax->isImplicit()) {
+      // Skip implicit syntax node.
+      CurSyntax ++;
+    } else if (CurSyntax->getStartLoc() == Tok.getStartLoc()) {
       // Prefer syntax nodes to tokens.
       Results.emplace_back(*CurSyntax);
-      It += CurSyntax->TokCount;
+      while(It->getEndLoc() != CurSyntax->getEndLoc()) It++;
+      assert(It < Tokens.end() && It->getEndLoc() == CurSyntax->getEndLoc());
+      It ++;
       CurSyntax ++;
     } else {
       // We have to add token in this case since the next syntax node has not
       // started.
-      assert(Tok.StartLoc.getOpaquePointerValue() <
-             CurSyntax->StartLoc.getOpaquePointerValue());
+      assert(Tok.getStartLoc().getOpaquePointerValue() <
+             CurSyntax->getStartLoc().getOpaquePointerValue());
       Results.push_back(Tok);
       It ++;
     }
@@ -178,8 +188,8 @@
     Result.emplace(makeUnknownSyntax(SyntaxFactory::getUnknownKind(Kind),
                                      SyntaxParts));
   }
-  RawSyntaxInfo NewSyntaxNode(Parts.front().StartLoc, countTokens(Parts),
-                              Result->getRaw());
+  RawSyntaxInfo NewSyntaxNode(getNodesRange(Parts), Result->getRaw());
+
   // Remove the building bricks and re-append the result.
   for (unsigned I = 0; I < N; I ++)
     PendingSyntax.pop_back();
@@ -209,26 +219,9 @@
     }
   }
   for (auto Info: ContextData.getPendingSyntax()) {
-    std::vector<StmtSyntax> AllStmts;
-    auto S = Info.makeSyntax<Syntax>();
-    if (S.isDecl()) {
-      AllStmts.push_back(SyntaxFactory::makeDeclarationStmt(
-        S.getAs<DeclSyntax>().getValue(), None));
-    } else if (S.isExpr()) {
-      AllStmts.push_back(SyntaxFactory::makeExpressionStmt(
-        S.getAs<ExprSyntax>().getValue(), None));
-    } else if (S.isStmt()) {
-      AllStmts.push_back(S.getAs<StmtSyntax>().getValue());
-    } else {
-      // If this is a standalone token, we create an unknown expression wrapper
-      // for it.
-      AllStmts.push_back(SyntaxFactory::makeExpressionStmt(
-        *makeUnknownSyntax(SyntaxKind::UnknownExpr,
-                           { *S.getAs<TokenSyntax>() }).getAs<ExprSyntax>(),
-                                                           None));
-    }
+    assert(Info.RawNode->Kind == SyntaxKind::StmtList);
     AllTopLevel.push_back(SyntaxFactory::makeTopLevelCodeDecl(
-      SyntaxFactory::makeStmtList(AllStmts)));
+      Info.makeSyntax<StmtListSyntax>()));
   }
 
   File.setSyntaxRoot(
@@ -248,14 +241,16 @@
 
 SyntaxParsingContextChild::
 SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
-                          SyntaxContextKind Kind):
+      Optional<SyntaxContextKind> Kind, Optional<SyntaxKind> KnownSyntax):
     SyntaxParsingContext(*ContextHolder), Parent(ContextHolder),
-    ContextHolder(ContextHolder), Kind(Kind) {
+    ContextHolder(ContextHolder), Kind(Kind), KnownSyntax(KnownSyntax) {
+  assert(Kind.hasValue() != KnownSyntax.hasValue());
   ContextHolder = this;
   if (ContextData.Enabled)
     ContextData.setContextStart(Tok.getLoc());
 }
 
+
 void SyntaxParsingContextChild::addTokenSyntax(SourceLoc Loc) {
   if (ContextData.Enabled)
     ContextData.promoteTokenAt(Loc);
@@ -281,6 +276,53 @@
   }
 
   default:
+    llvm_unreachable("Unrecognized node kind.");
+  }
+}
+
+void SyntaxParsingContextChild::makeNodeWhole(SyntaxKind Kind) {
+  assert(ContextData.Enabled);
+  switch (Kind) {
+  case SyntaxKind::CodeBlock: {
+    ContextData.createFromBack(Kind);
+    break;
+  }
+  case SyntaxKind::StmtList: {
+    if (ContextData.getPendingSyntax().empty()) {
+      // Create an empty statement list if no statement is in the context.
+      ContextData.addPendingSyntax({SyntaxFactory::makeBlankStmtList().getRaw()});
+    } else {
+      ContextData.createFromBack(Kind);
+    }
+    break;
+  }
+  default:
+    llvm_unreachable("Unrecognized node kind.");
+  }
+}
+
+void RawSyntaxInfo::brigeWithContext(SyntaxContextKind Kind) {
+  switch (Kind) {
+  case SyntaxContextKind::Stmt: {
+    if (RawNode->isDecl()) {
+      // Wrap a declaration with a declaration statement
+      RawNode = SyntaxFactory::createSyntax(SyntaxKind::DeclarationStmt,
+        { makeSyntax<Syntax>() })->getRaw();
+    } else if (RawNode->isExpr()) {
+      // Wrap an expression with an expression statement
+      RawNode = SyntaxFactory::createSyntax(SyntaxKind::ExpressionStmt,
+        { makeSyntax<Syntax>() })->getRaw();
+    } else if (RawNode->isToken()) {
+      // Wrap a standalone token withn an expression statement
+      RawNode = SyntaxFactory::createSyntax(SyntaxKind::ExpressionStmt,
+        makeUnknownSyntax(SyntaxKind::UnknownExpr,
+                          {make<Syntax>(RawNode)}))->getRaw();
+    }
+    assert(RawNode->isStmt());
+    break;
+  }
+  case SyntaxContextKind::Decl:
+  case SyntaxContextKind::Expr:
     break;
   }
 }
@@ -295,32 +337,51 @@
 
   // Set the end of the context.
   ContextData.setContextEnd(Tok.getLoc());
+  if (KnownSyntax) {
+    // If the entire context should be created to a known syntax kind, create
+    // all pending syntax nodes into that node.
+    makeNodeWhole(*KnownSyntax);
+    assert(ContextData.getPendingSyntax().size() == 1);
+    auto AllNodes = ContextData.collectAllSyntax();
+    assert(AllNodes.size() == 1);
+    Parent->ContextData.addPendingSyntax(AllNodes.front());
+    return;
+  }
   auto AllNodes = ContextData.collectAllSyntax();
-  assert(countTokens(AllNodes) == ContextData.allTokens().size());
   RC<RawSyntax> FinalResult;
   if (AllNodes.empty())
     return;
 
+  // Make sure we used all tokens.
+  assert(AllNodes.front().getStartLoc() == ContextData.allTokens().front().getStartLoc());
+  assert(AllNodes.back().getEndLoc() == ContextData.allTokens().back().getStartLoc());
+
   if (AllNodes.size() == 1) {
-    // FIXME: Check kind
-    Parent->ContextData.addPendingSyntax(AllNodes.front());
+    // If we have only one syntax node remaining, we are done.
+    auto Result = AllNodes.front();
+    // Bridge the syntax node to the expected context kind.
+    Result.brigeWithContext(*Kind);
+    Parent->ContextData.addPendingSyntax(Result);
     return;
   }
 
   llvm::SmallVector<Syntax, 8> Scratch;
   auto SyntaxNodes = getSyntaxNodes(AllNodes, Scratch);
-  SourceLoc Start = AllNodes.front().StartLoc;
-  unsigned TokCount = countTokens(AllNodes);
+  SourceLoc Start = AllNodes.front().getStartLoc();
+  SourceLoc End = AllNodes.back().getEndLoc();
   SyntaxKind UnknownKind;
-  switch (Kind) {
+  switch (*Kind) {
     case SyntaxContextKind::Expr:
       UnknownKind = SyntaxKind::UnknownExpr;
       break;
     case SyntaxContextKind::Decl:
       UnknownKind = SyntaxKind::UnknownDecl;
       break;
+    case SyntaxContextKind::Stmt:
+      UnknownKind = SyntaxKind::UnknownStmt;
+      break;
   }
   // Create an unknown node and give it to the parent context.
-  Parent->ContextData.addPendingSyntax({Start, TokCount,
+  Parent->ContextData.addPendingSyntax({SourceRange(Start, End),
     makeUnknownSyntax(UnknownKind, SyntaxNodes).getRaw()});
 }
diff --git a/test/Compatibility/default_init.swift b/test/Compatibility/default_init.swift
new file mode 100644
index 0000000..e6eebc4
--- /dev/null
+++ b/test/Compatibility/default_init.swift
@@ -0,0 +1,16 @@
+// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify -swift-version 4
+
+// Default initialization of variables -- totally broken Swift 4 behavior.
+
+class NotInitializableOptionalClass {
+  var opt: Optional<Int>
+}
+
+struct NotInitializableOptionalStruct { // expected-note {{'init(opt:)' declared here}}
+  var opt: Optional<Int>
+}
+
+func testBadDefaultInit() {
+  _ = NotInitializableOptionalStruct() // expected-error {{missing argument for parameter 'opt' in call}}
+  _ = NotInitializableOptionalClass()
+}
diff --git a/test/SILOptimizer/definite_init_scalarization_test.sil b/test/SILOptimizer/definite_init_scalarization_test.sil
new file mode 100644
index 0000000..d79d250
--- /dev/null
+++ b/test/SILOptimizer/definite_init_scalarization_test.sil
@@ -0,0 +1,228 @@
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init | %FileCheck %s
+//
+// Make sure that we properly scalarize tuples.
+//
+// TODO: This should be split out into its own pass /before/ DI rather than
+// running during DI. Even once that happens, it is important that we update
+// this test so that the test is in its post scalarization state so we can
+// verify that DI can properly look through destructures.
+
+sil_stage raw
+
+import Builtin
+
+struct Int {
+  var _value: Builtin.Int64
+}
+
+struct TripleInt {
+  var a, b, c: Int
+}
+
+struct ObjectValue {
+  var a : Builtin.NativeObject
+}
+
+// CHECK-LABEL: sil @test_store_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @trivial $TripleInt, [[ARG1:%.*]] : @trivial $TripleInt, [[ARG2:%.*]] : @trivial $TripleInt):
+// CHECK:   [[BOX:%.*]] = alloc_box
+// CHECK:   [[PB_BOX:%.*]] = project_box [[BOX]]
+// CHECK:   [[ELT0:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 0
+// CHECK:   [[ELT1:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 1
+// CHECK:   [[ELT10:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 0
+// CHECK:   [[ELT11:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 1
+// CHECK:   [[RHS_TUP:%.*]] = tuple ([[ARG0]] : ${{.*}}, [[ARG1:%.*]] : ${{.*}})
+// CHECK:   [[TUP:%.*]] = tuple ([[ARG2:%.*]] : ${{.*}}, [[RHS_TUP]] : ${{.*}})
+// CHECK:   ([[DESTRUCTURE_TUP_LHS:%.*]], [[DESTRUCTURE_TUP_RHS:%.*]]) = destructure_tuple [[TUP]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK:   store [[DESTRUCTURE_TUP_LHS]] to [trivial] [[ELT0]]
+// CHECK:   ([[DESTRUCTURE_TUP_RHS_LHS:%.*]], [[DESTRUCTURE_TUP_RHS_RHS:%.*]]) = destructure_tuple [[DESTRUCTURE_TUP_RHS]] : $(TripleInt, TripleInt)
+// CHECK:   store [[DESTRUCTURE_TUP_RHS_LHS]] to [trivial] [[ELT10]]
+// CHECK:   store [[DESTRUCTURE_TUP_RHS_RHS]] to [trivial] [[ELT11]]
+// CHECK:   destroy_value [[BOX]]
+// CHECK: } // end sil function 'test_store_trivial'
+sil @test_store_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+bb0(%0 : @trivial $TripleInt, %1 : @trivial $TripleInt, %1a : @trivial $TripleInt):
+  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+  %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+  %4 = mark_uninitialized [var] %3 : $*(TripleInt, (TripleInt, TripleInt))
+  %5 = tuple(%0 : $TripleInt, %1 : $TripleInt)
+  %6 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+  store %6 to [trivial] %4 : $*(TripleInt, (TripleInt, TripleInt))
+  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_store_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $Builtin.NativeObject, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
+// CHECK:   [[BOX:%.*]] = alloc_box
+// CHECK:   [[PB_BOX:%.*]] = project_box [[BOX]]
+// CHECK:   [[ELT0:%.*]] = tuple_element_addr [[PB_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 0
+// CHECK:   [[ELT1:%.*]] = tuple_element_addr [[PB_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 1
+// CHECK:   [[ELT10:%.*]] = tuple_element_addr [[ELT1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 0
+// CHECK:   [[ELT11:%.*]] = tuple_element_addr [[ELT1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK:   [[RHS_TUP:%.*]] = tuple ([[ARG0]] : ${{.*}}, [[ARG1:%.*]] : ${{.*}})
+// CHECK:   [[TUP:%.*]] = tuple ([[ARG2:%.*]] : ${{.*}}, [[RHS_TUP]] : ${{.*}})
+// CHECK:   ([[DESTRUCTURE_TUP_LHS:%.*]], [[DESTRUCTURE_TUP_RHS:%.*]]) = destructure_tuple [[TUP]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK:   store [[DESTRUCTURE_TUP_LHS]] to [init] [[ELT0]]
+// CHECK:   ([[DESTRUCTURE_TUP_RHS_LHS:%.*]], [[DESTRUCTURE_TUP_RHS_RHS:%.*]]) = destructure_tuple [[DESTRUCTURE_TUP_RHS]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK:   store [[DESTRUCTURE_TUP_RHS_LHS]] to [init] [[ELT10]]
+// CHECK:   store [[DESTRUCTURE_TUP_RHS_RHS]] to [init] [[ELT11]]
+// CHECK:   destroy_value [[BOX]]
+// CHECK: } // end sil function 'test_store_owned'
+sil @test_store_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %1a : @owned $Builtin.NativeObject):
+  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+  %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+  %4 = mark_uninitialized [var] %3 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  %5 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+  %6 = tuple(%1a : $Builtin.NativeObject, %5 : $(Builtin.NativeObject, Builtin.NativeObject))
+  store %6 to [init] %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assign_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @trivial $TripleInt, [[ARG1:%.*]] : @trivial $TripleInt, [[ARG2:%.*]] : @trivial $TripleInt):
+// CHECK:   [[BOX:%.*]] = alloc_box
+// CHECK:   [[PB_BOX:%.*]] = project_box [[BOX]]
+// CHECK:   [[ELT0:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 0
+// CHECK:   [[ELT1:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 1
+// CHECK:   [[ELT10:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 0
+// CHECK:   [[ELT11:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 1
+// CHECK:   [[RHS_TUP:%.*]] = tuple ([[ARG0]] : ${{.*}}, [[ARG1:%.*]] : ${{.*}})
+// CHECK:   [[TUP:%.*]] = tuple ([[ARG2:%.*]] : ${{.*}}, [[RHS_TUP]] : ${{.*}})
+// CHECK:   ([[DESTRUCTURE_TUP_LHS:%.*]], [[DESTRUCTURE_TUP_RHS:%.*]]) = destructure_tuple [[TUP]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK:   store [[DESTRUCTURE_TUP_LHS]] to [trivial] [[ELT0]]
+// CHECK:   ([[DESTRUCTURE_TUP_RHS_LHS:%.*]], [[DESTRUCTURE_TUP_RHS_RHS:%.*]]) = destructure_tuple [[DESTRUCTURE_TUP_RHS]] : $(TripleInt, TripleInt)
+// CHECK:   store [[DESTRUCTURE_TUP_RHS_LHS]] to [trivial] [[ELT10]]
+// CHECK:   store [[DESTRUCTURE_TUP_RHS_RHS]] to [trivial] [[ELT11]]
+// CHECK:   destroy_value [[BOX]]
+// CHECK: } // end sil function 'test_assign_trivial'
+sil @test_assign_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+bb0(%0 : @trivial $TripleInt, %1 : @trivial $TripleInt, %1a : @trivial $TripleInt):
+  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+  %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+  %4 = mark_uninitialized [var] %3 : $*(TripleInt, (TripleInt, TripleInt))
+  %5 = tuple(%0 : $TripleInt, %1 : $TripleInt)
+  %6 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+  assign %6 to %4 : $*(TripleInt, (TripleInt, TripleInt))
+  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assign_trivial_2 : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @trivial $TripleInt, [[ARG1:%.*]] : @trivial $TripleInt, [[ARG2:%.*]] : @trivial $TripleInt):
+// CHECK:   [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+// CHECK:   [[PROJ_BOX:%.*]] = project_box [[BOX]] : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+// CHECK:   [[PROJ_BOX_0:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 0
+// CHECK:   [[PROJ_BOX_1:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 1
+// CHECK:   [[PROJ_BOX_10:%.*]] = tuple_element_addr %6 : $*(TripleInt, TripleInt), 0
+// CHECK:   [[PROJ_BOX_11:%.*]] = tuple_element_addr %6 : $*(TripleInt, TripleInt), 1
+// CHECK:   [[TUP11:%.*]] = tuple ([[ARG0]] : $TripleInt, [[ARG1]] : $TripleInt)
+// CHECK:   [[TUP1:%.*]] = tuple ([[ARG2]] : $TripleInt, [[TUP11]] : $(TripleInt, TripleInt))
+// CHECK:   [[TUP1_2nd:%.*]] = tuple ([[ARG2]] : $TripleInt, [[TUP11]] : $(TripleInt, TripleInt))
+// CHECK:   ([[TUP1_D_0:%.*]], [[TUP1_D_1:%.*]]) = destructure_tuple [[TUP1]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK:   store [[TUP1_D_0]] to [trivial] [[PROJ_BOX_0]] : $*TripleInt
+// CHECK:   ([[TUP1_D_1_0:%.*]], [[TUP1_D_1_1:%.*]]) = destructure_tuple [[TUP1_D_1]] : $(TripleInt, TripleInt)
+// CHECK:   store [[TUP1_D_1_0]] to [trivial] [[PROJ_BOX_10]] : $*TripleInt
+// CHECK:   store [[TUP1_D_1_1]] to [trivial] [[PROJ_BOX_11]] : $*TripleInt
+// CHECK:   ([[TUP1_2nd_0:%.*]], [[TUP1_2nd_1:%.*]]) = destructure_tuple [[TUP1_2nd]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK:   store [[TUP1_2nd_0]] to [trivial] [[PROJ_BOX_0]] : $*TripleInt
+// CHECK:   ([[TUP1_2nd_10:%.*]], [[TUP1_2nd_11:%.*]]) = destructure_tuple [[TUP1_2nd_1]] : $(TripleInt, TripleInt)
+// CHECK:   store [[TUP1_2nd_10]] to [trivial] [[PROJ_BOX_10]] : $*TripleInt
+// CHECK:   store [[TUP1_2nd_11]] to [trivial] [[PROJ_BOX_11]] : $*TripleInt
+// CHECK:   destroy_value [[BOX]] : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+// CHECK: } // end sil function 'test_assign_trivial_2'
+sil @test_assign_trivial_2 : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+bb0(%0 : @trivial $TripleInt, %1 : @trivial $TripleInt, %1a : @trivial $TripleInt):
+  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+  %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+  %4 = mark_uninitialized [var] %3 : $*(TripleInt, (TripleInt, TripleInt))
+  %5 = tuple(%0 : $TripleInt, %1 : $TripleInt)
+  %6 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+  %7 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+  assign %6 to %4 : $*(TripleInt, (TripleInt, TripleInt))
+  assign %7 to %4 : $*(TripleInt, (TripleInt, TripleInt))
+  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assign_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $Builtin.NativeObject, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
+// CHECK:   [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK:   [[PROJ_BOX:%.*]] = project_box [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+// CHECK:   [[PROJ_BOX_0:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 0
+// CHECK:   [[PROJ_BOX_1:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 1
+// CHECK:   [[PROJ_BOX_10:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 0
+// CHECK:   [[PROJ_BOX_11:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK:   [[TUP_1:%.*]] = tuple ([[ARG0]] : $Builtin.NativeObject, [[ARG1]] : $Builtin.NativeObject)
+// CHECK:   [[TUP:%.*]] = tuple ([[ARG2]] : $Builtin.NativeObject, [[TUP_1]] : $(Builtin.NativeObject, Builtin.NativeObject))
+// CHECK:   ([[TUP_D_0:%.*]], [[TUP_D_1:%.*]]) = destructure_tuple [[TUP]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK:   store [[TUP_D_0]] to [init] [[PROJ_BOX_0]] : $*Builtin.NativeObject
+// CHECK:   ([[TUP_D_10:%.*]], [[TUP_D_11:%.*]]) = destructure_tuple [[TUP_D_1]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK:   store [[TUP_D_10]] to [init] [[PROJ_BOX_10]] : $*Builtin.NativeObject
+// CHECK:   store [[TUP_D_11]] to [init] [[PROJ_BOX_11]] : $*Builtin.NativeObject
+// CHECK:   destroy_value [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK: } // end sil function 'test_assign_owned'
+sil @test_assign_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %1a : @owned $Builtin.NativeObject):
+  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+  %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+  %4 = mark_uninitialized [var] %3 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  %5 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+  %6 = tuple(%1a : $Builtin.NativeObject, %5 : $(Builtin.NativeObject, Builtin.NativeObject))
+  assign %6 to %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assigned_owned_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $Builtin.NativeObject, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
+// CHECK:   [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK:   [[PROJ_BOX:%.*]] = project_box [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+// CHECK:   [[PROJ_BOX_0:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 0
+// CHECK:   [[PROJ_BOX_1:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 1
+// CHECK:   [[PROJ_BOX_10:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 0
+// CHECK:   [[PROJ_BOX_11:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK:   [[TUP_1:%.*]] = tuple ([[ARG0]] : $Builtin.NativeObject, [[ARG1]] : $Builtin.NativeObject)
+// CHECK:   [[TUP:%.*]] = tuple ([[ARG2]] : $Builtin.NativeObject, [[TUP_1]] : $(Builtin.NativeObject, Builtin.NativeObject))
+// CHECK:   [[TUP_COPY:%.*]] = copy_value [[TUP]]
+// CHECK:   ([[TUP_D_0:%.*]], [[TUP_D_1:%.*]]) = destructure_tuple [[TUP]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK:   store [[TUP_D_0]] to [init] [[PROJ_BOX_0]] : $*Builtin.NativeObject
+// CHECK:   ([[TUP_D_10:%.*]], [[TUP_D_11:%.*]]) = destructure_tuple [[TUP_D_1]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK:   store [[TUP_D_10]] to [init] [[PROJ_BOX_10]] : $*Builtin.NativeObject
+// CHECK:   store [[TUP_D_11]] to [init] [[PROJ_BOX_11]] : $*Builtin.NativeObject
+
+// CHECK:   ([[TUP_D_0:%.*]], [[TUP_D_1:%.*]]) = destructure_tuple [[TUP_COPY]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK:   [[OLD_VALUE:%.*]] = load [take] [[PROJ_BOX_0]]
+// CHECK:   store [[TUP_D_0]] to [init] [[PROJ_BOX_0]] : $*Builtin.NativeObject
+// CHECK:   destroy_value [[OLD_VALUE]]
+// CHECK:   ([[TUP_D_10:%.*]], [[TUP_D_11:%.*]]) = destructure_tuple [[TUP_D_1]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK:   [[OLD_VALUE:%.*]] = load [take] [[PROJ_BOX_10]]
+// CHECK:   store [[TUP_D_10]] to [init] [[PROJ_BOX_10]] : $*Builtin.NativeObject
+// CHECK:   destroy_value [[OLD_VALUE]]
+// CHECK:   [[OLD_VALUE:%.*]] = load [take] [[PROJ_BOX_11]]
+// CHECK:   store [[TUP_D_11]] to [init] [[PROJ_BOX_11]] : $*Builtin.NativeObject
+// CHECK:   destroy_value [[OLD_VALUE]]
+
+// CHECK:   destroy_value [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK: } // end sil function 'test_assigned_owned_2'
+sil @test_assigned_owned_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %1a : @owned $Builtin.NativeObject):
+  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+  %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+  %4 = mark_uninitialized [var] %3 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  %5 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+  %6 = tuple(%1a : $Builtin.NativeObject, %5 : $(Builtin.NativeObject, Builtin.NativeObject))
+  %7 = copy_value %6 : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  assign %6 to %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  assign %7 to %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 04d5077..6c36768 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -1,12 +1,12 @@
-<DeclarationStmt><UnknownDecl>// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
+<UnknownDecl>// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
 // RUN: diff -u %s %t
 // RUN: %swift-syntax-test -input-source-filename %s -parse-gen -print-node-kind > %t.withkinds
 // RUN: diff -u %S/Outputs/round_trip_parse_gen.swift.withkinds %t.withkinds
 
 class C {<UnknownDecl>
-  func bar(_ a: Int) {}</UnknownDecl><UnknownDecl>
-  func bar1(_ a: Float) -> Float { return <UnknownExpr><FloatLiteralExpr>-0.6 </FloatLiteralExpr>+ <FloatLiteralExpr>0.1 </FloatLiteralExpr>- <FloatLiteralExpr>0.3 </FloatLiteralExpr></UnknownExpr>}</UnknownDecl><UnknownDecl>
-  func foo() {<UnknownDecl>
+  func bar(_ a: Int) <CodeBlock>{}</CodeBlock></UnknownDecl><UnknownDecl>
+  func bar1(_ a: Float) -> Float <CodeBlock>{ <UnknownStmt>return <UnknownExpr><FloatLiteralExpr>-0.6 </FloatLiteralExpr>+ <FloatLiteralExpr>0.1 </FloatLiteralExpr>- <FloatLiteralExpr>0.3 </FloatLiteralExpr></UnknownExpr></UnknownStmt>}</CodeBlock></UnknownDecl><UnknownDecl>
+  func foo() <CodeBlock>{<UnknownDecl>
     var a = /*comment*/<StringLiteralExpr>"abc"/*comment*/</StringLiteralExpr></UnknownDecl><UnknownDecl>
     var b = /*comment*/<IntegerLiteralExpr>+2/*comment*/</IntegerLiteralExpr></UnknownDecl><UnknownExpr>
     bar(<IntegerLiteralExpr>1</IntegerLiteralExpr>)</UnknownExpr><UnknownExpr>
@@ -15,5 +15,5 @@
     bar1(<FloatLiteralExpr>-1.1</FloatLiteralExpr>)</UnknownExpr><UnknownExpr>
     bar1(<FloatLiteralExpr>1.1</FloatLiteralExpr>)</UnknownExpr><UnknownDecl>
     var f = /*comments*/<FloatLiteralExpr>+0.1/*comments*/</FloatLiteralExpr></UnknownDecl>
-  }</UnknownDecl>
-}</UnknownDecl></DeclarationStmt>
+  }</CodeBlock></UnknownDecl>
+}</UnknownDecl>
diff --git a/test/decl/protocol/conforms/failure.swift b/test/decl/protocol/conforms/failure.swift
index f61c257..a669f55 100644
--- a/test/decl/protocol/conforms/failure.swift
+++ b/test/decl/protocol/conforms/failure.swift
@@ -100,9 +100,10 @@
   init() { } // expected-note 2{{candidate has non-matching type '()'}}
 }
 
+// Type witness cannot have its own generic parameters
 // FIXME: Crappy diagnostic
 protocol PA {
-  associatedtype A // expected-note 2 {{protocol requires nested type 'A'; do you want to add it?}}
+  associatedtype A // expected-note 3 {{protocol requires nested type 'A'; do you want to add it?}}
 }
 
 struct BadCase1 : PA { // expected-error {{type 'BadCase1' does not conform to protocol 'PA'}}
@@ -113,6 +114,13 @@
   typealias A<T> = T
 }
 
+// Variation on the above
+struct G<T> {}
+
+struct BadCase3 : PA { // expected-error {{type 'BadCase3' does not conform to protocol 'PA'}}
+  typealias A = G
+}
+
 // rdar://problem/32215763
 extension UInt32: ExpressibleByStringLiteral {}
 // expected-error@-1 {{type 'UInt32' does not conform to protocol 'ExpressibleByStringLiteral'}}
diff --git a/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift b/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift
index a9f0963..4fee57d 100644
--- a/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift
+++ b/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift
@@ -645,3 +645,7 @@
     case value
   }
 }
+
+struct GenericCodableStruct<T : Codable> : Codable {}
+
+func foo(_: GenericCodableStruct<Int>.CodingKeys) // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
diff --git a/test/decl/var/default_init.swift b/test/decl/var/default_init.swift
index 0f28437..d21ee17 100644
--- a/test/decl/var/default_init.swift
+++ b/test/decl/var/default_init.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify
+// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify -swift-version 5
 
 // Default initialization of variables.
 
@@ -38,3 +38,16 @@
 
 var global: Int?
 
+class NotInitializableOptionalClass { // expected-error{{class 'NotInitializableOptionalClass' has no initializers}}
+  // Do not perform default initialization for properties with explicitly-spelled 'Optional'.
+  var opt: Optional<Int> // expected-note{{stored property 'opt' without initial value prevents synthesized initializers}}
+}
+
+struct NotInitializableOptionalStruct { // expected-note {{'init(opt:)' declared here}}
+  var opt: Optional<Int>
+}
+
+func testBadDefaultInit() {
+  _ = NotInitializableOptionalStruct() // expected-error {{missing argument for parameter 'opt' in call}}
+  _ = NotInitializableOptionalClass() // expected-error {{'NotInitializableOptionalClass' cannot be constructed because it has no accessible initializers}}
+}