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())