Merge pull request #17931 from rintaro/4.2-ide-complete-rdar40956846

[4.2][CodeComplete] Fix crasher when completing inout IUO variable
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index e1b37d9..ad3f600 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -885,10 +885,21 @@
 ERROR(missing_nullary_call,none,
      "function produces expected type %0; did you mean to call it with '()'?",
      (Type))
-ERROR(missing_unwrap_optional,none,
-      "value of optional type %0 not unwrapped; did you mean to use '!' "
-      "or '?'?",
-     (Type))
+ERROR(optional_not_unwrapped,none,
+      "value of optional type %0 must be unwrapped to a value of type %1",
+     (Type, Type))
+NOTE(unwrap_with_default_value,none,
+     "coalesce using '?" "?' to provide a default when the optional value "
+     "contains 'nil'", ())
+NOTE(unwrap_with_force_value,none,
+     "force-unwrap using '!' to abort execution if the optional value contains "
+     "'nil'", ())
+ERROR(optional_base_not_unwrapped,none,
+      "value of optional type %0 must be unwrapped to refer to member %1 of "
+      "wrapped base type %2", (Type, DeclName, Type))
+NOTE(optional_base_chain,none,
+     "chain the optional using '?' to access member %0 only for non-'nil' "
+     "base values", (DeclName))
 ERROR(missing_unwrap_optional_try,none,
       "value of optional type %0 not unwrapped; did you mean to use 'try!' "
       "or chain with '?'?",
diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def
index 288837c..d160d0d 100644
--- a/include/swift/AST/KnownIdentifiers.def
+++ b/include/swift/AST/KnownIdentifiers.def
@@ -135,6 +135,7 @@
 IDENTIFIER(CastingPrecedence)
 IDENTIFIER(DefaultPrecedence)
 IDENTIFIER(FunctionArrowPrecedence)
+IDENTIFIER(NilCoalescingPrecedence)
 IDENTIFIER(TernaryPrecedence)
 
 // Builtins and literals
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index a6ae2f8..f27e02f 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1293,6 +1293,26 @@
     Arguments.push_back("-ldl");
 }
 
+/// Returns true if the compiler depends on features provided by the ObjC
+/// runtime that are not present on the deployment target indicated by
+/// \p triple.
+static bool wantsObjCRuntime(const llvm::Triple &triple) {
+  assert((!triple.isTvOS() || triple.isiOS()) &&
+         "tvOS is considered a kind of iOS");
+
+  // When updating the versions listed here, please record the most recent
+  // feature being depended on and when it was introduced:
+  //
+  // - The hook to override class_getImageName (macOS 10.14 and equivalent)
+  if (triple.isiOS())
+    return triple.isOSVersionLT(12);
+  if (triple.isMacOSX())
+    return triple.isMacOSXVersionLT(10, 14);
+  if (triple.isWatchOS())
+    return triple.isOSVersionLT(5);
+  llvm_unreachable("unknown Darwin OS");
+}
+
 ToolChain::InvocationInfo
 toolchains::Darwin::constructInvocation(const LinkJobAction &job,
                                         const JobContext &context) const {
@@ -1377,15 +1397,9 @@
   if (llvm::sys::fs::exists(CompilerRTPath))
     Arguments.push_back(context.Args.MakeArgString(CompilerRTPath));
 
-  bool wantsObjCRuntime = false;
-  if (Triple.isiOS())
-    wantsObjCRuntime = Triple.isOSVersionLT(9);
-  else if (Triple.isMacOSX())
-    wantsObjCRuntime = Triple.isMacOSXVersionLT(10, 11);
-
   if (context.Args.hasFlag(options::OPT_link_objc_runtime,
                            options::OPT_no_link_objc_runtime,
-                           /*Default=*/wantsObjCRuntime)) {
+                           /*Default=*/wantsObjCRuntime(Triple))) {
     llvm::SmallString<128> ARCLiteLib(D.getSwiftProgramPath());
     llvm::sys::path::remove_filename(ARCLiteLib); // 'swift'
     llvm::sys::path::remove_filename(ARCLiteLib); // 'bin'
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 7ffb330..5b76ad9 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -599,8 +599,10 @@
         KnownProtocolKind::Hashable);
     auto conformance = SGF.SGM.M.getSwiftModule()->lookupConformance(
         inputSubstType, protocol);
-    auto result = SGF.emitAnyHashableErasure(Loc, v, inputSubstType,
-                                             *conformance, ctxt);
+    auto addr = v.getType().isAddress() ? v : v.materialize(SGF, Loc);
+    auto result = SGF.emitAnyHashableErasure(Loc, addr,
+                                             inputSubstType, *conformance,
+                                             ctxt);
     if (result.isInContext())
       return ManagedValue::forInContext();
     return std::move(result).getAsSingleValue(SGF, Loc);
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 52c0fea..d69b922 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -7906,6 +7906,27 @@
   return exprNeedsParensOutsideFollowingOperator(TC, DC, expr, rootExpr, asPG);
 }
 
+bool swift::exprNeedsParensBeforeAddingNilCoalescing(TypeChecker &TC,
+                                                     DeclContext *DC,
+                                                     Expr *expr) {
+  auto asPG =
+    TC.lookupPrecedenceGroup(DC, DC->getASTContext().Id_NilCoalescingPrecedence,
+                             SourceLoc());
+  if (!asPG) return true;
+  return exprNeedsParensInsideFollowingOperator(TC, DC, expr, asPG);
+}
+
+bool swift::exprNeedsParensAfterAddingNilCoalescing(TypeChecker &TC,
+                                                    DeclContext *DC,
+                                                    Expr *expr,
+                                                    Expr *rootExpr) {
+  auto asPG =
+    TC.lookupPrecedenceGroup(DC, DC->getASTContext().Id_NilCoalescingPrecedence,
+                             SourceLoc());
+  if (!asPG) return true;
+  return exprNeedsParensOutsideFollowingOperator(TC, DC, expr, rootExpr, asPG);
+}
+
 namespace {
   class ExprWalker : public ASTWalker {
     ExprRewriter &Rewriter;
@@ -8067,7 +8088,7 @@
     
   switch (fix.first.getKind()) {
   case FixKind::ForceOptional: {
-    const Expr *unwrapped = affected->getValueProvidingExpr();
+    Expr *unwrapped = affected->getValueProvidingExpr();
     auto type = solution.simplifyType(getType(affected))
                   ->getRValueObjectType();
 
@@ -8078,25 +8099,17 @@
                       "try!");
 
     } else {
-      auto diag = TC.diagnose(affected->getLoc(),
-                              diag::missing_unwrap_optional, type);
-      if (affected->canAppendPostfixExpression(true)) {
-        diag.fixItInsertAfter(affected->getEndLoc(), "!");
-      } else {
-        diag.fixItInsert(affected->getStartLoc(), "(")
-            .fixItInsertAfter(affected->getEndLoc(), ")!");
-      }
+      return diagnoseUnwrap(TC, DC, unwrapped, type);
     }
     return true;
   }
           
-  case FixKind::OptionalChaining: {
+  case FixKind::UnwrapOptionalBase: {
     auto type = solution.simplifyType(getType(affected))
                 ->getRValueObjectType();
-    auto diag = TC.diagnose(affected->getLoc(),
-                            diag::missing_unwrap_optional, type);
-    diag.fixItInsertAfter(affected->getEndLoc(), "?");
-    return true;
+    DeclName memberName = fix.first.getDeclNameArgument(*this);
+    return diagnoseBaseUnwrapForMemberAccess(affected, type, memberName,
+                                             SourceRange());
   }
 
   case FixKind::ForceDowncast: {
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index ea268ec..840834d 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -2199,22 +2199,15 @@
   // telling us that it knows what it is doing, then believe it.
   if (!options.contains(TCC_ForceRecheck)) {
     if (CS.TC.isExprBeingDiagnosed(subExpr)) {
-      auto exprAndCS = CS.TC.getExprBeingDiagnosed(subExpr);
-      auto *savedExpr = exprAndCS.first;
+      auto *savedExpr = CS.TC.getExprBeingDiagnosed(subExpr);
       if (subExpr == savedExpr)
         return subExpr;
 
-      auto *oldCS = exprAndCS.second;
-
-      // The types on the result might have already been cached into
-      // another CS, but likely not this one.
-      if (oldCS != &CS)
-        CS.transferExprTypes(oldCS, savedExpr);
-
+      CS.cacheExprTypes(savedExpr);
       return savedExpr;
     }
 
-    CS.TC.addExprForDiagnosis(subExpr, std::make_pair(subExpr, &CS));
+    CS.TC.addExprForDiagnosis(subExpr, subExpr);
   }
 
   // Validate contextual type before trying to use it.
@@ -2262,15 +2255,6 @@
       allowFreeTypeVariables)
     TCEOptions |= TypeCheckExprFlags::AllowUnresolvedTypeVariables;
   
-  // If we're not passing down contextual type information this time, but the
-  // original failure had type info that wasn't an optional type,
-  // then set the flag to prefer fixits with force unwrapping.
-  if (!convertType) {
-    auto previousType = CS.getContextualType();
-    if (previousType && previousType->getOptionalObjectType().isNull())
-      TCEOptions |= TypeCheckExprFlags::PreferForceUnwrapToOptional;
-  }
-
   auto resultTy = CS.TC.typeCheckExpression(
       subExpr, CS.DC, TypeLoc::withoutLoc(convertType), convertTypePurpose,
       TCEOptions, listener, &CS);
@@ -2300,7 +2284,8 @@
     SavedTypeData.restore();
   }
 
-  CS.TC.addExprForDiagnosis(preCheckedExpr, std::make_pair(subExpr, &CS));
+  if (preCheckedExpr != subExpr)
+    CS.TC.addExprForDiagnosis(preCheckedExpr, subExpr);
 
   return subExpr;
 }
@@ -7751,15 +7736,9 @@
       }
 
       if (!optionalResult.ViableCandidates.empty()) {
-        // By default we assume that the LHS type is not optional.
-        StringRef fixIt = "!";
-        auto contextualType = CS.getContextualType();
-        if (contextualType && isa<OptionalType>(contextualType.getPointer()))
-          fixIt = "?";
-
-        diagnose(BaseLoc, diag::missing_unwrap_optional, baseObjTy)
-            .fixItInsertAfter(baseExpr->getEndLoc(), fixIt);
-        return true;
+        if (diagnoseBaseUnwrapForMemberAccess(baseExpr, baseObjTy, memberName,
+                                              memberRange))
+          return true;
       }
     }
 
@@ -8666,3 +8645,76 @@
   diagnoseFailureForExpr(expr);
   return true;
 }
+
+bool swift::diagnoseUnwrap(TypeChecker &TC, DeclContext *DC,
+                           Expr *expr, Type type) {
+  Type unwrappedType = type->getOptionalObjectType();
+  if (!unwrappedType)
+    return false;
+
+  TC.diagnose(expr->getLoc(), diag::optional_not_unwrapped, type,
+              unwrappedType);
+
+  // Suggest a default value via ?? <default value>
+  {
+    auto diag =
+      TC.diagnose(expr->getLoc(), diag::unwrap_with_default_value);
+
+    // Figure out what we need to parenthesize.
+    bool needsParensInside =
+      exprNeedsParensBeforeAddingNilCoalescing(TC, DC, expr);
+    bool needsParensOutside =
+      exprNeedsParensAfterAddingNilCoalescing(TC, DC, expr, expr);
+
+    llvm::SmallString<2> insertBefore;
+    llvm::SmallString<32> insertAfter;
+    if (needsParensOutside) {
+      insertBefore += "(";
+    }
+    if (needsParensInside) {
+      insertBefore += "(";
+      insertAfter += ")";
+    }
+    insertAfter += " ?? <" "#default value#" ">";
+    if (needsParensOutside)
+      insertAfter += ")";
+
+    if (!insertBefore.empty()) {
+      diag.fixItInsert(expr->getStartLoc(), insertBefore);
+    }
+    diag.fixItInsertAfter(expr->getEndLoc(), insertAfter);
+  }
+
+  // Suggest a force-unwrap.
+  {
+    auto diag =
+      TC.diagnose(expr->getLoc(), diag::unwrap_with_force_value);
+    if (expr->canAppendPostfixExpression(true)) {
+      diag.fixItInsertAfter(expr->getEndLoc(), "!");
+    } else {
+      diag.fixItInsert(expr->getStartLoc(), "(")
+          .fixItInsertAfter(expr->getEndLoc(), ")!");
+    }
+  }
+
+  return true;
+}
+
+bool swift::diagnoseBaseUnwrapForMemberAccess(Expr *baseExpr, Type baseType,
+                                              DeclName memberName,
+                                              SourceRange memberRange) {
+  auto unwrappedBaseType = baseType->getOptionalObjectType();
+  if (!unwrappedBaseType)
+    return false;
+
+  ASTContext &ctx = baseType->getASTContext();
+  DiagnosticEngine &diags = ctx.Diags;
+  diags.diagnose(baseExpr->getLoc(), diag::optional_base_not_unwrapped,
+                 baseType, memberName, unwrappedBaseType);
+
+  diags.diagnose(baseExpr->getLoc(), diag::optional_base_chain, memberName)
+    .fixItInsertAfter(baseExpr->getEndLoc(), "?");
+  diags.diagnose(baseExpr->getLoc(), diag::unwrap_with_force_value)
+    .fixItInsertAfter(baseExpr->getEndLoc(), "!");
+  return true;
+}
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 5d79878..616d085 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -3548,18 +3548,9 @@
   // Value member lookup has some hacks too.
   if (shouldAttemptFixes() && baseObjTy->getOptionalObjectType()) {
     // If the base type was an optional, look through it.
-    
-    // Determine whether or not we want to provide an optional chaining fixit or
-    // a force unwrap fixit.
-    bool optionalChain;
-    if (!getContextualType())
-      optionalChain = !(Options & ConstraintSystemFlags::PreferForceUnwrapToOptional);
-    else
-      optionalChain = !getContextualType()->getOptionalObjectType().isNull();
-    auto fixKind = optionalChain ? FixKind::OptionalChaining : FixKind::ForceOptional;
 
-    // Note the fix.
-    if (recordFix(fixKind, locator))
+    // We're unwrapping the base to perform a member access.
+    if (recordFix(Fix::getUnwrapOptionalBase(*this, member), locator))
       return SolutionKind::Error;
     
     // Look through one level of optional.
@@ -4871,8 +4862,8 @@
     getDefaultDecompositionOptions(flags) | TMF_ApplyingFix;
   switch (fix.getKind()) {
   case FixKind::ForceOptional:
-  case FixKind::OptionalChaining: {
-    // Assume that '!' was applied to the first type.
+  case FixKind::UnwrapOptionalBase: {
+    // Assume that we've unwrapped the first type.
     auto result =
         matchTypes(type1->getRValueObjectType()->getOptionalObjectType(), type2,
                    matchKind, subflags, locator);
diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp
index e7b51cc..3bc0b0b 100644
--- a/lib/Sema/CalleeCandidateInfo.cpp
+++ b/lib/Sema/CalleeCandidateInfo.cpp
@@ -992,10 +992,10 @@
     // Check for optional near miss.
     if (auto argOptType = substitution->getOptionalObjectType()) {
       if (isSubstitutableFor(argOptType, paramArchetype, CS.DC)) {
-        CS.TC.diagnose(badArgExpr->getLoc(), diag::missing_unwrap_optional,
-                       argType);
-        foundFailure = true;
-        break;
+        if (diagnoseUnwrap(CS.TC, CS.DC, badArgExpr, substitution)) {
+          foundFailure = true;
+          break;
+        }
       }
     }
     
diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp
index 622cfb1..aec4737 100644
--- a/lib/Sema/Constraint.cpp
+++ b/lib/Sema/Constraint.cpp
@@ -487,17 +487,29 @@
   return Fix(FixKind::ForceDowncast, index);
 }
 
+Fix Fix::getUnwrapOptionalBase(ConstraintSystem &cs, DeclName memberName) {
+  unsigned index = cs.FixedDeclNames.size();
+  cs.FixedDeclNames.push_back(memberName);
+  return Fix(FixKind::UnwrapOptionalBase, index);
+}
+
 Type Fix::getTypeArgument(ConstraintSystem &cs) const {
   assert(getKind() == FixKind::ForceDowncast);
   return cs.FixedTypes[Data];
 }
 
+/// If this fix has a name argument, retrieve it.
+DeclName Fix::getDeclNameArgument(ConstraintSystem &cs) const {
+  assert(getKind() == FixKind::UnwrapOptionalBase);
+  return cs.FixedDeclNames[Data];
+}
+
 StringRef Fix::getName(FixKind kind) {
   switch (kind) {
   case FixKind::ForceOptional:
     return "fix: force optional";
-  case FixKind::OptionalChaining:
-    return "fix: optional chaining";
+  case FixKind::UnwrapOptionalBase:
+    return "fix: unwrap optional base of member lookup";
   case FixKind::ForceDowncast:
     return "fix: force downcast";
   case FixKind::AddressOf:
diff --git a/lib/Sema/Constraint.h b/lib/Sema/Constraint.h
index ca09d09..560a80f 100644
--- a/lib/Sema/Constraint.h
+++ b/lib/Sema/Constraint.h
@@ -233,8 +233,8 @@
   /// Introduce a '!' to force an optional unwrap.
   ForceOptional,
 
-  /// Introduce a '?.' to begin optional chaining.
-  OptionalChaining,
+  /// Unwrap an optional base when we have a member access.
+  UnwrapOptionalBase,
 
   /// Append 'as! T' to force a downcast to the specified type.
   ForceDowncast,
@@ -265,17 +265,26 @@
 public:
   Fix(FixKind kind) : Kind(kind), Data(0) {
     assert(kind != FixKind::ForceDowncast && "Use getForceDowncast()");
+    assert(kind != FixKind::UnwrapOptionalBase &&
+           "Use getUnwrapOptionalBase()");
   }
 
   /// Produce a new fix that performs a forced downcast to the given type.
   static Fix getForcedDowncast(ConstraintSystem &cs, Type toType);
 
+  /// Produce a new fix that unwraps an optional base for an access to a member
+  /// with the given name.
+  static Fix getUnwrapOptionalBase(ConstraintSystem &cs, DeclName memberName);
+
   /// Retrieve the kind of fix.
   FixKind getKind() const { return Kind; }
 
   /// If this fix has a type argument, retrieve it.
   Type getTypeArgument(ConstraintSystem &cs) const;
 
+  /// If this fix has a name argument, retrieve it.
+  DeclName getDeclNameArgument(ConstraintSystem &cs) const;
+
   /// Return a string representation of a fix.
   static llvm::StringRef getName(FixKind kind);
 
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 763cb66..f655902 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -796,10 +796,6 @@
   /// Whether we allow the solver to attempt fixes to the system.
   AllowFixes = 0x01,
   
-  /// Set if the client prefers fixits to be in the form of force unwrapping
-  /// or optional chaining to return an optional.
-  PreferForceUnwrapToOptional = 0x02,
-
   /// If set, this is going to prevent constraint system from erasing all
   /// discovered solutions except the best one.
   ReturnAllDiscoveredSolutions = 0x04,
@@ -1001,6 +997,9 @@
   /// Types used in fixes.
   std::vector<Type> FixedTypes;
 
+  /// Declaration names used in fixes.
+  std::vector<DeclName> FixedDeclNames;
+
   /// \brief The set of remembered disjunction choices used to reach
   /// the current constraint system.
   SmallVector<std::pair<ConstraintLocator*, unsigned>, 32>
@@ -1326,30 +1325,6 @@
     bool walkToDeclPre(Decl *decl) override { return false; }
   };
 
-  class TransferExprTypes : public ASTWalker {
-    ConstraintSystem &toCS;
-    ConstraintSystem &fromCS;
-
-  public:
-    TransferExprTypes(ConstraintSystem &toCS, ConstraintSystem &fromCS)
-        : toCS(toCS), fromCS(fromCS) {}
-
-    Expr *walkToExprPost(Expr *expr) override {
-      if (fromCS.hasType(expr))
-        toCS.setType(expr, fromCS.getType(expr));
-
-      return expr;
-    }
-
-    /// \brief Ignore statements.
-    std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
-      return { false, stmt };
-    }
-
-    /// \brief Ignore declarations.
-    bool walkToDeclPre(Decl *decl) override { return false; }
-  };
-
 public:
 
   void setExprTypes(Expr *expr) {
@@ -1375,10 +1350,6 @@
     expr->walk(CacheExprTypes(expr, *this, excludeRoot));
   }
 
-  void transferExprTypes(ConstraintSystem *oldCS, Expr *expr) {
-    expr->walk(TransferExprTypes(*this, *oldCS));
-  }
-
   /// \brief The current solver state.
   ///
   /// This will be non-null when we're actively solving the constraint
@@ -3508,6 +3479,36 @@
     return { true, expr };
   }
 };
+
+
+/// Diagnose an attempt to recover when we have a value of optional type
+/// that needs to be unwrapped.
+///
+/// \returns true if a diagnostic was produced.
+bool diagnoseUnwrap(TypeChecker &TC, DeclContext *DC, Expr *expr, Type type);
+
+/// Diagnose an attempt to recover from a member access into a value of
+/// optional type which needed to be unwrapped for the member to be found.
+///
+/// \returns true if a diagnostic was produced.
+bool diagnoseBaseUnwrapForMemberAccess(Expr *baseExpr, Type baseType,
+                                       DeclName memberName,
+                                       SourceRange memberRange);
+
+// Return true if, when replacing "<expr>" with "<expr> ?? T", parentheses need
+// to be added around <expr> first in order to maintain the correct precedence.
+bool exprNeedsParensBeforeAddingNilCoalescing(TypeChecker &TC,
+                                              DeclContext *DC,
+                                              Expr *expr);
+
+// Return true if, when replacing "<expr>" with "<expr> as T", parentheses need
+// to be added around the new expression in order to maintain the correct
+// precedence.
+bool exprNeedsParensAfterAddingNilCoalescing(TypeChecker &TC,
+                                             DeclContext *DC,
+                                             Expr *expr,
+                                             Expr *rootExpr);
+
 } // end namespace swift
 
 #endif // LLVM_SWIFT_SEMA_CONSTRAINT_SYSTEM_H
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 5c1aa59..ccd6bc0 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -1856,8 +1856,6 @@
 
   // Construct a constraint system from this expression.
   ConstraintSystemOptions csOptions = ConstraintSystemFlags::AllowFixes;
-  if (options.contains(TypeCheckExprFlags::PreferForceUnwrapToOptional))
-    csOptions |= ConstraintSystemFlags::PreferForceUnwrapToOptional;
   ConstraintSystem cs(*this, dc, csOptions);
   cs.baseCS = baseCS;
   CleanupIllFormedExpressionRAII cleanup(Context, expr);
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 1e4b78c..bb4a7d7 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -57,12 +57,6 @@
 using ConformanceMap =
     llvm::DenseMap<SubstitutableType *, SmallVector<ProtocolConformance *, 2>>;
 
-/// \brief Used for recursive lookups into an expr that is already
-/// being type-checked and the constraint system in which its type is
-/// stored.
-using ExprAndConstraintSystem =
-    std::pair<Expr *, constraints::ConstraintSystem *>;
-
 /// Special-case type checking semantics for certain declarations.
 enum class DeclTypeCheckingSemantics {
   /// A normal declaration.
@@ -248,10 +242,6 @@
   /// and so we should not visit bodies of non-single expression closures.
   SkipMultiStmtClosures = 0x40,
 
-  /// Set if the client prefers fixits to be in the form of force unwrapping
-  /// or optional chaining to return an optional.
-  PreferForceUnwrapToOptional = 0x80,
-
   /// If set, don't apply a solution.
   SkipApplyingSolution = 0x100,
 };
@@ -907,7 +897,7 @@
   llvm::DenseSet<CanType> CIntegerTypes;
 
   /// The set of expressions currently being analyzed for failures.
-  llvm::DenseMap<Expr*, ExprAndConstraintSystem> DiagnosedExprs;
+  llvm::DenseMap<Expr*, Expr*> DiagnosedExprs;
 
   ModuleDecl *StdlibModule = nullptr;
 
@@ -2497,13 +2487,13 @@
   void checkInitializerErrorHandling(Initializer *I, Expr *E);
   void checkEnumElementErrorHandling(EnumElementDecl *D);
 
-  void addExprForDiagnosis(Expr *E1, ExprAndConstraintSystem Result) {
+  void addExprForDiagnosis(Expr *E1, Expr *Result) {
     DiagnosedExprs[E1] = Result;
   }
   bool isExprBeingDiagnosed(Expr *E) {
     return DiagnosedExprs.count(E);
   }
-  ExprAndConstraintSystem getExprBeingDiagnosed(Expr *E) {
+  Expr *getExprBeingDiagnosed(Expr *E) {
     return DiagnosedExprs[E];
   }
 
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index c364c91..3c3b7dc 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -24,6 +24,7 @@
 #include "swift/Runtime/ExistentialContainer.h"
 #include "swift/Runtime/HeapObject.h"
 #include "swift/Runtime/Mutex.h"
+#include "swift/Runtime/Once.h"
 #include "swift/Strings.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
@@ -54,6 +55,7 @@
 #endif
 
 #if SWIFT_OBJC_INTEROP
+#include <dlfcn.h>
 #include <objc/runtime.h>
 #endif
 
@@ -593,7 +595,7 @@
 
   // Otherwise, the input should already be a Swift class object.
   auto theClass = cast<ClassMetadata>(theMetadata);
-  assert(theClass->isTypeMetadata() && !theClass->isArtificialSubclass());
+  assert(theClass->isTypeMetadata());
   return theClass;
 }
 
@@ -2017,6 +2019,45 @@
   return self;
 }
 
+#if SWIFT_OBJC_INTEROP
+
+// FIXME: This is from a later version of <objc/runtime.h>. Once the declaration
+// is available in SDKs, we can remove this typedef.
+typedef BOOL (*objc_hook_getImageName)(
+    Class _Nonnull cls, const char * _Nullable * _Nonnull outImageName);
+
+/// \see customGetImageNameFromClass
+static objc_hook_getImageName defaultGetImageNameFromClass = nullptr;
+
+/// A custom implementation of Objective-C's class_getImageName for Swift
+/// classes, which knows how to handle dynamically-initialized class metadata.
+///
+/// Per the documentation for objc_setHook_getImageName, any non-Swift classes
+/// will still go through the normal implementation of class_getImageName,
+/// which is stored in defaultGetImageNameFromClass.
+static BOOL
+customGetImageNameFromClass(Class _Nonnull objcClass,
+                            const char * _Nullable * _Nonnull outImageName) {
+  auto *classAsMetadata = reinterpret_cast<const ClassMetadata *>(objcClass);
+
+  // Is this a Swift class?
+  if (classAsMetadata->isTypeMetadata() &&
+      !classAsMetadata->isArtificialSubclass()) {
+    const void *descriptor = classAsMetadata->getDescription();
+    assert(descriptor &&
+           "all non-artificial Swift classes should have a descriptor");
+    Dl_info imageInfo = {};
+    if (!dladdr(descriptor, &imageInfo))
+      return NO;
+    *outImageName = imageInfo.dli_fname;
+    return imageInfo.dli_fname != nullptr;
+  }
+
+  // If not, fall back to the default implementation.
+  return defaultGetImageNameFromClass(objcClass, outImageName);
+}
+#endif
+
 /// Initialize the field offset vector for a dependent-layout class, using the
 /// "Universal" layout strategy.
 void
@@ -2025,6 +2066,23 @@
                                size_t numFields,
                                const TypeLayout * const *fieldTypes,
                                size_t *fieldOffsets) {
+#if SWIFT_OBJC_INTEROP
+  // Register our custom implementation of class_getImageName.
+  static swift_once_t onceToken;
+  swift_once(&onceToken, [](void *unused) {
+    (void)unused;
+    // FIXME: This is from a later version of <objc/runtime.h>. Once the
+    // declaration is available in SDKs, we can access this directly instead of
+    // using dlsym.
+    if (void *setHookPtr = dlsym(RTLD_DEFAULT, "objc_setHook_getImageName")) {
+      auto setHook = reinterpret_cast<
+          void(*)(objc_hook_getImageName _Nonnull,
+                  objc_hook_getImageName _Nullable * _Nonnull)>(setHookPtr);
+      setHook(customGetImageNameFromClass, &defaultGetImageNameFromClass);
+    }
+  }, nullptr);
+#endif
+
   _swift_initializeSuperclass(self);
 
   // Start layout by appending to a standard heap object header.
diff --git a/test/ClangImporter/cfuncs_parse.swift b/test/ClangImporter/cfuncs_parse.swift
index 26089ce..92a7ebb 100644
--- a/test/ClangImporter/cfuncs_parse.swift
+++ b/test/ClangImporter/cfuncs_parse.swift
@@ -16,21 +16,27 @@
 
 func test_cfunc3_a() {
   let b = cfunc3( { (a : Double, b : Double) -> Double in a + b } )
-  _ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') not unwrapped; did you mean to use '!' or '?'?}}
+  _ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   _ = b!(1.5, 2.5) as Double
   _ = b as Double// expected-error{{cannot convert value of type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') to type 'Double' in coercion}}
 }
 
 func test_cfunc3_b() {
   let b = cfunc3( { a, b in a + b } )
-  _ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') not unwrapped; did you mean to use '!' or '?'?}}
+  _ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   _ = b!(1.5, 2.5) as Double
   _ = b as Double// expected-error{{cannot convert value of type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') to type 'Double' in coercion}}
 }
 
 func test_cfunc3_c() {
   let b = cfunc3({ $0 + $1 })
-  _ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') not unwrapped; did you mean to use '!' or '?'?}}
+  _ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   _ = b!(1.5, 2.5) as Double
   _ = b as Double// expected-error{{cannot convert value of type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') to type 'Double' in coercion}}
 }
diff --git a/test/ClangImporter/nullability.swift b/test/ClangImporter/nullability.swift
index cb7e8e0..73bf093 100644
--- a/test/ClangImporter/nullability.swift
+++ b/test/ClangImporter/nullability.swift
@@ -23,14 +23,22 @@
   if sc.methodD() == nil { } // expected-warning {{comparing non-optional value of type 'Any' to nil always returns false}}
 
   sc.methodE(sc)
-  sc.methodE(osc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
+  sc.methodE(osc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 
   sc.methodF(sc, second: sc)
-  sc.methodF(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
-  sc.methodF(sc, second: osc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{29-29=!}}
+  sc.methodF(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
+  sc.methodF(sc, second: osc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 
   sc.methodG(sc, second: sc)
-  sc.methodG(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
+  sc.methodG(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   sc.methodG(sc, second: osc) 
 
   let ci: CInt = 1
@@ -41,7 +49,9 @@
 
   let sc3 = SomeClass(double: 1.5)
   if sc3 == nil { } // okay
-  let sc3a: SomeClass = sc3 // expected-error{{value of optional type 'SomeClass?' not unwrapped}} {{28-28=!}}
+  let sc3a: SomeClass = sc3 // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   _ = sc3a
 
   let sc4 = sc.returnMe()
diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift
index 9da60fa..aed2ec8 100644
--- a/test/ClangImporter/objc_parse.swift
+++ b/test/ClangImporter/objc_parse.swift
@@ -130,7 +130,9 @@
   var obj : AnyObject = b
   var optStr = obj.nsstringProperty // optStr has type String??
   if optStr != nil {
-    var s : String = optStr! // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}}
+    var s : String = optStr! // expected-error{{value of optional type 'String?' must be unwrapped}}
+    // expected-note@-1{{coalesce}}
+    // expected-note@-2{{force-unwrap}}
     var t : String = optStr!!
   }
 
@@ -288,7 +290,9 @@
 
 func optionalMemberAccess(_ w: NSWobbling) {
   w.wobble()
-  w.wibble() // expected-error{{value of optional type '(() -> Void)?' not unwrapped; did you mean to use '!' or '?'?}} {{11-11=!}}
+  w.wibble() // expected-error{{value of optional type '(() -> Void)?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   let x = w[5]!!
   _ = x
 }
diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift
index 4e0f99e..5971087 100644
--- a/test/Constraints/closures.swift
+++ b/test/Constraints/closures.swift
@@ -282,7 +282,9 @@
 
   func subscribe<Object: AnyObject>(object: Object?, method: (Object, T) -> ()) where Object: Hashable {
     let wrappedMethod = { (object: AnyObject, value: T) in }
-    // expected-error @+1 {{value of optional type 'Object?' not unwrapped; did you mean to use '!' or '?'?}}
+    // expected-error @+3 {{value of optional type 'Object?' must be unwrapped to a value of type 'Object'}}
+    // expected-note @+2{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
+    // expected-note @+1{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
     cs.forEach { $0.w.append(value: wrappedMethod, forKey: object) }
   }
 }
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index d82e9e2..faf8040 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -221,7 +221,9 @@
 }
 
 func testStructWithOptionalArray(_ foo: StructWithOptionalArray) -> Int {
-  return foo.array[0]  // expected-error {{value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'?}} {{19-19=!}}
+  return foo.array[0]  // expected-error {{value of optional type '[Int]?' must be unwrapped to refer to member 'subscript' of wrapped base type '[Int]'}}
+  // expected-note@-1{{chain the optional using '?' to access member 'subscript' only for non-'nil' base values}}{{19-19=?}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{19-19=!}}
 }
 
 
@@ -542,7 +544,9 @@
 // <rdar://problem/22263468> QoI: Not producing specific argument conversion diagnostic for tuple init
 func r22263468(_ a : String?) {
   typealias MyTuple = (Int, String)
-  _ = MyTuple(42, a) // expected-error {{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}} {{20-20=!}}
+  _ = MyTuple(42, a) // expected-error {{value of optional type 'String?' must be unwrapped to a value of type 'String'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
 }
 
 
@@ -599,7 +603,9 @@
 // <rdar://problem/23560128> QoI: trying to mutate an optional dictionary result produces bogus diagnostic
 func r23560128() {
   var a : (Int,Int)?
-  a.0 = 42  // expected-error {{value of optional type '(Int, Int)?' not unwrapped; did you mean to use '!' or '?'?}} {{4-4=?}}
+  a.0 = 42 // expected-error{{value of optional type '(Int, Int)?' must be unwrapped to refer to member '0' of wrapped base type '(Int, Int)'}}
+  // expected-note@-1{{chain the optional }}
+  // expected-note@-2{{force-unwrap using '!'}}
 }
 
 // <rdar://problem/21890157> QoI: wrong error message when accessing properties on optional structs without unwrapping
@@ -607,7 +613,9 @@
   var property = "property"
 }
 var example21890157: ExampleStruct21890157?
-example21890157.property = "confusing"  // expected-error {{value of optional type 'ExampleStruct21890157?' not unwrapped; did you mean to use '!' or '?'?}} {{16-16=?}}
+example21890157.property = "confusing"  // expected-error {{value of optional type 'ExampleStruct21890157?' must be unwrapped to refer to member 'property' of wrapped base type 'ExampleStruct21890157'}}
+  // expected-note@-1{{chain the optional }}
+  // expected-note@-2{{force-unwrap using '!'}}
 
 
 struct UnaryOp {}
diff --git a/test/Constraints/fixes.swift b/test/Constraints/fixes.swift
index d480ff2..50cd8f7 100644
--- a/test/Constraints/fixes.swift
+++ b/test/Constraints/fixes.swift
@@ -47,16 +47,28 @@
 /// Forgot the '!' to unwrap an optional.
 func parseInt() -> Int? { }
 
+func <(lhs: A, rhs: A) -> A? { return nil }
+
 func forgotOptionalBang(_ a: A, obj: AnyObject) {
-  var i: Int = parseInt() // expected-error{{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}{{26-26=!}}
+  var i: Int = parseInt() // expected-error{{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{26-26= ?? <#default value#>}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{26-26=!}}
 
   var a = A(), b = B()
-  b = a as? B  // expected-error{{value of optional type 'B?' not unwrapped; did you mean to use '!' or '?'?}}{{7-7=(}}{{14-14=)!}}
+  b = a as? B  // expected-error{{value of optional type 'B?' must be unwrapped to a value of type 'B'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{14-14= ?? <#default value#>}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{7-7=(}}{{14-14=)!}}
 
+  a = a < a // expected-error{{value of optional type 'A?' must be unwrapped to a value of type 'A'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{7-7=(}}{{12-12=) ?? <#default value#>}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{7-7=(}}{{12-12=)!}}
+  
   // rdar://problem/20377684 -- take care that the '!' doesn't fall into an
   // optional evaluation context
   let bo: B? = b
-  let b2: B = bo?.createB() // expected-error{{value of optional type 'B?' not unwrapped; did you mean to use '!' or '?'?}}{{15-15=(}}{{28-28=)!}}
+  let b2: B = bo?.createB() // expected-error{{value of optional type 'B?' must be unwrapped to a value of type 'B'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
 }
 
 // Crash with one-element tuple with labeled element
@@ -64,7 +76,9 @@
 
 func microwave() -> Dinner {
   let d: Dinner? = nil
-  return (n: d) // expected-error{{value of optional type 'Dinner?' not unwrapped; did you mean to use '!' or '?'?}} {{16-16=!}}
+  return (n: d) // expected-error{{value of optional type 'Dinner?' must be unwrapped to a value of type 'Dinner'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
 }
 
 func forgotAnyObjectBang(_ obj: AnyObject) {
@@ -89,7 +103,9 @@
   var i = 7
   i = i() // expected-error{{cannot call value of non-function type 'Int'}}{{8-10=}}
 
-  maybeFn()(5) // expected-error{{value of optional type '((Int) -> Int)?' not unwrapped; did you mean to use '!' or '?'?}}{{12-12=!}}
+  maybeFn()(5) // expected-error{{value of optional type '((Int) -> Int)?' must be unwrapped to a value of type '(Int) -> Int'}}
+  // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
+  // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
 }
 
 class U {
@@ -125,17 +141,27 @@
 !ciuo // expected-error{{optional type 'C?' cannot be used as a boolean; test for '!= nil' instead}}{{2-2=(}} {{6-6= != nil)}}
 
 // Forgotten ! or ?
-var someInt = co.a // expected-error{{value of optional type 'C?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=?}}
+var someInt = co.a // expected-error{{value of optional type 'C?' must be unwrapped to refer to member 'a' of wrapped base type 'C'}}
+// expected-note@-1{{chain the optional using '?' to access member 'a' only for non-'nil' base values}}{{17-17=?}}
+// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{17-17=!}}
 
 // SR-839
 struct Q {
   let s: String?
 }
 let q = Q(s: nil)
-let a: Int? = q.s.utf8 // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}} {{18-18=?}}
-let b: Int = q.s.utf8 // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
-let d: Int! = q.s.utf8 // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}} {{18-18=?}}
-let c = q.s.utf8 // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}} {{12-12=?}}
+let a: Int? = q.s.utf8 // expected-error{{value of optional type 'String?' must be unwrapped to refer to member 'utf8' of wrapped base type 'String'}}
+// expected-note@-1{{chain the optional using '?'}}{{18-18=?}}
+// expected-note@-2{{force-unwrap using '!'}}{{18-18=!}}
+let b: Int = q.s.utf8 // expected-error{{value of optional type 'String?' must be unwrapped to refer to member 'utf8' of wrapped base type 'String'}}
+// expected-note@-1{{chain the optional using '?'}}{{17-17=?}}
+// expected-note@-2{{force-unwrap using '!'}}{{17-17=!}}
+let d: Int! = q.s.utf8 // expected-error{{value of optional type 'String?' must be unwrapped to refer to member 'utf8' of wrapped base type 'String'}}
+// expected-note@-1{{chain the optional using '?'}}{{18-18=?}}
+// expected-note@-2{{force-unwrap using '!'}}{{18-18=!}}
+let c = q.s.utf8 // expected-error{{value of optional type 'String?' must be unwrapped to refer to member 'utf8' of wrapped base type 'String'}}
+// expected-note@-1{{chain the optional using '?' to access member 'utf8' only for non-'nil' base values}}{{12-12=?}}
+// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{12-12=!}}
 
 // SR-1116
 struct S1116 {
diff --git a/test/Constraints/if_expr.swift b/test/Constraints/if_expr.swift
index 0f80ec8..ffce5aa 100644
--- a/test/Constraints/if_expr.swift
+++ b/test/Constraints/if_expr.swift
@@ -62,7 +62,9 @@
 let ib: Bool! = false
 let eb: Bool? = .some(false)
 let conditional = ib ? "Broken" : "Heart" // should infer Bool!
-let conditional = eb ? "Broken" : "Heart" // expected-error {{value of optional type 'Bool?' not unwrapped; did you mean to use '!' or '?'?}}
+let conditional = eb ? "Broken" : "Heart" // expected-error {{value of optional type 'Bool?' must be unwrapped}}
+// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
+// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
 
 // <rdar://problem/39586166> - crash when IfExpr has UnresolvedType in condition
 struct Delegate {
diff --git a/test/Constraints/iuo.swift b/test/Constraints/iuo.swift
index 50641d3..e15417c 100644
--- a/test/Constraints/iuo.swift
+++ b/test/Constraints/iuo.swift
@@ -210,8 +210,10 @@
 }
 
 func conditionalDowncastToObject(b: B?) -> D {
-  return b as? D! // expected-error {{value of optional type 'D?' not unwrapped; did you mean to use '!' or '?'?}}
-  // expected-warning@-1 {{using '!' here is deprecated and will be removed in a future release}}
+  return b as? D! // expected-error {{value of optional type 'D?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
+  // expected-warning@-3 {{using '!' here is deprecated and will be removed in a future release}}
 }
 
 // Ensure that we select the overload that does *not* involve forcing an IUO.
diff --git a/test/Constraints/iuo_objc.swift b/test/Constraints/iuo_objc.swift
index afd27de..1d11b98 100644
--- a/test/Constraints/iuo_objc.swift
+++ b/test/Constraints/iuo_objc.swift
@@ -5,25 +5,34 @@
 
 func iuo_error(prop: IUOProperty) {
   let _: Coat? = prop.iuo.optional()
-  // expected-error@-1 {{value of optional type '(() -> Coat?)?' not unwrapped; did you mean to use '!' or '?'?}}
+  // expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
+  // expected-note@-2{{coalesce}}
+  // expected-note@-3{{force-unwrap}}
   let _: Coat? = prop.iuo.optional()!
   // expected-error@-1 {{cannot invoke 'optional' with no arguments}}
   let _: Coat? = prop.iuo.optional!()
   let _: Coat? = prop.iuo.optional!()!
   let _: Coat? = prop.iuo!.optional()
-  // expected-error@-1 {{value of optional type '(() -> Coat?)?' not unwrapped; did you mean to use '!' or '?'?}}
+  // expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
+  // expected-note@-2{{coalesce}}
+  // expected-note@-3{{force-unwrap}}
   let _: Coat? = prop.iuo!.optional()!
   // expected-error@-1 {{cannot invoke 'optional' with no arguments}}
   let _: Coat? = prop.iuo!.optional!()
   let _: Coat? = prop.iuo!.optional!()!
   let _: Coat = prop.iuo.optional()
-  // expected-error@-1 {{value of optional type '(() -> Coat)?' not unwrapped; did you mean to use '!' or '?'?}}
+  // expected-error@-1 {{value of optional type '(() -> Coat)?' must be unwrapped}}
+  // expected-note@-2{{coalesce}}
+  // expected-note@-3{{force-unwrap}}
   let _: Coat = prop.iuo.optional()!
   // expected-error@-1 {{cannot invoke 'optional' with no arguments}}
   let _: Coat = prop.iuo.optional!()
   let _: Coat = prop.iuo.optional!()!
   let _: Coat = prop.iuo!.optional()
-  // expected-error@-1 {{value of optional type '(() -> Coat)?' not unwrapped; did you mean to use '!' or '?'?}}
+  // expected-error@-1 {{value of optional type '(() -> Coat)?' must be unwrapped}}
+  // expected-note@-2{{coalesce}}
+  // expected-note@-3{{force-unwrap}}
+  
   let _: Coat = prop.iuo!.optional()!
   // expected-error@-1 {{cannot invoke 'optional' with no arguments}}
   let _: Coat = prop.iuo!.optional!()
diff --git a/test/Constraints/overload.swift b/test/Constraints/overload.swift
index c6b5e21..8e5e666 100644
--- a/test/Constraints/overload.swift
+++ b/test/Constraints/overload.swift
@@ -153,7 +153,9 @@
 }
 
 let x1 = X1(Int.self)
-let x1check: X1 = x1 // expected-error{{value of optional type 'X1?' not unwrapped; did you mean to use '!' or '?'?}}
+let x1check: X1 = x1 // expected-error{{value of optional type 'X1?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 
 
 struct X2 {
@@ -164,7 +166,9 @@
 }
 
 let x2 = X2(Int.self)
-let x2check: X2 = x2 // expected-error{{value of optional type 'X2?' not unwrapped; did you mean to use '!' or '?'?}}
+let x2check: X2 = x2 // expected-error{{value of optional type 'X2?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 
 // rdar://problem/28051973
 struct R_28051973 {
diff --git a/test/Constraints/patterns.swift b/test/Constraints/patterns.swift
index 022c4e1..734d5bb 100644
--- a/test/Constraints/patterns.swift
+++ b/test/Constraints/patterns.swift
@@ -292,7 +292,7 @@
   case .init(0): break
   case .init(_): break // expected-error{{'_' can only appear in a pattern}}
   case .init(let x): break // expected-error{{cannot appear in an expression}}
-  case .init(opt: 0): break // expected-error{{not unwrapped}}
+  case .init(opt: 0): break // expected-error{{pattern cannot match values of type 'StaticMembers'}}
 
   case .prop: break
   // TODO: repeated error message
@@ -309,7 +309,7 @@
   case .method(withLabel: let x): break // expected-error{{cannot appear in an expression}}
 
   case .optMethod: break // expected-error{{cannot match}}
-  case .optMethod(0): break // expected-error{{not unwrapped}}
+  case .optMethod(0): break // expected-error{{pattern cannot match values of type 'StaticMembers'}}
 }
 
 _ = 0
diff --git a/test/Constraints/rdar42056741.swift b/test/Constraints/rdar42056741.swift
new file mode 100644
index 0000000..a04c981
--- /dev/null
+++ b/test/Constraints/rdar42056741.swift
@@ -0,0 +1,23 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
+// REQUIRES: objc_interop
+
+import Foundation
+
+class A {
+  static var `default` = A()
+
+  func foo(arg: String) -> Bool {
+    return false
+  }
+
+  func foo(arg: String, _ flag: UnsafeMutablePointer<ObjCBool>?) -> Bool {
+    return true
+  }
+}
+
+class B {
+  var bar: Bool = false
+  func baz() {
+    bar = A.default.foo(arg: self.) // expected-error {{expected member name following '.'}}
+  }
+}
diff --git a/test/Driver/linker-arclite.swift b/test/Driver/linker-arclite.swift
index 4b99dd4..73e67aa 100644
--- a/test/Driver/linker-arclite.swift
+++ b/test/Driver/linker-arclite.swift
@@ -11,15 +11,24 @@
 
 // RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-ios8.0 %S/../Inputs/empty.swift | %FileCheck -check-prefix IOS_ARCLITE %s
 
-// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.11 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
-// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-ios9.0 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
-// RUN: %swiftc_driver -driver-print-jobs -target arm64-apple-tvos9.0 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
-// RUN: %swiftc_driver -driver-print-jobs -target armv7k-apple-watchos2.0 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
-
 // IOS_ARCLITE: bin/ld{{"? }}
 // IOS_ARCLITE: -force_load {{[^ ]+/lib/arc/libarclite_iphonesimulator.a}}
 // IOS_ARCLITE: -o {{[^ ]+}}
 
+
+// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.14 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.13 %S/../Inputs/empty.swift | %FileCheck -check-prefix ANY_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-ios12 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-ios11 %S/../Inputs/empty.swift | %FileCheck -check-prefix ANY_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target arm64-apple-tvos12 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target arm64-apple-tvos11 %S/../Inputs/empty.swift | %FileCheck -check-prefix ANY_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target armv7k-apple-watchos5 %S/../Inputs/empty.swift | %FileCheck -check-prefix NO_ARCLITE %s
+// RUN: %swiftc_driver -driver-print-jobs -target armv7k-apple-watchos4 %S/../Inputs/empty.swift | %FileCheck -check-prefix ANY_ARCLITE %s
+
 // NO_ARCLITE: bin/ld{{"? }}
 // NO_ARCLITE-NOT: arclite
 // NO_ARCLITE: -o {{[^ ]+}}
+
+// ANY_ARCLITE: bin/ld{{"? }}
+// ANY_ARCLITE: -force_load {{[^ ]+}}/lib/arc/libarclite_{{.+}}.a
+// ANY_ARCLITE: -o {{[^ ]+}}
diff --git a/test/Generics/deduction.swift b/test/Generics/deduction.swift
index 355c684..e18d723 100644
--- a/test/Generics/deduction.swift
+++ b/test/Generics/deduction.swift
@@ -316,7 +316,9 @@
     let j = min(Int(3), Float(2.5)) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}}
     let k = min(A(), A()) // expected-error{{argument type 'A' does not conform to expected type 'Comparable'}}
     let oi : Int? = 5
-    let l = min(3, oi) // expected-error{{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}
+    let l = min(3, oi) // expected-error{{value of optional type 'Int?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 }
 
 infix operator +&
diff --git a/test/Interpreter/SDK/Inputs/SimpleNSObjectSubclass.swift b/test/Interpreter/SDK/Inputs/SimpleNSObjectSubclass.swift
new file mode 100644
index 0000000..a72c498
--- /dev/null
+++ b/test/Interpreter/SDK/Inputs/SimpleNSObjectSubclass.swift
@@ -0,0 +1,3 @@
+import Foundation
+
+public class SimpleSubclass: NSObject {}
diff --git a/test/Interpreter/SDK/Inputs/class_getImageName-helper.swift b/test/Interpreter/SDK/Inputs/class_getImageName-helper.swift
new file mode 100644
index 0000000..bcbc188
--- /dev/null
+++ b/test/Interpreter/SDK/Inputs/class_getImageName-helper.swift
@@ -0,0 +1,23 @@
+import Foundation
+
+public class SimpleSwiftObject {}
+public class SimpleNSObject: NSObject {
+  @objc public dynamic var observableName: String = ""
+}
+
+public class GenericSwiftObject<T> {}
+public class GenericNSObject<T>: NSObject {}
+
+public class GenericAncestrySwiftObject: GenericSwiftObject<AnyObject> {}
+public class GenericAncestryNSObject: GenericNSObject<AnyObject> {
+  @objc public dynamic var observableName: String = ""
+}
+
+public class ResilientFieldSwiftObject {
+  public var url: URL?
+  public var data: Data?
+}
+public class ResilientFieldNSObject: NSObject {
+  public var url: URL?
+  public var data: Data?
+}
diff --git a/test/Interpreter/SDK/Inputs/class_getImageName-static-helper.h b/test/Interpreter/SDK/Inputs/class_getImageName-static-helper.h
new file mode 100644
index 0000000..8a4e7fc
--- /dev/null
+++ b/test/Interpreter/SDK/Inputs/class_getImageName-static-helper.h
@@ -0,0 +1,7 @@
+static inline const char *getNameOfClassToFind() {
+  return "SimpleNSObjectSubclass.SimpleSubclass";
+}
+
+static inline const char *getHookName() {
+  return "objc_setHook_getImageName";
+}
diff --git a/test/Interpreter/SDK/KVO.swift b/test/Interpreter/SDK/KVO.swift
index ea3500b..2cdfd50 100644
--- a/test/Interpreter/SDK/KVO.swift
+++ b/test/Interpreter/SDK/KVO.swift
@@ -55,3 +55,20 @@
 let bar = foo.foo
 // CHECK-NEXT: 0
 print(bar)
+
+let fooClass: AnyClass = object_getClass(foo)!
+precondition(fooClass !== Foo.self, "no KVO subclass?")
+precondition(fooClass is Foo.Type, "improper KVO subclass")
+precondition(!(fooClass is Observer.Type), "improper KVO subclass")
+
+let fooClassAsObject: AnyObject = fooClass
+precondition(fooClassAsObject !== Foo.self, "no KVO subclass?")
+precondition(fooClassAsObject is Foo.Type, "improper KVO subclass")
+precondition(!(fooClassAsObject is Observer.Type), "improper KVO subclass")
+
+let fooClassAsAny: Any = fooClass
+precondition(fooClassAsAny is Foo.Type, "improper KVO subclass")
+precondition(!(fooClassAsAny is Observer.Type), "improper KVO subclass")
+
+// CHECK-NEXT: class metadata checks okay
+print("class metadata checks okay")
diff --git a/test/Interpreter/SDK/class_getImageName-static.swift b/test/Interpreter/SDK/class_getImageName-static.swift
new file mode 100644
index 0000000..5f4bab5
--- /dev/null
+++ b/test/Interpreter/SDK/class_getImageName-static.swift
@@ -0,0 +1,61 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-library -o %t/libSimpleNSObjectSubclass.dylib %S/Inputs/SimpleNSObjectSubclass.swift -Xlinker -install_name -Xlinker @executable_path/libSimpleNSObjectSubclass.dylib
+// RUN: %target-codesign %t/libSimpleNSObjectSubclass.dylib
+
+// RUN: %target-build-swift %s -o %t/main -lSimpleNSObjectSubclass -L%t -import-objc-header %S/Inputs/class_getImageName-static-helper.h
+// RUN: %target-run %t/main %t/libSimpleNSObjectSubclass.dylib
+
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+import Darwin
+import ObjectiveC
+// import SimpleNSObjectSubclass // Deliberately omitted in favor of dynamic loads.
+
+// Note: The following typealias uses AnyObject instead of AnyClass so that the
+// function type is trivially bridgeable to Objective-C. (The representation of
+// AnyClass is not the same as Objective-C's 'Class' type.)
+typealias GetImageHook = @convention(c) (AnyObject, UnsafeMutablePointer<UnsafePointer<CChar>?>) -> ObjCBool
+var hook: GetImageHook?
+
+func checkThatSwiftHookWasNotInstalled() {
+  // Check that the Swift hook did not get installed.
+  guard let setHookPtr = dlsym(UnsafeMutableRawPointer(bitPattern: -2),
+                               getHookName()) else {
+    // If the version of the ObjC runtime we're using doesn't have the hook,
+    // we're good.
+    return
+  }
+
+  let setHook = unsafeBitCast(setHookPtr, to: (@convention(c) (GetImageHook, UnsafeMutablePointer<GetImageHook?>) -> Void).self)
+  setHook({ hook!($0, $1) }, &hook)
+
+  var info: Dl_info = .init()
+  guard 0 != dladdr(unsafeBitCast(hook, to: UnsafeRawPointer.self), &info) else {
+    fatalError("could not get dladdr info for objc_hook_getImageName")
+  }
+
+  precondition(String(cString: info.dli_fname).hasSuffix("libobjc.A.dylib"),
+               "hook was replaced")
+}
+
+// It's important that this test does not register any Swift classes with the
+// Objective-C runtime---that's where Swift sets up its custom hook, and we want
+// to check the behavior /without/ that hook. That includes the buffer types for
+// String and Array. Therefore, we get C strings directly from a bridging
+// header.
+
+guard let theClass = objc_getClass(getNameOfClassToFind()) as! AnyClass? else {
+  fatalError("could not find class")
+}
+
+guard let imageName = class_getImageName(theClass) else {
+  fatalError("could not find image")
+}
+
+checkThatSwiftHookWasNotInstalled()
+
+// Okay, now we can use String.
+
+precondition(String(cString: imageName).hasSuffix("libSimpleNSObjectSubclass.dylib"),
+             "found wrong image")
diff --git a/test/Interpreter/SDK/class_getImageName.swift b/test/Interpreter/SDK/class_getImageName.swift
new file mode 100644
index 0000000..c684d9d
--- /dev/null
+++ b/test/Interpreter/SDK/class_getImageName.swift
@@ -0,0 +1,125 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-library -o %t/libGetImageNameHelper.dylib -emit-module %S/Inputs/class_getImageName-helper.swift -Xlinker -install_name -Xlinker @executable_path/libGetImageNameHelper.dylib
+// RUN: %target-codesign %t/libGetImageNameHelper.dylib
+
+// RUN: %target-build-swift -g %s -I %t -o %t/main -L %t -lGetImageNameHelper
+// RUN: %target-run %t/main %t/libGetImageNameHelper.dylib
+
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+import Darwin
+import ObjectiveC
+import GetImageNameHelper
+import StdlibUnittest
+
+func check(_ cls: AnyClass, in library: String) {
+  guard let imageName = class_getImageName(cls) else {
+    expectUnreachable("could not find image for \(cls)")
+    return
+  }
+  expectTrue(String(cString: imageName).hasSuffix(library),
+             "wrong library for \(cls)")
+}
+
+let isMissingObjCRuntimeHook =
+    (nil == dlsym(UnsafeMutableRawPointer(bitPattern: -2),
+                  "objc_setHook_getImageName"))
+
+var testSuite = TestSuite("class_getImageName")
+
+testSuite.test("Simple") {
+  check(SimpleSwiftObject.self, in: "libGetImageNameHelper.dylib")
+  check(SimpleNSObject.self, in: "libGetImageNameHelper.dylib")
+}
+
+testSuite.test("Generic")
+    .xfail(.custom({ isMissingObjCRuntimeHook },
+                   reason: "hook for class_getImageName not present"))
+    .code {
+  check(GenericSwiftObject<Int>.self, in: "libGetImageNameHelper.dylib")
+  check(GenericSwiftObject<NSObject>.self, in: "libGetImageNameHelper.dylib")
+
+  check(GenericNSObject<Int>.self, in: "libGetImageNameHelper.dylib")
+  check(GenericNSObject<NSObject>.self, in: "libGetImageNameHelper.dylib")
+}
+
+testSuite.test("GenericAncestry")
+    .xfail(.custom({ isMissingObjCRuntimeHook },
+                   reason: "hook for class_getImageName not present"))
+    .code {
+  check(GenericAncestrySwiftObject.self, in: "libGetImageNameHelper.dylib")
+  check(GenericAncestryNSObject.self, in: "libGetImageNameHelper.dylib")
+}
+
+testSuite.test("Resilient") {
+  check(ResilientFieldSwiftObject.self, in: "libGetImageNameHelper.dylib")
+  check(ResilientFieldNSObject.self, in: "libGetImageNameHelper.dylib")
+}
+
+testSuite.test("ObjC") {
+  check(NSObject.self, in: "libobjc.A.dylib")
+}
+
+testSuite.test("KVO/Simple") {
+  // We use object_getClass in this test to not look through KVO's artificial
+  // subclass.
+  let obj = SimpleNSObject()
+  autoreleasepool {
+    let observation = obj.observe(\.observableName) { _, _ in }
+    withExtendedLifetime(observation) {
+      let theClass = object_getClass(obj)
+      precondition(theClass !== SimpleNSObject.self, "no KVO subclass?")
+      expectNil(class_getImageName(theClass),
+                "should match what happens with NSObject (below)")
+    }
+  }
+}
+
+testSuite.test("KVO/GenericAncestry") {
+  // We use object_getClass in this test to not look through KVO's artificial
+  // subclass.
+  let obj = GenericAncestryNSObject()
+  autoreleasepool {
+    let observation = obj.observe(\.observableName) { _, _ in }
+    withExtendedLifetime(observation) {
+      let theClass = object_getClass(obj)
+      precondition(theClass !== GenericAncestryNSObject.self, "no KVO subclass?")
+      expectNil(class_getImageName(theClass),
+                "should match what happens with NSObject (below)")
+    }
+  }
+}
+
+testSuite.test("KVO/ObjC") {
+  // We use object_getClass in this test to not look through KVO's artificial
+  // subclass.
+  let obj = NSObject()
+  autoreleasepool {
+    let observation = obj.observe(\.description) { _, _ in }
+    withExtendedLifetime(observation) {
+      let theClass = object_getClass(obj)
+      precondition(theClass !== NSObject.self, "no KVO subclass?")
+      expectNil(class_getImageName(theClass),
+                "should match what happens with the Swift objects (above)")
+    }
+  }
+}
+
+testSuite.test("dynamic") {
+  let newClass: AnyClass = objc_allocateClassPair(/*superclass*/nil,
+                                                  "CompletelyDynamic",
+                                                  /*extraBytes*/0)!
+  objc_registerClassPair(newClass)
+
+  // We don't actually care what the result is; we just need to not crash.
+  _ = class_getImageName(newClass)
+}
+
+testSuite.test("nil") {
+  // The ObjC runtime should handle this before it even gets to Swift's custom
+  // implementation, but just in case.
+  expectNil(class_getImageName(nil))
+}
+
+runAllTests()
diff --git a/test/Migrator/rdar31892850.swift b/test/Migrator/rdar31892850.swift
index f2675b9..883f16b 100644
--- a/test/Migrator/rdar31892850.swift
+++ b/test/Migrator/rdar31892850.swift
@@ -21,6 +21,6 @@
 // CHECK:  {
 // CHECK:    "file": "{{.*}}rdar31892850.swift",
 // CHECK:    "offset": 310,
-// CHECK:    "text": ")!"
+// CHECK:    "text": ")"
 // CHECK:  }
 // CHECK:]
diff --git a/test/NameBinding/dynamic-member-lookup.swift b/test/NameBinding/dynamic-member-lookup.swift
index 49fc872..d89e097 100644
--- a/test/NameBinding/dynamic-member-lookup.swift
+++ b/test/NameBinding/dynamic-member-lookup.swift
@@ -150,7 +150,9 @@
   
   let _ : Int = x.bar  // Test implicitly forced optional
   let b = x.bar        // Should promote to 'Int?'
-  let _ : Int = b // expected-error {{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'}}
+  let _ : Int = b // expected-error {{value of optional type 'Int?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 }
 
 
diff --git a/test/Parse/optional_chain_lvalues.swift b/test/Parse/optional_chain_lvalues.swift
index ebf51c3..44845ee 100644
--- a/test/Parse/optional_chain_lvalues.swift
+++ b/test/Parse/optional_chain_lvalues.swift
@@ -36,7 +36,9 @@
 mutT?.mutS = S()
 mutT?.mutS? = S()
 mutT?.mutS?.x += 0
-_ = mutT?.mutS?.x + 0 // expected-error{{value of optional type 'Int?' not unwrapped}} {{5-5=(}} {{18-18=)!}}
+_ = mutT?.mutS?.x + 0 // expected-error{{value of optional type 'Int?' must be unwrapped}}
+// expected-note@-1{{coalesce}}
+// expected-note@-2{{force-unwrap}}
 mutT?.mutS?.y -= 0 // expected-error{{left side of mutating operator isn't mutable: 'y' is a 'let' constant}}
 mutT?.immS = S() // expected-error{{cannot assign to property: 'immS' is a 'let' constant}}
 mutT?.immS? = S() // expected-error{{cannot assign to value: 'immS' is a 'let' constant}}
diff --git a/test/Parse/pointer_conversion.swift.gyb b/test/Parse/pointer_conversion.swift.gyb
index cd2a7df..e048cd4 100644
--- a/test/Parse/pointer_conversion.swift.gyb
+++ b/test/Parse/pointer_conversion.swift.gyb
@@ -263,12 +263,16 @@
 func optionality(_ op: UnsafeMutablePointer<Float>?) {
   takesMutableVoidPointer(op)
 % if not suffix:
-  // expected-error@-2 {{value of optional type 'UnsafeMutablePointer<Float>?' not unwrapped}}
+  // expected-error@-2 {{value of optional type 'UnsafeMutablePointer<Float>?' must be unwrapped}}
+  // expected-note@-3{{coalesce}}
+  // expected-note@-4{{force-unwrap}}
 % end
 
   takesConstVoidPointer(op)
 % if not suffix:
-  // expected-error@-2 {{value of optional type 'UnsafeMutablePointer<Float>?' not unwrapped}}
+  // expected-error@-2 {{value of optional type 'UnsafeMutablePointer<Float>?' must be unwrapped}}
+  // expected-note@-3{{coalesce}}
+  // expected-note@-4{{force-unwrap}}
 % end
 }
 
diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift
index 526a44f..4da77ae 100644
--- a/test/SILGen/function_conversion.swift
+++ b/test/SILGen/function_conversion.swift
@@ -665,3 +665,21 @@
     return Foo<Klass>.enum1Func(SelfTy.bar)
   }
 }
+
+// CHECK: sil {{.*}} @$SS4SIgggoo_S2Ss11AnyHashableVyps5Error_pIegggrrzo_TR
+// CHECK:  [[TUPLE:%.*]] = apply %4(%2, %3) : $@noescape @callee_guaranteed (@guaranteed String, @guaranteed String) -> (@owned String, @owned String)
+// CHECK:  [[BORROW:%.*]] = begin_borrow [[TUPLE]] : $(String, String)
+// CHECK:  [[FRST:%.*]] = tuple_extract [[BORROW]] : $(String, String), 0
+// CHECK:  [[COPY1:%.*]] = copy_value [[FRST]] : $String
+// CHECK:  [[SND:%.*]] = tuple_extract [[BORROW]] : $(String, String), 1
+// CHECK:  [[COPY2:%.*]] = copy_value [[SND]] : $String
+// CHECK:  end_borrow [[BORROW]] from [[TUPLE]] : $(String, String), $(String, String)
+// CHECK:  destroy_value [[TUPLE]] : $(String, String)
+// CHECK:  [[ADDR:%.*]] = alloc_stack $String
+// CHECK:  store [[COPY1]] to [init] [[ADDR]] : $*String
+// CHECK:  [[CVT:%.*]] = function_ref @$Ss21_convertToAnyHashableys0cD0VxSHRzlF : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0) -> @out AnyHashable
+// CHECK:  apply [[CVT]]<String>(%0, [[ADDR]])
+func dontCrash() {
+  let userInfo = ["hello": "world"]
+  let d = [AnyHashable: Any](uniqueKeysWithValues: userInfo.map { ($0.key, $0.value) })
+}
diff --git a/test/decl/init/failable.swift b/test/decl/init/failable.swift
index 0571756..d93e439 100644
--- a/test/decl/init/failable.swift
+++ b/test/decl/init/failable.swift
@@ -32,7 +32,9 @@
 func testConstruction(_ i: Int, s: String) {
   let s0Opt = S0(string: s)
   assert(s0Opt != nil)
-  var _: S0 = s0Opt // expected-error{{value of optional type 'S0?' not unwrapped; did you mean to use '!' or '?'?}} {{20-20=!}}
+  var _: S0 = s0Opt // expected-error{{value of optional type 'S0?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
   
   let s0IUO = S0(int: i)
   assert(s0IUO != nil)
diff --git a/test/expr/cast/precedence.swift b/test/expr/cast/precedence.swift
index f45aed9..d80edaf 100644
--- a/test/expr/cast/precedence.swift
+++ b/test/expr/cast/precedence.swift
@@ -4,5 +4,7 @@
 
 func testInIf(a: Any) {
   if a as? Float {} // expected-error {{cannot be used as a boolean}} {{6-6=((}} {{17-17=) != nil)}}
-  let _: Float = a as? Float // expected-error {{value of optional type 'Float?' not unwrapped; did you mean to use '!' or '?'?}} {{18-18=(}} {{29-29=)!}}
+  let _: Float = a as? Float // expected-error {{value of optional type 'Float?' must be unwrapped}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 }
diff --git a/test/expr/postfix/dot/optional_context_member.swift b/test/expr/postfix/dot/optional_context_member.swift
index b2d79e3..fdb5307 100644
--- a/test/expr/postfix/dot/optional_context_member.swift
+++ b/test/expr/postfix/dot/optional_context_member.swift
@@ -13,14 +13,15 @@
   case ():
     return .someVar
   case (): // expected-warning {{case is already handled by previous patterns; consider removing it}}
-    return .someOptVar // expected-error 2 {{value of optional type 'Foo' not unwrapped; did you mean to use '!' or '?'?}} {{23-23=!}}
+    // FIXME: Customize this diagnostic for the optional case.
+    return .someOptVar // expected-error 1 {{member 'someOptVar' in 'Foo' produces result of type 'Foo?', but context expects 'Foo'}}
   // TODO
   //case ():
   //  return .someOptVar!
   case (): // expected-warning {{case is already handled by previous patterns; consider removing it}}
     return .someFunc()
   case (): // expected-warning {{case is already handled by previous patterns; consider removing it}}
-    return .someOptFunc() // expected-error{{}} {{26-26=!}}
+    return .someOptFunc() // expected-error{{member 'someOptFunc' in 'Foo' produces result of type 'Foo?', but context expects 'Foo'}}
   // TODO
   //case ():
   //  return .someOptFunc()!
diff --git a/test/stdlib/StringCompatibilityDiagnostics3.swift b/test/stdlib/StringCompatibilityDiagnostics3.swift
index a3edaa3..dc2b26a 100644
--- a/test/stdlib/StringCompatibilityDiagnostics3.swift
+++ b/test/stdlib/StringCompatibilityDiagnostics3.swift
@@ -22,6 +22,8 @@
 
   var _ = String(str.utf8) ?? "" // expected-warning{{'init' is deprecated: Failable initializer was removed in Swift 4. When upgrading to Swift 4, please use non-failable String.init(_:UTF8View)}}
   var _ = String(str.utf8) // expected-warning{{'init' is deprecated: Failable initializer was removed in Swift 4. When upgrading to Swift 4, please use non-failable String.init(_:UTF8View)}}
-  var _: String = String(str.utf8) // expected-error {{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}}
+  var _: String = String(str.utf8) // expected-error {{value of optional type 'String?' must be unwrapped to a value of type 'String'}}
+  // expected-note@-1{{coalesce}}
+  // expected-note@-2{{force-unwrap}}
 }
 
diff --git a/test/stmt/foreach.swift b/test/stmt/foreach.swift
index 3f97744..266d709 100644
--- a/test/stmt/foreach.swift
+++ b/test/stmt/foreach.swift
@@ -168,7 +168,9 @@
 // <rdar://problem/21662365> QoI: diagnostic for for-each over an optional sequence isn't great
 func testOptionalSequence() {
   let array : [Int]?
-  for x in array {  // expected-error {{value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
+  for x in array {  // expected-error {{value of optional type '[Int]?' must be unwrapped}}
+    // expected-note@-1{{coalesce}}
+    // expected-note@-2{{force-unwrap}}
   }
 }
 
diff --git a/validation-test/IDE/crashers_2_fixed/0020-rdar42056741.swift b/validation-test/IDE/crashers_2_fixed/0020-rdar42056741.swift
new file mode 100644
index 0000000..8c4ec32
--- /dev/null
+++ b/validation-test/IDE/crashers_2_fixed/0020-rdar42056741.swift
@@ -0,0 +1,23 @@
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -code-completion-token=COMPLETE -source-filename=%s
+// REQUIRES: objc_interop
+
+import Foundation
+
+class A {
+  static var `default` = A()
+
+  func foo(arg: String) -> Bool {
+    return false
+  }
+
+  func foo(arg: String, _ flag: UnsafeMutablePointer<ObjCBool>?) -> Bool {
+    return true
+  }
+}
+
+class B {
+  var bar: Bool = false
+  func baz() {
+    bar = A.default.foo(arg: self.#^COMPLETE^#)
+  }
+}