Merge pull request #11881 from milseman/4_0_failable_view_init_message

[4.0][stdlib] Better message for unavailable String.init(_:UTF8Buffer)
diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp
index b8aa3f4..c82273e 100644
--- a/lib/SILOptimizer/IPO/CapturePromotion.cpp
+++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp
@@ -1209,6 +1209,7 @@
   // Initialize a SILBuilder and create a function_ref referencing the cloned
   // closure.
   SILBuilderWithScope B(PAI);
+  B.addOpenedArchetypeOperands(PAI);
   SILValue FnVal = B.createFunctionRef(PAI->getLoc(), ClonedFn);
 
   // Populate the argument list for a new partial_apply instruction, taking into
@@ -1222,7 +1223,8 @@
   auto CalleePInfo = SubstCalleeFunctionTy->getParameters();
   SILFunctionConventions paConv(PAI->getType().castTo<SILFunctionType>(), M);
   unsigned FirstIndex = paConv.getNumSILArguments();
-  unsigned OpNo = 1, OpCount = PAI->getNumOperands();
+  unsigned OpNo = 1;
+  unsigned OpCount = PAI->getNumOperands() - PAI->getNumTypeDependentOperands();
   SmallVector<SILValue, 16> Args;
   auto NumIndirectResults = calleeConv.getNumIndirectSILResults();
   for (; OpNo != OpCount; ++OpNo) {
diff --git a/lib/Sema/ConstraintGraph.cpp b/lib/Sema/ConstraintGraph.cpp
index 475b542..4b49e96 100644
--- a/lib/Sema/ConstraintGraph.cpp
+++ b/lib/Sema/ConstraintGraph.cpp
@@ -641,13 +641,6 @@
   case ConstraintKind::BindParam:
   case ConstraintKind::BindToPointerType:
   case ConstraintKind::Equal:
-
-  // We currently only allow subtype contractions for the purpose of 
-  // parameter binding constraints.
-  // TODO: We do this because of how inout parameter bindings are handled
-  // for implicit closure parameters. We should consider adjusting our
-  // current approach to unlock more opportunities for subtype contractions.
-  case ConstraintKind::Subtype:
     return true;
 
   default:
@@ -671,12 +664,7 @@
     t1 = tt->getElementType(0).getPointer();
   }
 
-  auto iot = t1->getAs<InOutType>();
-
-  if (!iot)
-    return false;
-
-  return !iot->getObjectType()->isTypeVariableOrMember();
+  return t1->is<InOutType>();
 }
 
 bool ConstraintGraph::contractEdges() {
@@ -698,14 +686,6 @@
         auto t1 = constraint->getFirstType()->getDesugaredType();
         auto t2 = constraint->getSecondType()->getDesugaredType();
 
-        if (kind == ConstraintKind::Subtype) {
-          if (auto iot1 = t1->getAs<InOutType>()) {
-            t1 = iot1->getObjectType().getPointer();
-          } else {
-            continue;
-          }
-        }
-
         auto tyvar1 = t1->getAs<TypeVariableType>();
         auto tyvar2 = t2->getAs<TypeVariableType>();
 
diff --git a/test/SILOptimizer/capture_promotion.sil b/test/SILOptimizer/capture_promotion.sil
index ceaab34..50f17a4 100644
--- a/test/SILOptimizer/capture_promotion.sil
+++ b/test/SILOptimizer/capture_promotion.sil
@@ -305,4 +305,24 @@
   return %16 : $()
 }
 
+// CHECK-LABEL: sil @test_with_dynamic_self
+// CHECK: %{{[0-9]+}} = partial_apply %{{[0-9]+}}(%{{[0-9]+}}, %{{[0-9]+}}) : $@convention(thin) (Int, @thick @dynamic_self Bar.Type) -> () // type-defs: %1
+// CHECK: return
+sil @test_with_dynamic_self : $@convention(method) (Int, @guaranteed Bar) -> () {
+bb0(%0 : $Int, %1 : $Bar):
+  %4 = alloc_box ${ var Int }, var, name "item"
+  %5 = project_box %4 : ${ var Int }, 0
+  store %0 to %5 : $*Int
+  %17 = function_ref @closure_with_dynamic_self : $@convention(thin) (@owned { var Int }, @thick @dynamic_self Bar.Type) -> ()
+  %21 = metatype $@thick @dynamic_self Bar.Type
+  %26 = partial_apply %17(%4, %21) : $@convention(thin) (@owned { var Int }, @thick @dynamic_self Bar.Type) -> ()
+  %39 = tuple ()
+  return %39 : $()
+}
 
+sil private @closure_with_dynamic_self : $@convention(thin) (@owned { var Int }, @thick @dynamic_self Bar.Type) -> () {
+bb0(%1 : ${ var Int }, %2 : $@thick @dynamic_self Bar.Type):
+  strong_release %1 : ${ var Int }
+  %39 = tuple ()
+  return %39 : $()
+}
diff --git a/validation-test/Sema/rdar34333874.swift b/validation-test/Sema/rdar34333874.swift
new file mode 100644
index 0000000..7b1f5f6
--- /dev/null
+++ b/validation-test/Sema/rdar34333874.swift
@@ -0,0 +1,42 @@
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+class C {
+  var a: Int = 0
+  var b: Int = 0
+}
+
+@inline(never)
+func foo<T>(_ item: T, update: (inout T) throws -> Void) rethrows -> T {
+  var this = item
+  try update(&this)
+  return this
+}
+
+// Test single statement closure because it's type-checked
+// together with the call to `foo`
+
+let rdar34333874_1 = foo(C()) {
+  $0.a = 42
+}
+
+// The multi-statement closure which is type-checked
+// separately from call to `foo`
+
+let rdar34333874_2 = foo(C()) {
+  $0.a = 42
+  $0.b = 0
+}
+
+print(rdar34333874_1)
+print(rdar34333874_2)
+
+// Example which avoids mutating fields of the class
+
+@inline(never)
+func bar(_ o : C) {
+  let _ = foo(o) { (item) in
+  }
+}
+
+bar(C())