Merge pull request #13256 from gottesmm/pr-32910d38250e0b4150eb84cd3ae8d42ccf6661a6

diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 76b376a..9fd1b87 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -189,13 +189,11 @@
   entity-spec ::= 'Te' bridge-spec           // outlined objective c method call
 
   entity-spec ::= decl-name function-signature generic-signature? 'F'    // function
-  entity-spec ::= storage-spec
+  entity-spec ::= type file-discriminator? 'i' ACCESSOR                  // subscript
+  entity-spec ::= decl-name type 'v' ACCESSOR                            // variable
   entity-spec ::= decl-name type 'fp'                // generic type parameter
   entity-spec ::= decl-name type 'fo'                // enum element (currently not used)
 
-  storage-spec ::= type file-discriminator? 'i' ACCESSOR
-  storage-spec ::= decl-name type 'v' ACCESSOR
-
   ACCESSOR ::= 'm'                           // materializeForSet
   ACCESSOR ::= 's'                           // setter
   ACCESSOR ::= 'g'                           // getter
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index d41ccf7..35d411f 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3117,11 +3117,11 @@
 WARNING(implicitly_unwrapped_optional_spelling_deprecated_with_fixit,none,
         "the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name", ())
 
-WARNING(implicitly_unwrapped_optional_spelling_decay_to_optional,none,
-        "'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead", ())
+WARNING(implicitly_unwrapped_optional_spelling_suggest_optional,none,
+        "using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead", ())
 
-WARNING(implicitly_unwrapped_optional_in_illegal_position_decay_to_optional,none,
-        "'!' is not allowed here; interpreting this as '?' instead", ())
+WARNING(implicitly_unwrapped_optional_in_illegal_position_suggest_optional,none,
+        "using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead", ())
 
 ERROR(implicitly_unwrapped_optional_spelling_error,none,
         "the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use an explicit type followed by '!'", ())
diff --git a/include/swift/Syntax/SyntaxParsingContext.h b/include/swift/Syntax/SyntaxParsingContext.h
index c1256d7..7373d00 100644
--- a/include/swift/Syntax/SyntaxParsingContext.h
+++ b/include/swift/Syntax/SyntaxParsingContext.h
@@ -33,6 +33,7 @@
   Expr,
   Type,
   Pattern,
+  Syntax,
 };
 
 /// Indicates what action should be performed on the destruction of
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index fc85b1f..0349d52 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -747,13 +747,13 @@
     // terms of the specialized types, not the conformance-declaring decl's
     // types.
     auto nominal = GenericConformance->getType()->getAnyNominal();
-    auto subMap =
-      getType()->getContextSubstitutionMap(nominal->getModuleContext(),
-                                           nominal);
+    auto module = nominal->getModuleContext();
+    auto subMap = getType()->getContextSubstitutionMap(module, nominal);
 
     SmallVector<Requirement, 4> newReqs;
     for (auto oldReq : GenericConformance->getConditionalRequirements()) {
-      if (auto newReq = oldReq.subst(subMap))
+      if (auto newReq = oldReq.subst(QuerySubstitutionMap{subMap},
+                                     LookUpConformanceInModule(module)))
         newReqs.push_back(*newReq);
     }
     auto &ctxt = getProtocol()->getASTContext();
diff --git a/lib/IDE/CommentConversion.cpp b/lib/IDE/CommentConversion.cpp
index 25074e0..44cb237 100644
--- a/lib/IDE/CommentConversion.cpp
+++ b/lib/IDE/CommentConversion.cpp
@@ -408,14 +408,15 @@
   std::string S;
   llvm::raw_string_ostream SS(S);
   D->print(SS, Options);
-  std::string Signature = SS.str();
   auto OI = Doc.find(Open);
   auto CI = Doc.find(Close);
-  if (StringRef::npos != OI && StringRef::npos != CI && CI > OI)
-    OS << Doc.substr(0, OI) << Open << Signature << Close <<
-      Doc.substr(CI + Close.size());
-  else
+  if (StringRef::npos != OI && StringRef::npos != CI && CI > OI) {
+    OS << Doc.substr(0, OI) << Open;
+    appendWithXMLEscaping(OS, SS.str());
+    OS << Close << Doc.substr(CI + Close.size());
+  } else {
     OS << Doc;
+  }
 }
 
 static LineList getLineListFromComment(SourceManager &SourceMgr,
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index 3285596..7776b2d 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -945,7 +945,7 @@
         llvm::MapVector<CanType, llvm::Value *> &typeToMetadataVec,
         SILType T) const override {
       auto canType = T.getSwiftRValueType();
-      assert(!canType->hasArchetype() &&
+      assert(!canType->is<ArchetypeType>() &&
              "collectArchetypeMetadata: no archetype expected here");
     }
 
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index 22c1df0..84247a4 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -1397,6 +1397,5 @@
     llvm::MapVector<CanType, llvm::Value *> &typeToMetadataVec,
     SILType T) const {
   auto canType = T.getSwiftRValueType();
-  assert(!canType->getWithoutSpecifierType()->is<ArchetypeType>() &&
-         "Did not expect an ArchetypeType");
+  assert(!canType->is<ArchetypeType>() && "Did not expect an ArchetypeType");
 }
diff --git a/lib/Migrator/TupleSplatMigratorPass.cpp b/lib/Migrator/TupleSplatMigratorPass.cpp
index 717c120..15c9607 100644
--- a/lib/Migrator/TupleSplatMigratorPass.cpp
+++ b/lib/Migrator/TupleSplatMigratorPass.cpp
@@ -76,53 +76,94 @@
 
 struct TupleSplatMigratorPass : public ASTMigratorPass,
   public SourceEntityWalker {
-    
-  bool handleClosureShorthandMismatch(FunctionConversionExpr *FC) {
-    if (!SF->getASTContext().LangOpts.isSwiftVersion3() || !FC->isImplicit() ||
-        !isa<ClosureExpr>(FC->getSubExpr())) {
-      return false;
-    }
 
-    auto *Closure = cast<ClosureExpr>(FC->getSubExpr());
-    if (Closure->getInLoc().isValid())
+  llvm::DenseSet<FunctionConversionExpr*> CallArgFuncConversions;
+
+  void blacklistFuncConversionArgs(CallExpr *CE) {
+    if (CE->isImplicit() || !SF->getASTContext().LangOpts.isSwiftVersion3())
+      return;
+
+    Expr *Arg = CE->getArg();
+    if (auto *Shuffle = dyn_cast<TupleShuffleExpr>(Arg))
+      Arg = Shuffle->getSubExpr();
+
+    if (auto *Paren = dyn_cast<ParenExpr>(Arg)) {
+      if (auto FC = dyn_cast_or_null<FunctionConversionExpr>(Paren->getSubExpr()))
+        CallArgFuncConversions.insert(FC);
+    } else if (auto *Tuple = dyn_cast<TupleExpr>(Arg)){
+      for (auto Elem : Tuple->getElements()) {
+        if (auto *FC = dyn_cast_or_null<FunctionConversionExpr>(Elem))
+          CallArgFuncConversions.insert(FC);
+      }
+    }
+  }
+
+  ClosureExpr *getShorthandClosure(Expr *E) {
+    if (auto *Closure = dyn_cast_or_null<ClosureExpr>(E)) {
+      if (Closure->hasAnonymousClosureVars())
+        return Closure;
+    }
+    return nullptr;
+  }
+
+  bool handleClosureShorthandMismatch(const FunctionConversionExpr *FC) {
+    if (!SF->getASTContext().LangOpts.isSwiftVersion3() || !FC->isImplicit())
+      return false;
+
+    ClosureExpr *Closure = getShorthandClosure(FC->getSubExpr());
+    if (!Closure)
       return false;
 
     FunctionType *FuncTy = FC->getType()->getAs<FunctionType>();
 
     unsigned NativeArity = FuncTy->getParams().size();
     unsigned ClosureArity = Closure->getParameters()->size();
-    if (NativeArity <= ClosureArity)
+    if (NativeArity == ClosureArity)
       return false;
 
-    ShorthandFinder Finder(Closure);
-
     if (ClosureArity == 1 && NativeArity > 1) {
       // Remove $0. from existing references or if it's only $0, replace it
       // with a tuple of the native arity, e.g. ($0, $1, $2)
-      Finder.forEachReference([this, NativeArity](Expr *Ref, ParamDecl *Def) {
-        if (auto *TE = dyn_cast<TupleElementExpr>(Ref)) {
-          SourceLoc Start = TE->getStartLoc();
-          SourceLoc End = TE->getLoc();
-          Editor.replace(CharSourceRange(SM, Start, End), "$");
-        } else {
-          std::string TupleText;
-          {
-            llvm::raw_string_ostream OS(TupleText);
-            for (size_t i = 1; i < NativeArity; ++i) {
-              OS << ", $" << i;
+      ShorthandFinder(Closure)
+        .forEachReference([this, NativeArity](Expr *Ref, ParamDecl *Def) {
+          if (auto *TE = dyn_cast<TupleElementExpr>(Ref)) {
+            SourceLoc Start = TE->getStartLoc();
+            SourceLoc End = TE->getLoc();
+            Editor.replace(CharSourceRange(SM, Start, End), "$");
+          } else {
+            std::string TupleText;
+            {
+              llvm::raw_string_ostream OS(TupleText);
+              for (size_t i = 1; i < NativeArity; ++i) {
+                OS << ", $" << i;
+              }
+              OS << ")";
             }
-            OS << ")";
+            Editor.insert(Ref->getStartLoc(), "(");
+            Editor.insertAfterToken(Ref->getEndLoc(), TupleText);
           }
-          Editor.insert(Ref->getStartLoc(), "(");
-          Editor.insertAfterToken(Ref->getEndLoc(), TupleText);
-        }
-      });
+        });
+      return true;
+    }
+
+    // This direction is only needed if not passed as a call argument. e.g.
+    // someFunc({ $0 > $1 }) // doesn't need migration
+    // let x: ((Int, Int)) -> Bool = { $0 > $1 } // needs migration
+    if (NativeArity == 1 && ClosureArity > 1 && !CallArgFuncConversions.count(FC)) {
+      // Prepend $0. to existing references
+      ShorthandFinder(Closure)
+        .forEachReference([this](Expr *Ref, ParamDecl *Def) {
+          if (auto *TE = dyn_cast<TupleElementExpr>(Ref))
+            Ref = TE->getBase();
+          SourceLoc AfterDollar = Ref->getStartLoc().getAdvancedLoc(1);
+          Editor.insert(AfterDollar, "0.");
+        });
       return true;
     }
     return false;
   }
 
-      /// Migrates code that compiles fine in Swift 3 but breaks in Swift 4 due to
+  /// Migrates code that compiles fine in Swift 3 but breaks in Swift 4 due to
   /// changes in how the typechecker handles tuple arguments.
   void handleTupleArgumentMismatches(const CallExpr *E) {
     if (!SF->getASTContext().LangOpts.isSwiftVersion3())
@@ -169,6 +210,7 @@
     if (auto *FCE = dyn_cast<FunctionConversionExpr>(E)) {
       handleClosureShorthandMismatch(FCE);
     } else if (auto *CE = dyn_cast<CallExpr>(E)) {
+      blacklistFuncConversionArgs(CE);
       handleTupleArgumentMismatches(CE);
     }
     return true;
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 06b0755..ef9805c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2282,16 +2282,27 @@
         StaticLoc = Tok.getLoc();
         StaticSpelling = StaticSpellingKind::KeywordStatic;
       }
+      SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
       consumeToken(tok::kw_static);
+      // Static modifier doesn't have more details.
+      SyntaxParsingContext DetailContext(SyntaxContext, SyntaxKind::TokenList);
       continue;
     }
     // 'class' is a modifier on func, but is also a top-level decl.
     case tok::kw_class: {
-      SourceLoc ClassLoc = consumeToken(tok::kw_class);
-
+      SourceLoc ClassLoc;
+      bool AsModifier;
+      {
+        BacktrackingScope Scope(*this);
+        ClassLoc = consumeToken(tok::kw_class);
+        AsModifier = isStartOfDecl();
+      }
       // If 'class' is a modifier on another decl kind, like var or func,
       // then treat it as a modifier.
-      if (isStartOfDecl()) {
+      if (AsModifier) {
+        SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
+        consumeToken(tok::kw_class);
+        SyntaxParsingContext DetailContext(SyntaxContext, SyntaxKind::TokenList);
         if (StaticLoc.isValid()) {
           diagnose(Tok, diag::decl_already_static,
                    StaticSpellingKind::KeywordClass)
@@ -2303,6 +2314,7 @@
         continue;
       }
 
+      consumeToken(tok::kw_class);
       // Otherwise this is the start of a class declaration.
       DeclResult = parseDeclClass(ClassLoc, Flags, Attributes);
       break;
@@ -2312,6 +2324,7 @@
     case tok::kw_fileprivate:
     case tok::kw_internal:
     case tok::kw_public: {
+      SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
       // We still model these specifiers as attributes.
       parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_AccessControl);
       continue;
@@ -2356,6 +2369,7 @@
         Kind = DAK_Convenience;
       }
       if (Kind) {
+        SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
         parseNewDeclAttribute(Attributes, SourceLoc(), *Kind);
         continue;
       }
diff --git a/lib/Parse/ParseGeneric.cpp b/lib/Parse/ParseGeneric.cpp
index d5f83da..be5d54f 100644
--- a/lib/Parse/ParseGeneric.cpp
+++ b/lib/Parse/ParseGeneric.cpp
@@ -22,6 +22,7 @@
 #include "swift/Syntax/SyntaxNodes.h"
 #include "swift/Syntax/SyntaxParsingContext.h"
 using namespace swift;
+using namespace swift::syntax;
 
 /// parseGenericParameters - Parse a sequence of generic parameters, e.g.,
 /// < T : Comparable, U : Container> along with an optional requires clause.
@@ -245,11 +246,17 @@
                SmallVectorImpl<RequirementRepr> &Requirements,
                bool &FirstTypeInComplete,
                bool AllowLayoutConstraints) {
+  SyntaxParsingContext ClauseContext(SyntaxContext,
+                                     SyntaxKind::GenericWhereClause);
   ParserStatus Status;
   // Parse the 'where'.
   WhereLoc = consumeToken(tok::kw_where);
   FirstTypeInComplete = false;
+  SyntaxParsingContext ReqListContext(SyntaxContext,
+                                      SyntaxKind::GenericRequirementList);
+  bool HasNextReq;
   do {
+    SyntaxParsingContext ReqContext(SyntaxContext, SyntaxContextKind::Syntax);
     // Parse the leading type-identifier.
     auto FirstTypeResult = parseTypeIdentifier();
     if (FirstTypeResult.hasSyntax())
@@ -269,7 +276,7 @@
     if (Tok.is(tok::colon)) {
       // A conformance-requirement.
       SourceLoc ColonLoc = consumeToken();
-
+      ReqContext.setCreateSyntax(SyntaxKind::ConformanceRequirement);
       if (Tok.is(tok::identifier) &&
           getLayoutConstraint(Context.getIdentifier(Tok.getText()), Context)
               ->isKnownLayout()) {
@@ -309,6 +316,7 @@
       }
     } else if ((Tok.isAnyOperator() && Tok.getText() == "==") ||
                Tok.is(tok::equal)) {
+      ReqContext.setCreateSyntax(SyntaxKind::SameTypeRequirement);
       // A same-type-requirement
       if (Tok.is(tok::equal)) {
         diagnose(Tok, diag::requires_single_equal)
@@ -334,8 +342,9 @@
       Status.setIsParseError();
       break;
     }
+    HasNextReq = consumeIf(tok::comma);
     // If there's a comma, keep parsing the list.
-  } while (consumeIf(tok::comma));
+  } while (HasNextReq);
 
   if (Requirements.empty())
     WhereLoc = SourceLoc();
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index d503baa..97650fe 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -467,7 +467,7 @@
 
   // Subtype conversions:
 
-  //  - upcasts
+  //  - upcasts for classes
   if (outputSubstType->getClassOrBoundGenericClass() &&
       inputSubstType->getClassOrBoundGenericClass()) {
     auto class1 = inputSubstType->getClassOrBoundGenericClass();
@@ -490,6 +490,32 @@
     }
   }
 
+  // - upcasts for collections
+  if (outputSubstType->getStructOrBoundGenericStruct() &&
+      inputSubstType->getStructOrBoundGenericStruct()) {
+    auto *inputStruct = inputSubstType->getStructOrBoundGenericStruct();
+    auto *outputStruct = outputSubstType->getStructOrBoundGenericStruct();
+
+    // Attempt collection upcast only if input and output declarations match.
+    if (inputStruct == outputStruct) {
+      FuncDecl *fn = nullptr;
+      auto &ctx = SGF.getASTContext();
+      if (inputStruct == ctx.getArrayDecl()) {
+        fn = SGF.SGM.getArrayForceCast(Loc);
+      } else if (inputStruct == ctx.getDictionaryDecl()) {
+        fn = SGF.SGM.getDictionaryUpCast(Loc);
+      } else if (inputStruct == ctx.getSetDecl()) {
+        fn = SGF.SGM.getSetUpCast(Loc);
+      } else {
+        llvm_unreachable("unsupported collection upcast kind");
+      }
+
+      return SGF.emitCollectionConversion(Loc, fn, inputSubstType,
+                                          outputSubstType, v, ctxt)
+                .getScalarValue();
+    }
+  }
+
   //  - upcasts from an archetype
   if (outputSubstType->getClassOrBoundGenericClass()) {
     if (auto archetypeType = dyn_cast<ArchetypeType>(inputSubstType)) {
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 3a55afb..0625e61 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -161,8 +161,6 @@
     if (!conformance)
       return nullptr;
   }
-  assert(conformance->getConditionalRequirements().empty() &&
-         "unhandled conditional conformance");
 
   // For a type with dependent conformance, just return the requirement from
   // the protocol. There are no protocol conformance tables.
@@ -6608,8 +6606,6 @@
   auto conformance = tc.conformsToProtocol(type, protocol, cs.DC,
                                            ConformanceCheckFlags::InExpression);
   assert(conformance && "must conform to literal protocol");
-  assert(conformance->getConditionalRequirements().empty() &&
-         "unexpected conditional requirements");
 
   // Figure out the (non-builtin) argument type if there is one.
   Type argType;
@@ -6752,8 +6748,6 @@
   auto conformance = tc.conformsToProtocol(type, protocol, cs.DC,
                                            ConformanceCheckFlags::InExpression);
   assert(conformance && "must conform to literal protocol");
-  assert(conformance->getConditionalRequirements().empty() &&
-         "unexpected conditional requirements");
 
   // Dig out the literal type and perform a builtin literal conversion to it.
   if (!literalType.empty()) {
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index fd39811..b63727a 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -2090,8 +2090,7 @@
     }
     
     // Special implicit nominal conversions.
-    if (!type1->is<LValueType>() &&
-        kind >= ConstraintKind::Conversion) {
+    if (!type1->is<LValueType>() && kind >= ConstraintKind::Subtype) {
       // Array -> Array.
       if (isArrayType(desugar1) && isArrayType(desugar2)) {
         assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index fee6907..08f48a3 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3002,13 +3002,7 @@
     // primitive literal protocols.
     auto conformsToProtocol = [&](KnownProtocolKind protoKind) {
         ProtocolDecl *proto = TC.getProtocol(ED->getLoc(), protoKind);
-        auto conformance =
-            TC.conformsToProtocol(rawTy, proto, ED->getDeclContext(), None);
-        if (conformance)
-          assert(conformance->getConditionalRequirements().empty() &&
-                 "conditionally conforming to literal protocol not currently "
-                 "supported");
-        return conformance;
+        return TC.conformsToProtocol(rawTy, proto, ED->getDeclContext(), None);
     };
 
     static auto otherLiteralProtocolKinds = {
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 85f444b..4e48289 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -6209,9 +6209,6 @@
                      (ConformanceCheckFlags::SuppressDependencyTracking|
                       ConformanceCheckFlags::Used));
   if (conformance && conformance->isConcrete()) {
-    assert(conformance->getConditionalRequirements().empty() &&
-           "cannot conform condtionally to _ErrorCodeProtocol");
-
     if (Type errorType = ProtocolConformanceRef::getTypeWitnessByName(
           type, *conformance, Context.Id_ErrorType, this)) {
       (void)conformsToProtocol(errorType, bridgedStoredNSError, dc,
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index a24595c..be860b1 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -670,9 +670,6 @@
                             sequence->getLoc());
     if (!genConformance)
       return nullptr;
-    assert(
-        genConformance->getConditionalRequirements().empty() &&
-        "conditionally conforming to IteratorProtocol not currently supported");
 
     Type elementTy = TC.getWitnessType(generatorTy, generatorProto,
                                        *genConformance, TC.Context.Id_Element,
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 28d1106..5bcfc48 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -1130,14 +1130,6 @@
 
   auto id = comp->getIdentifier();
 
-  // If we're compiling for Swift version < 5 and we have a mention of
-  // ImplicitlyUnwrappedOptional where it is not allowed, treat it as
-  // if it was spelled Optional.
-  if (id == TC.Context.Id_ImplicitlyUnwrappedOptional
-      && !options.contains(TypeResolutionFlags::AllowIUO)
-      && !TC.Context.isSwiftVersionAtLeast(5))
-    id = TC.Context.Id_Optional;
-
   NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
   if (options.contains(TypeResolutionFlags::KnownNonCascadingDependency))
     lookupOptions |= NameLookupFlags::KnownPrivate;
@@ -1239,7 +1231,7 @@
       }
     } else if (isa<GenericIdentTypeRepr>(comp)) {
       Diagnostic diag =
-          diag::implicitly_unwrapped_optional_spelling_decay_to_optional;
+          diag::implicitly_unwrapped_optional_spelling_suggest_optional;
 
       if (TC.Context.isSwiftVersionAtLeast(5))
         diag = diag::implicitly_unwrapped_optional_spelling_in_illegal_position;
@@ -1258,7 +1250,7 @@
               genericTyR->getAngleBrackets().End.getAdvancedLoc(1));
     } else {
       Diagnostic diag =
-          diag::implicitly_unwrapped_optional_spelling_decay_to_optional;
+          diag::implicitly_unwrapped_optional_spelling_suggest_optional;
 
       if (TC.Context.isSwiftVersionAtLeast(5))
         diag = diag::
@@ -2847,7 +2839,7 @@
        TypeResolutionOptions options) {
   if (!options.contains(TypeResolutionFlags::AllowIUO)) {
     Diagnostic diag = diag::
-        implicitly_unwrapped_optional_in_illegal_position_decay_to_optional;
+        implicitly_unwrapped_optional_in_illegal_position_suggest_optional;
 
     if (TC.Context.isSwiftVersionAtLeast(5))
       diag = diag::implicitly_unwrapped_optional_in_illegal_position;
@@ -2865,12 +2857,8 @@
   if (!baseTy || baseTy->hasError()) return baseTy;
 
   Type uncheckedOptionalTy;
-  if (!options.contains(TypeResolutionFlags::AllowIUO))
-    // Treat IUOs in illegal positions as optionals.
-    uncheckedOptionalTy = TC.getOptionalType(repr->getExclamationLoc(), baseTy);
-  else
-    uncheckedOptionalTy = TC.getImplicitlyUnwrappedOptionalType(
-        repr->getExclamationLoc(), baseTy);
+  uncheckedOptionalTy =
+      TC.getImplicitlyUnwrappedOptionalType(repr->getExclamationLoc(), baseTy);
 
   if (!uncheckedOptionalTy)
     return ErrorType::get(Context);
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index 1afdb90..43d65ec 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -158,6 +158,9 @@
       if (!RawNode->isPattern())
         return makeUnknownSyntax(SyntaxKind::UnknownPattern, Parts);
       break;
+    case SyntaxContextKind::Syntax:
+      // We don't need to coerce in this case.
+      break;
     }
     return RawNode;
   } else {
@@ -178,6 +181,9 @@
     case SyntaxContextKind::Pattern:
       UnknownKind = SyntaxKind::UnknownPattern;
       break;
+    case SyntaxContextKind::Syntax:
+      UnknownKind = SyntaxKind::Unknown;
+      break;
     }
     return makeUnknownSyntax(UnknownKind, Parts);
   }
diff --git a/test/Constraints/array_literal.swift b/test/Constraints/array_literal.swift
index 1d12aee..e5c212e 100644
--- a/test/Constraints/array_literal.swift
+++ b/test/Constraints/array_literal.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -enable-experimental-conditional-conformances
 
 struct IntList : ExpressibleByArrayLiteral {
   typealias Element = Int
@@ -322,3 +322,21 @@
 //        accident.
 let SR3786a: [Int] = [1, 2, 3]
 let SR3786aa = [SR3786a.reversed(), SR3786a]
+
+// Conditional conformance
+protocol P { }
+
+struct PArray<T> { }
+
+extension PArray : ExpressibleByArrayLiteral where T: P {
+  typealias ArrayLiteralElement = T
+
+  init(arrayLiteral elements: T...) { }
+}
+
+extension Int: P { }
+
+func testConditional(i: Int, s: String) {
+  let _: PArray<Int> = [i, i, i]
+  let _: PArray<String> = [s, s, s] // expected-error{{contextual type 'PArray<String>' cannot be used with array literal}}
+}
diff --git a/test/Generics/conditional_conformances.swift b/test/Generics/conditional_conformances.swift
index b1a9e00..c71bd0f 100644
--- a/test/Generics/conditional_conformances.swift
+++ b/test/Generics/conditional_conformances.swift
@@ -334,3 +334,29 @@
   _ = Free<T>() as P2 // expected-error{{'Free<T>' is not convertible to 'P2'; did you mean to use 'as!' to force downcast?}}
 }
 
+// rdar://problem/35837054
+protocol P7 { }
+
+protocol P8 {
+  associatedtype A
+}
+
+struct X0 { }
+
+struct X1 { }
+
+extension X1: P8 {
+  typealias A = X0
+}
+
+struct X2<T> { }
+
+extension X2: P7 where T: P8, T.A: P7 { }
+
+func takesF7<T: P7>(_: T) { }
+func passesConditionallyNotF7(x21: X2<X1>) {
+  takesF7(x21) // expected-error{{type 'X1.A' (aka 'X0') does not conform to protocol 'P7'}}
+  // expected-error@-1{{'<T where T : P7> (T) -> ()' requires that 'X1.A' (aka 'X0') conform to 'P7'}}
+  // expected-note@-2{{requirement specified as 'X1.A' (aka 'X0') : 'P7'}}
+  // expected-note@-3{{requirement from conditional conformance of 'X2<X1>' to 'P7'}}
+}
diff --git a/test/Interpreter/FunctionConversion.swift b/test/Interpreter/FunctionConversion.swift
index d3c6f35..31d2d02 100644
--- a/test/Interpreter/FunctionConversion.swift
+++ b/test/Interpreter/FunctionConversion.swift
@@ -241,4 +241,61 @@
   do { try print(g()) } catch {}
 }
 
+class A: Quilt {
+  var n: Int8 {
+    return 42
+  }
+}
+
+func rdar35702810_arr<T: Quilt>(type: T.Type, _ fn: ([T]?) -> Int8) -> Int8 {
+  let x: [T] = [A() as! T]
+  return fn(x)
+}
+
+func rdar35702810_map<T: Quilt>(type: T.Type, _ fn: ([String: T]) -> Int8) -> Int8 {
+  let x: [String: T] = ["ultimate question": A() as! T]
+  return fn(x)
+}
+
+FunctionConversionTestSuite.test("CollectionUpCastsInFuncParameters") {
+  let fn_arr: ([Quilt]?) -> Int8 = { v in v![0].n }
+  let fn_map: ([String: Quilt]) -> Int8 = { v in v["ultimate question"]!.n }
+
+  expectEqual(rdar35702810_arr(type: A.self, fn_arr), 42)
+  expectEqual(rdar35702810_map(type: A.self, fn_map), 42)
+}
+
+protocol X: Hashable {}
+class B: X {
+  var hashValue: Int { return 42 }
+  static func == (lhs: B, rhs: B) -> Bool {
+    return lhs.hashValue == rhs.hashValue
+  }
+}
+
+func rdar35702810_arr_hashable<T: X>(type: T.Type, _ fn: ([T]?) -> Int) -> Int {
+  let x: [T] = [B() as! T]
+  return fn(x)
+}
+
+func rdar35702810_map_hashable<T: X>(type: T.Type, _ fn: ([String: T]) -> Int) -> Int {
+  let x: [String: T] = ["ultimate question": B() as! T]
+  return fn(x)
+}
+
+func rdar35702810_set_hashable<T: X>(type: T.Type, _ fn: (Set<T>) -> Int) -> Int {
+  let x: Set<T> = [B() as! T]
+  return fn(x)
+}
+
+FunctionConversionTestSuite.test("CollectionUpCastsWithHashableInFuncParameters") {
+  let fn_arr: ([AnyHashable]?) -> Int = { v in v![0].hashValue }
+  let fn_map: ([String: AnyHashable]) -> Int = { v in v["ultimate question"]!.hashValue }
+  let fn_set: (Set<AnyHashable>) -> Int = { v in v.first!.hashValue }
+
+  expectEqual(rdar35702810_arr_hashable(type: B.self, fn_arr), 42)
+  expectEqual(rdar35702810_map_hashable(type: B.self, fn_map), 42)
+  expectEqual(rdar35702810_set_hashable(type: B.self, fn_set), 42)
+}
+
 runAllTests()
diff --git a/test/Migrator/Inputs/API.json b/test/Migrator/Inputs/API.json
index 1288127..822b318 100644
--- a/test/Migrator/Inputs/API.json
+++ b/test/Migrator/Inputs/API.json
@@ -319,7 +319,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "WrapOptional",
     "ChildIndex": "1",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -330,7 +330,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "WrapOptional",
     "ChildIndex": "1",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -341,7 +341,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "WrapOptional",
     "ChildIndex": "1",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -352,7 +352,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "ImplicitOptionalToOptional",
     "ChildIndex": "1:0",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -363,7 +363,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "UnwrapOptional",
     "ChildIndex": "1:1:0",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
diff --git a/test/Migrator/tuple-arguments.swift b/test/Migrator/tuple-arguments.swift
index 33df8a1..19c75b4 100644
--- a/test/Migrator/tuple-arguments.swift
+++ b/test/Migrator/tuple-arguments.swift
@@ -59,3 +59,7 @@
 
 let dictionary: [String: String] = [:]
 _ = dictionary.first { (column, value) in true }!.value
+
+func doit(_ x: Int) -> Bool { return x > 0 }
+let _: ((String, Int)) -> [String:Bool] = { [$0: doit($1)] }
+func returnClosure() -> ((Int, Int)) -> Bool { return {$1 > $0} }
diff --git a/test/Migrator/tuple-arguments.swift.expected b/test/Migrator/tuple-arguments.swift.expected
index f64a3a7..65eb8a1 100644
--- a/test/Migrator/tuple-arguments.swift.expected
+++ b/test/Migrator/tuple-arguments.swift.expected
@@ -59,3 +59,7 @@
 
 let dictionary: [String: String] = [:]
 _ = dictionary.first { (column, value) in true }!.value
+
+func doit(_ x: Int) -> Bool { return x > 0 }
+let _: ((String, Int)) -> [String:Bool] = { [$0.0: doit($0.1)] }
+func returnClosure() -> ((Int, Int)) -> Bool { return {$0.1 > $0.0} }
diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift
index e08a19b4..bdc2502 100644
--- a/test/SILGen/function_conversion.swift
+++ b/test/SILGen/function_conversion.swift
@@ -598,3 +598,59 @@
 // CHECK-NEXT:    dealloc_stack [[OPTIONAL_VALUE]]
 // CHECK-NEXT:    dealloc_stack [[ANY_VALUE]]
 // CHECK-NEXT:    return
+
+// ==== Support collection subtyping in function argument position
+
+protocol Z {}
+class A: Z {}
+
+func foo_arr<T: Z>(type: T.Type, _ fn: ([T]?) -> Void) {}
+func foo_map<T: Z>(type: T.Type, _ fn: ([Int: T]) -> Void) {}
+
+func rdar35702810() {
+  let fn_arr: ([Z]?) -> Void = { _ in }
+  let fn_map: ([Int: Z]) -> Void = { _ in }
+
+  // CHECK: function_ref @_T0s15_arrayForceCastSayq_GSayxGr0_lF : $@convention(thin) <τ_0_0, τ_0_1> (@owned Array<τ_0_0>) -> @owned Array<τ_0_1>
+  // CHECK: apply %4<A, Z>(%3) : $@convention(thin) <τ_0_0, τ_0_1> (@owned Array<τ_0_0>) -> @owned Array<τ_0_1>
+  foo_arr(type: A.self, fn_arr)
+
+  // CHECK: function_ref @_T0s17_dictionaryUpCasts10DictionaryVyq0_q1_GACyxq_Gs8HashableRzsAFR0_r2_lF : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
+  // CHECK: apply %2<Int, A, Int, Z>(%0) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
+  // CHECK: apply %1(%3) : $@callee_guaranteed (@owned Dictionary<Int, Z>) -> ()
+  foo_map(type: A.self, fn_map)
+}
+
+protocol X: Hashable {}
+class B: X {
+  var hashValue: Int { return 42 }
+  static func == (lhs: B, rhs: B) -> Bool {
+    return lhs.hashValue == rhs.hashValue
+  }
+}
+
+func bar_arr<T: X>(type: T.Type, _ fn: ([T]?) -> Void) {}
+func bar_map<T: X>(type: T.Type, _ fn: ([T: Int]) -> Void) {}
+func bar_set<T: X>(type: T.Type, _ fn: (Set<T>) -> Void) {}
+
+func rdar35702810_anyhashable() {
+  let fn_arr: ([AnyHashable]?) -> Void = { _ in }
+  let fn_map: ([AnyHashable: Int]) -> Void = { _ in }
+  let fn_set: (Set<AnyHashable>) -> Void = { _ in }
+
+
+  // CHECK: function_ref @_T0Says11AnyHashableVGSgIegx_Say19function_conversion1BCGSgIgx_TR : $@convention(thin) (@owned Optional<Array<B>>, @guaranteed @callee_guaranteed (@owned Optional<Array<AnyHashable>>) -> ()) -> ()
+  // CHECK: partial_apply [callee_guaranteed] %12(%11) : $@convention(thin) (@owned Optional<Array<B>>, @guaranteed @callee_guaranteed (@owned Optional<Array<AnyHashable>>) -> ()) -> ()
+  // CHECK: convert_function %13 : $@callee_guaranteed (@owned Optional<Array<B>>) -> () to $@noescape @callee_guaranteed (@owned Optional<Array<B>>) -> ()
+  bar_arr(type: B.self, fn_arr)
+
+  // CHECK: function_ref @_T0s10DictionaryVys11AnyHashableVSiGIegx_ABy19function_conversion1BCSiGIgx_TR : $@convention(thin) (@owned Dictionary<B, Int>, @guaranteed @callee_guaranteed (@owned Dictionary<AnyHashable, Int>) -> ()) -> ()
+  // CHECK: partial_apply [callee_guaranteed] %21(%20) : $@convention(thin) (@owned Dictionary<B, Int>, @guaranteed @callee_guaranteed (@owned Dictionary<AnyHashable, Int>) -> ()) -> ()
+  // CHECK: convert_function %22 : $@callee_guaranteed (@owned Dictionary<B, Int>) -> () to $@noescape @callee_guaranteed (@owned Dictionary<B, Int>) -> ()
+  bar_map(type: B.self, fn_map)
+
+  // CHECK: function_ref @_T0s3SetVys11AnyHashableVGIegx_ABy19function_conversion1BCGIgx_TR : $@convention(thin) (@owned Set<B>, @guaranteed @callee_guaranteed (@owned Set<AnyHashable>) -> ()) -> ()
+  // CHECK: partial_apply [callee_guaranteed] %30(%29) : $@convention(thin) (@owned Set<B>, @guaranteed @callee_guaranteed (@owned Set<AnyHashable>) -> ()) -> ()
+  // CHECK: convert_function %31 : $@callee_guaranteed (@owned Set<B>) -> () to $@noescape @callee_guaranteed (@owned Set<B>) -> ()
+  bar_set(type: B.self, fn_set)
+}
diff --git a/test/SILOptimizer/devirt_class_witness_method.sil b/test/SILOptimizer/devirt_class_witness_method.sil
index 21e7796..6632c0f 100644
--- a/test/SILOptimizer/devirt_class_witness_method.sil
+++ b/test/SILOptimizer/devirt_class_witness_method.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -devirtualizer -sil-combine -enable-resilience | tee /tmp/xxx | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -devirtualizer -sil-combine -enable-resilience | %FileCheck %s
 sil_stage canonical
 
 import Builtin
diff --git a/test/Sema/diag_deprecated_iuo.swift b/test/Sema/diag_deprecated_iuo.swift
index be357e0..8a44304 100644
--- a/test/Sema/diag_deprecated_iuo.swift
+++ b/test/Sema/diag_deprecated_iuo.swift
@@ -27,10 +27,7 @@
 let _: ImplicitlyUnwrappedOptional<Int> = 1 // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name}}{{8-36=}} {{39-39=!}} {{39-40=}}
 let _: ImplicitlyUnwrappedOptional = 1 // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use an explicit type followed by '!'}}
 
-extension ImplicitlyUnwrappedOptional { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{11-38=Optional}}
-  func unwrap() -> Wrapped {
-   return self.unsafelyUnwrapped
-  }
+extension ImplicitlyUnwrappedOptional { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{11-38=Optional}}
 }
 
 func functionSpelling(
@@ -48,8 +45,8 @@
 
 // Not okay because '!' is not at the top level of the type.
 func functionSigilArray(
-  _: [Int!] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-) -> [Int!] { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
+  _: [Int!] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+) -> [Int!] { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
   return [1]
 }
 
@@ -68,12 +65,12 @@
 
 func genericFunctionSigilArray<T>(
   // FIXME: We validate these types multiple times resulting in multiple diagnostics
-  iuo: [T!] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-  // expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-  // expected-warning@-2 {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-) -> [T!] { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  // expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  // expected-warning@-2 {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
+  iuo: [T!] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+  // expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+  // expected-warning@-2 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+) -> [T!] { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  // expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  // expected-warning@-2 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
   return iuo
 }
 
@@ -83,16 +80,16 @@
 }
 
 struct S : P {
-  typealias T = ImplicitlyUnwrappedOptional<Int> // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{17-45=}} {{48-48=?}} {{48-49=}}
-  typealias U = Optional<ImplicitlyUnwrappedOptional<Int>> // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{26-54=}} {{57-57=?}} {{57-58=}}
+  typealias T = ImplicitlyUnwrappedOptional<Int> // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{17-45=}} {{48-48=?}} {{48-49=}}
+  typealias U = Optional<ImplicitlyUnwrappedOptional<Int>> // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{26-54=}} {{57-57=?}} {{57-58=}}
 
-  typealias V = Int!  // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{20-21=?}}
-  typealias W = Int!? // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{20-21=?}}
+  typealias V = Int!  // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{20-21=?}}
+  typealias W = Int!? // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{20-21=?}}
 
   var x: V
   var y: W
-  var fn1: (Int!) -> Int // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{16-17=?}}
-  var fn2: (Int) -> Int! // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{24-25=?}}
+  var fn1: (Int!) -> Int // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{16-17=?}}
+  var fn2: (Int) -> Int! // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{24-25=?}}
 
   subscript (
     index: ImplicitlyUnwrappedOptional<Int> // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name}}{{12-40=}} {{43-43=!}} {{43-44=}}
@@ -107,100 +104,100 @@
   }
 }
 
-func generic<T : P>(_: T) where T.T == ImplicitlyUnwrappedOptional<Int> { } // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{40-68=}} {{71-71=?}} {{71-72=}}
-func genericOptIUO<T : P>(_: T) where T.U == Optional<ImplicitlyUnwrappedOptional<Int>> {} // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{55-83=}} {{86-86=?}} {{86-87=}}
+func generic<T : P>(_: T) where T.T == ImplicitlyUnwrappedOptional<Int> { } // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{40-68=}} {{71-71=?}} {{71-72=}}
+func genericOptIUO<T : P>(_: T) where T.U == Optional<ImplicitlyUnwrappedOptional<Int>> {} // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{55-83=}} {{86-86=?}} {{86-87=}}
 
 func testClosure() -> Int {
   return {
     (i: ImplicitlyUnwrappedOptional<Int>) // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name}}{{9-37=}} {{40-40=!}} {{40-41=}}
-     -> ImplicitlyUnwrappedOptional<Int> in // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{9-37=}} {{40-40=?}} {{40-41=}}
+     -> ImplicitlyUnwrappedOptional<Int> in // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{9-37=}} {{40-40=?}} {{40-41=}}
     return i
   }(1)!
 }
 
-_ = Array<Int!>() // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{14-15=?}}
-let _: Array<Int!> = [1] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{17-18=?}}
-_ = [Int!]() // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{9-10=?}}
-let _: [Int!] = [1] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{12-13=?}}
-_ = Optional<Int!>(nil) // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{17-18=?}}
-let _: Optional<Int!> = nil // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{20-21=?}}
-_ = Int!?(0) // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-let _: Int!? = 0 // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{11-12=?}}
+_ = Array<Int!>() // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{14-15=?}}
+let _: Array<Int!> = [1] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{17-18=?}}
+_ = [Int!]() // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{9-10=?}}
+let _: [Int!] = [1] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{12-13=?}}
+_ = Optional<Int!>(nil) // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{17-18=?}}
+let _: Optional<Int!> = nil // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{20-21=?}}
+_ = Int!?(0) // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+let _: Int!? = 0 // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{11-12=?}}
 _ = (
-  Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{6-7=?}}
-  Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  String! // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{9-10=?}}
+  Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{6-7=?}}
+  Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  String! // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{9-10=?}}
 )(1, 2.0, "3")
 let _: (
-  Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{6-7=?}}
-  Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  String! // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{9-10=?}}
+  Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{6-7=?}}
+  Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  String! // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{9-10=?}}
 ) = (1, 2.0, "3")
 
 struct Generic<T, U, C> {
   init(_ t: T, _ u: U, _ c: C) {}
 }
-_ = Generic<Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{16-17=?}}
-            Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{18-19=?}}
-            String!>(1, 2.0, "3") // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{19-20=?}}
-let _: Generic<Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{19-20=?}}
-               Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{21-22=?}}
-               String!> = Generic(1, 2.0, "3") // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{22-23=?}}
+_ = Generic<Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{16-17=?}}
+            Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{18-19=?}}
+            String!>(1, 2.0, "3") // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{19-20=?}}
+let _: Generic<Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{19-20=?}}
+               Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{21-22=?}}
+               String!> = Generic(1, 2.0, "3") // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{22-23=?}}
 
-func vararg(_ first: Int, more: Int!...) { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{36-37=?}}
+func vararg(_ first: Int, more: Int!...) { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{36-37=?}}
 }
 
-func varargIdentifier(_ first: Int, more: ImplicitlyUnwrappedOptional<Int>...) { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
+func varargIdentifier(_ first: Int, more: ImplicitlyUnwrappedOptional<Int>...) { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
 }
 
-func iuoInTuple() -> (Int!) { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{26-27=?}}
+func iuoInTuple() -> (Int!) { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{26-27=?}}
   return 1
 }
 
-func iuoInTupleIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
+func iuoInTupleIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
   return 1
 }
 
-func iuoInTuple2() -> (Float, Int!) { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{34-35=?}}
+func iuoInTuple2() -> (Float, Int!) { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{34-35=?}}
   return (1.0, 1)
 }
 
-func iuoInTuple2Identifier() -> (Float, ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{41-69=}} {{72-72=?}} {{72-73=}}
+func iuoInTuple2Identifier() -> (Float, ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{41-69=}} {{72-72=?}} {{72-73=}}
   return (1.0, 1)
 }
 
-func takesFunc(_ fn: (Int!) -> Int) -> Int { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{26-27=?}}
+func takesFunc(_ fn: (Int!) -> Int) -> Int { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{26-27=?}}
   return fn(0)
 }
 
-func takesFuncIdentifier(_ fn: (ImplicitlyUnwrappedOptional<Int>) -> Int) -> Int { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
+func takesFuncIdentifier(_ fn: (ImplicitlyUnwrappedOptional<Int>) -> Int) -> Int { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
   return fn(0)
 }
 
-func takesFunc2(_ fn: (Int) -> Int!) -> Int { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{35-36=?}}
+func takesFunc2(_ fn: (Int) -> Int!) -> Int { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{35-36=?}}
   return fn(0)!
 }
 
-func takesFunc2Identifier(_ fn: (Int) -> ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{42-70=}} {{73-73=?}} {{73-74=}}
+func takesFunc2Identifier(_ fn: (Int) -> ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{42-70=}} {{73-73=?}} {{73-74=}}
   return fn(0)!
 }
 
-func returnsFunc() -> (Int!) -> Int { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{27-28=?}}
+func returnsFunc() -> (Int!) -> Int { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{27-28=?}}
   return { $0! }
 }
 
-func returnsFuncIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{34-62=}} {{65-65=?}} {{65-66=}}
+func returnsFuncIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{34-62=}} {{65-65=?}} {{65-66=}}
   return { $0! }
 }
 
-func returnsFunc2() -> (Int) -> Int! { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{36-37=?}}
+func returnsFunc2() -> (Int) -> Int! { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{36-37=?}}
   return { $0 }
 }
 
-func returnsFunc2Identifier() -> (Int) -> ImplicitlyUnwrappedOptional<Int> { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
+func returnsFunc2Identifier() -> (Int) -> ImplicitlyUnwrappedOptional<Int> { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
   return { $0 }
 }
 
-let x = 1 as ImplicitlyUnwrappedOptional // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{14-41=Optional}}
+let x = 1 as ImplicitlyUnwrappedOptional // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{14-41=Optional}}
 let y = x!
 let z: Int = x // expected-error {{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}{{15-15=!}}
diff --git a/test/SourceKit/DocSupport/doc_clang_module.swift.response b/test/SourceKit/DocSupport/doc_clang_module.swift.response
index 5a3c336..1584fd5 100644
--- a/test/SourceKit/DocSupport/doc_clang_module.swift.response
+++ b/test/SourceKit/DocSupport/doc_clang_module.swift.response
@@ -5712,7 +5712,7 @@
     key.kind: source.lang.swift.decl.function.free,
     key.name: "fooFunc1(_:)",
     key.usr: "c:@F@fooFunc1",
-    key.doc.full_as_xml: "<Function file=Foo.h line=\"66\" column=\"5\"><Name>fooFunc1</Name><USR>c:@F@fooFunc1</USR><Declaration>func fooFunc1(_ a: Int32) -> Int32</Declaration><Abstract><Para> Aaa.  fooFunc1.  Bbb.</Para></Abstract></Function>",
+    key.doc.full_as_xml: "<Function file=Foo.h line=\"66\" column=\"5\"><Name>fooFunc1</Name><USR>c:@F@fooFunc1</USR><Declaration>func fooFunc1(_ a: Int32) -&gt; Int32</Declaration><Abstract><Para> Aaa.  fooFunc1.  Bbb.</Para></Abstract></Function>",
     key.offset: 3282,
     key.length: 34,
     key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooFunc1</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>_</decl.var.parameter.argument_label> <decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.function.returntype></decl.function.free>",
@@ -5879,7 +5879,7 @@
     key.kind: source.lang.swift.decl.function.free,
     key.name: "redeclaredInMultipleModulesFunc1(_:)",
     key.usr: "c:@F@redeclaredInMultipleModulesFunc1",
-    key.doc.full_as_xml: "<Function file=Foo.h line=\"118\" column=\"5\"><Name>redeclaredInMultipleModulesFunc1</Name><USR>c:@F@redeclaredInMultipleModulesFunc1</USR><Declaration>func redeclaredInMultipleModulesFunc1(_ a: Int32) -> Int32</Declaration><Abstract><Para> Aaa.  redeclaredInMultipleModulesFunc1.  Bbb.</Para></Abstract></Function>",
+    key.doc.full_as_xml: "<Function file=Foo.h line=\"118\" column=\"5\"><Name>redeclaredInMultipleModulesFunc1</Name><USR>c:@F@redeclaredInMultipleModulesFunc1</USR><Declaration>func redeclaredInMultipleModulesFunc1(_ a: Int32) -&gt; Int32</Declaration><Abstract><Para> Aaa.  redeclaredInMultipleModulesFunc1.  Bbb.</Para></Abstract></Function>",
     key.offset: 3773,
     key.length: 58,
     key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>redeclaredInMultipleModulesFunc1</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>_</decl.var.parameter.argument_label> <decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.function.returntype></decl.function.free>",
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 308a5f4..effefd5 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -77,10 +77,12 @@
 
 struct foo <MemberDeclBlock>{<Attribute>
   @available(*, unavailable)</Attribute>
-  struct foo <MemberDeclBlock>{}</MemberDeclBlock>
-  public class foo {<Attribute>
+  struct foo <MemberDeclBlock>{}</MemberDeclBlock><DeclModifier>
+  public </DeclModifier>class foo {<Attribute>
     @available(*, unavailable)</Attribute><Attribute>
-    @objc(fooObjc)</Attribute>
-    private static func foo() <CodeBlock>{}</CodeBlock>
+    @objc(fooObjc)</Attribute><DeclModifier>
+    private </DeclModifier><DeclModifier>static </DeclModifier>func foo() <CodeBlock>{}</CodeBlock>
   }
 }</MemberDeclBlock>
+
+struct S<A, B, C, D> <GenericWhereClause>where <ConformanceRequirement><SimpleTypeIdentifier>A</SimpleTypeIdentifier>:<SimpleTypeIdentifier>B</SimpleTypeIdentifier>, </ConformanceRequirement><SameTypeRequirement><SimpleTypeIdentifier>B</SimpleTypeIdentifier>==<SimpleTypeIdentifier>C</SimpleTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><SimpleTypeIdentifier>A </SimpleTypeIdentifier>: <SimpleTypeIdentifier>C</SimpleTypeIdentifier>, </ConformanceRequirement><SameTypeRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>B</SimpleTypeIdentifier>.C </MemberTypeIdentifier>== <MemberTypeIdentifier><SimpleTypeIdentifier>D</SimpleTypeIdentifier>.A</MemberTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>A</SimpleTypeIdentifier>.B</MemberTypeIdentifier>: <MemberTypeIdentifier><SimpleTypeIdentifier>C</SimpleTypeIdentifier>.D </MemberTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{}</MemberDeclBlock>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index c5061da..06da77e 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -84,3 +84,5 @@
     private static func foo() {}
   }
 }
+
+struct S<A, B, C, D> where A:B, B==C, A : C, B.C == D.A, A.B: C.D {}
diff --git a/test/stmt/foreach.swift b/test/stmt/foreach.swift
index 6b89f7c..12df84c 100644
--- a/test/stmt/foreach.swift
+++ b/test/stmt/foreach.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -enable-experimental-conditional-conformances
 
 // Bad containers and ranges
 struct BadContainer1 {
@@ -178,3 +178,42 @@
     _ = x
   }
 }
+
+// Conditional conformance to Sequence and IteratorProtocol.
+protocol P { }
+
+struct RepeatedSequence<T> {
+  var value: T
+  var count: Int
+}
+
+struct RepeatedIterator<T> {
+  var value: T
+  var count: Int
+}
+
+extension RepeatedIterator: IteratorProtocol where T: P {
+  typealias Element = T
+
+  mutating func next() -> T? {
+    if count == 0 { return nil }
+    count = count - 1
+    return value
+  }
+}
+
+extension RepeatedSequence: Sequence where T: P {
+  typealias Element = T
+  typealias Iterator = RepeatedIterator<T>
+  typealias SubSequence = AnySequence<T>
+
+  func makeIterator() -> RepeatedIterator<T> {
+    return Iterator(value: value, count: count)
+  }
+}
+
+extension Int : P { }
+
+func testRepeated(ri: RepeatedSequence<Int>) {
+  for x in ri { _ = x }
+}
diff --git a/test/type/protocol_composition.swift b/test/type/protocol_composition.swift
index 0d9e2c2..aa49e39 100644
--- a/test/type/protocol_composition.swift
+++ b/test/type/protocol_composition.swift
@@ -139,15 +139,15 @@
 typealias F = protocol<Any, Any> // expected-error {{'protocol<...>' composition syntax has been removed and is not needed here}} {{15-33=Any}}
 typealias G = protocol<P1>.Type // expected-error {{'protocol<...>' composition syntax has been removed and is not needed here}} {{15-27=P1}}
 typealias H = protocol<P1>! // expected-error {{'protocol<...>' composition syntax has been removed and is not needed here}} {{15-28=P1!}}
-// expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}
+// expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}
 typealias J = protocol<P1, P2>.Protocol // expected-error {{'protocol<...>' composition syntax has been removed; join the protocols using '&'}} {{15-31=(P1 & P2)}}
 typealias K = protocol<P1, P2>? // expected-error {{'protocol<...>' composition syntax has been removed; join the protocols using '&'}} {{15-32=(P1 & P2)?}}
 
 typealias T01 = P1.Protocol & P2 // expected-error {{non-protocol, non-class type 'P1.Protocol' cannot be used within a protocol-constrained type}}
 typealias T02 = P1.Type & P2 // expected-error {{non-protocol, non-class type 'P1.Type' cannot be used within a protocol-constrained type}}
 typealias T03 = P1? & P2 // expected-error {{non-protocol, non-class type 'P1?' cannot be used within a protocol-constrained type}}
-typealias T04 = P1 & P2! // expected-error {{non-protocol, non-class type 'P2?' cannot be used within a protocol-constrained type}}
-// expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}
+typealias T04 = P1 & P2! // expected-error {{non-protocol, non-class type 'P2!' cannot be used within a protocol-constrained type}}
+// expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}
 typealias T05 = P1 & P2 -> P3 // expected-error {{single argument function types require parentheses}} {{17-17=(}} {{24-24=)}}
 typealias T06 = P1 -> P2 & P3 // expected-error {{single argument function types require parentheses}} {{17-17=(}} {{19-19=)}}
 typealias T07 = P1 & protocol<P2, P3> // expected-error {{protocol<...>' composition syntax has been removed; join the protocols using '&'}} {{22-38=P2 & P3}}
diff --git a/test/type/types.swift b/test/type/types.swift
index de9b136..5d16cef 100644
--- a/test/type/types.swift
+++ b/test/type/types.swift
@@ -152,7 +152,7 @@
 let dictWithTuple = [String: (age:Int, count:Int)]()
 
 // <rdar://problem/21684837> typeexpr not being formed for postfix !
-let bb2 = [Int!](repeating: nil, count: 2) // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}
+let bb2 = [Int!](repeating: nil, count: 2) // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}
 
 // <rdar://problem/21560309> inout allowed on function return type
 func r21560309<U>(_ body: (_: inout Int) -> inout U) {}  // expected-error {{'inout' may only be used on parameters}}
diff --git a/unittests/Syntax/DeclSyntaxTests.cpp b/unittests/Syntax/DeclSyntaxTests.cpp
index 5e737c8..15c1c70 100644
--- a/unittests/Syntax/DeclSyntaxTests.cpp
+++ b/unittests/Syntax/DeclSyntaxTests.cpp
@@ -17,7 +17,8 @@
   auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
   auto Set = SyntaxFactory::makeIdentifier("set", {}, {});
   auto RParen = SyntaxFactory::makeRightParenToken({}, {});
-  return SyntaxFactory::makeDeclModifier(Private, LParen, Set, RParen);
+  return SyntaxFactory::makeDeclModifier(Private,
+    SyntaxFactory::makeTokenList({ LParen, Set, RParen}));
 }
 
 TEST(DeclSyntaxTests, DeclModifierMakeAPIs) {
@@ -40,12 +41,13 @@
   auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
   auto Set = SyntaxFactory::makeIdentifier("set", {}, {});
   auto RParen = SyntaxFactory::makeRightParenToken({}, {});
-  auto Mod = SyntaxFactory::makeDeclModifier(Private, LParen, Set, RParen);
+  auto Mod = SyntaxFactory::makeDeclModifier(Private,
+    SyntaxFactory::makeTokenList({LParen, Set, RParen}));
 
   ASSERT_EQ(Private.getRaw(), Mod.getName().getRaw());
-  ASSERT_EQ(LParen.getRaw(), Mod.getLeftParen()->getRaw());
-  ASSERT_EQ(Set.getRaw(), Mod.getArgument()->getRaw());
-  ASSERT_EQ(RParen.getRaw(), Mod.getRightParen()->getRaw());
+  ASSERT_EQ(LParen.getRaw(), Mod.getDetail()[0].getRaw());
+  ASSERT_EQ(Set.getRaw(), Mod.getDetail()[1].getRaw());
+  ASSERT_EQ(RParen.getRaw(), Mod.getDetail()[2].getRaw());
 }
 
 TEST(DeclSyntaxTests, DeclModifierWithAPIs) {
@@ -58,9 +60,7 @@
   llvm::raw_svector_ostream OS(Scratch);
   SyntaxFactory::makeBlankDeclModifier()
     .withName(Private)
-    .withLeftParen(LParen)
-    .withArgument(Set)
-    .withRightParen(RParen)
+    .withDetail(SyntaxFactory::makeTokenList({LParen, Set, RParen}))
     .print(OS);
   ASSERT_EQ(OS.str().str(), "private(set)");
 }
@@ -480,12 +480,12 @@
   auto NoLParen = TokenSyntax::missingToken(tok::l_paren, "(");
   auto NoArgument = TokenSyntax::missingToken(tok::identifier, "");
   auto NoRParen = TokenSyntax::missingToken(tok::r_paren, ")");
-  auto Public = SyntaxFactory::makeDeclModifier(PublicID, NoLParen, NoArgument,
-                                                NoRParen);
+  auto Public = SyntaxFactory::makeDeclModifier(PublicID,
+    SyntaxFactory::makeTokenList({NoLParen, NoArgument, NoRParen}));
 
   auto StaticKW = SyntaxFactory::makeStaticKeyword({}, Trivia::spaces(1));
-  auto Static = SyntaxFactory::makeDeclModifier(StaticKW, NoLParen, NoArgument,
-                                                NoRParen);
+  auto Static = SyntaxFactory::makeDeclModifier(StaticKW,
+    SyntaxFactory::makeTokenList({NoLParen, NoArgument, NoRParen}));
 
   return SyntaxFactory::makeBlankModifierList()
     .appending(Public)
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index 979be6a..a361952 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -78,15 +78,7 @@
                        'fileprivate', 'internal', 'public', 'open',
                        'mutating', 'nonmutating',
                    ]),
-             Child('LeftParen', kind='LeftParenToken',
-                   is_optional=True),
-             Child('Argument', kind='IdentifierToken',
-                   is_optional=True,
-                   text_choices=[
-                       'unowned', 'safe', 'unsafe', 'set',
-                   ]),
-             Child('RightParen', kind='RightParenToken',
-                   is_optional=True),
+             Child('Detail', kind='TokenList'),
          ]),
 
     # type-inheritance-clause -> ':' type