Merge pull request #22572 from dcci/rdar47982630-50

[5.0][DebuggerSupport] Unbreak closures in the expression parser.
diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp
index 3535a99..aa16188 100644
--- a/lib/Sema/CSBindings.cpp
+++ b/lib/Sema/CSBindings.cpp
@@ -350,6 +350,14 @@
          "not a representative");
   assert(!typeVar->getImpl().getFixedType(nullptr) && "has a fixed type");
 
+  // Determines whether this type variable represents an object
+  // of the optional type extracted by force unwrap.
+  bool isOptionalObject = false;
+  if (auto *locator = typeVar->getImpl().getLocator()) {
+    auto *anchor = locator->getAnchor();
+    isOptionalObject = anchor && isa<ForceValueExpr>(anchor);
+  }
+
   // Gather the constraints associated with this type variable.
   llvm::SetVector<Constraint *> constraints;
   getConstraintGraph().gatherConstraints(
@@ -401,6 +409,18 @@
       if (exactTypes.insert(type->getCanonicalType()).second) {
         result.addPotentialBinding(*binding);
 
+        // Result of force unwrap is always connected to its base
+        // optional type via `OptionalObject` constraint which
+        // preserves l-valueness, so in case where object type got
+        // inferred before optional type (because it got the
+        // type from context e.g. parameter type of a function call),
+        // we need to test type with and without l-value after
+        // delaying bindings for as long as possible.
+        if (isOptionalObject && !type->is<LValueType>()) {
+          result.FullyBound = true;
+          result.PotentiallyIncomplete = true;
+        }
+
         if (auto *locator = typeVar->getImpl().getLocator()) {
           auto path = locator->getPath();
           auto voidType = getASTContext().TheEmptyTupleType;
diff --git a/test/Constraints/optional.swift b/test/Constraints/optional.swift
index b255778..0d2f919 100644
--- a/test/Constraints/optional.swift
+++ b/test/Constraints/optional.swift
@@ -302,3 +302,34 @@
   _ = [i!]         // expected-error {{cannot force unwrap value of non-optional type 'Int'}} {{9-10=}}
   _ = S<Int>([i!]) // expected-error {{cannot force unwrap value of non-optional type 'Int'}} {{16-17=}}
 }
+
+// rdar://problem/47967277 - cannot assign through '!': '$0' is immutable
+func sr_9893_1() {
+  func foo<T : Equatable>(_: @autoclosure () throws -> T,
+                          _: @autoclosure () throws -> T) {}
+
+  class A {
+    var bar: String?
+  }
+
+  let r1 = A()
+  let r2 = A()
+
+  let arr1: [A] = []
+  foo(Set(arr1.map { $0.bar! }), Set([r1, r2].map { $0.bar! })) // Ok
+}
+
+func sr_9893_2(cString: UnsafePointer<CChar>) {
+  struct S {
+    var a: Int32 = 0
+    var b = ContiguousArray<CChar>(repeating: 0, count: 10)
+  }
+
+  var s = S()
+
+  withUnsafeMutablePointer(to: &s.a) { ptrA in
+    s.b.withUnsafeMutableBufferPointer { bufferB in
+      withVaList([ptrA, bufferB.baseAddress!]) { ptr in } // Ok
+    }
+  }
+}