Merge pull request #21505 from DougGregor/dynamic-replacement-ambiguity-5.0
[5.0] [Type checker] Basic ambiguity resolution + diagnostics for dynamic replacement
diff --git a/include/swift/SILOptimizer/Utils/CastOptimizer.h b/include/swift/SILOptimizer/Utils/CastOptimizer.h
index 49f73711..2dbb79b 100644
--- a/include/swift/SILOptimizer/Utils/CastOptimizer.h
+++ b/include/swift/SILOptimizer/Utils/CastOptimizer.h
@@ -129,6 +129,10 @@
SILValue Dest, CanType Source,
CanType Target, SILBasicBlock *SuccessBB,
SILBasicBlock *FailureBB);
+
+ SILInstruction *
+ optimizeMetatypeConversion(ConversionInst *MCI,
+ MetatypeRepresentation Representation);
};
} // namespace swift
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index a814feb..336274b 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -353,19 +353,17 @@
return None;
};
+ // Check whether the superclass conforms.
+ if (auto superclass = genericSig->getSuperclassBound(type)) {
+ LookUpConformanceInSignature lookup(*getGenericSignature());
+ if (auto conformance = lookup(type->getCanonicalType(), superclass, proto))
+ return conformance;
+ }
+
// If the type doesn't conform to this protocol, the result isn't formed
// from these requirements.
- if (!genericSig->conformsToProtocol(type, proto)) {
- // Check whether the superclass conforms.
- if (auto superclass = genericSig->getSuperclassBound(type)) {
- return LookUpConformanceInSignature(*getGenericSignature())(
- type->getCanonicalType(),
- superclass,
- proto);
- }
-
+ if (!genericSig->conformsToProtocol(type, proto))
return None;
- }
auto accessPath =
genericSig->getConformanceAccessPath(type, proto);
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index fe009fa..15b0b7f 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -1908,8 +1908,9 @@
else
(void)0;
- // If the property has storage, emit the ivar name last.
- if (prop->hasStorage())
+ // If the property is an instance property and has storage, emit the ivar
+ // name last.
+ if (!prop->isStatic() && prop->hasStorage())
outs << ",V" << prop->getName();
}
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
index 64d2141..d231d6b 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
@@ -289,16 +289,19 @@
SILInstruction *
SILCombiner::
visitUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *UCCAI) {
- CastOpt.optimizeUnconditionalCheckedCastAddrInst(UCCAI);
+ if (CastOpt.optimizeUnconditionalCheckedCastAddrInst(UCCAI))
+ MadeChange = true;
+
return nullptr;
}
SILInstruction *
SILCombiner::
visitUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *UCCI) {
- if (CastOpt.optimizeUnconditionalCheckedCastInst(UCCI))
+ if (CastOpt.optimizeUnconditionalCheckedCastInst(UCCI)) {
+ MadeChange = true;
return nullptr;
-
+ }
// FIXME: rename from RemoveCondFails to RemoveRuntimeAsserts.
if (RemoveCondFails) {
auto LoweredTargetType = UCCI->getType();
@@ -388,32 +391,6 @@
return nullptr;
}
-/// Helper function for simplifying conversions between
-/// thick and objc metatypes.
-static SILInstruction *
-visitMetatypeConversionInst(SILBuilder &Builder, ConversionInst *MCI,
- MetatypeRepresentation Representation) {
- SILValue Op = MCI->getOperand(0);
- // Instruction has a proper target type already.
- SILType Ty = MCI->getType();
- auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
-
- if (MetatypeTy->getRepresentation() != Representation)
- return nullptr;
-
- if (isa<MetatypeInst>(Op))
- return Builder.createMetatype(MCI->getLoc(), Ty);
-
- if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op))
- return Builder.createValueMetatype(MCI->getLoc(), Ty, VMI->getOperand());
-
- if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op))
- return Builder.createExistentialMetatype(MCI->getLoc(), Ty,
- EMI->getOperand());
-
- return nullptr;
-}
-
SILInstruction *
SILCombiner::visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *TTOCMI) {
// Perform the following transformations:
@@ -425,8 +402,10 @@
//
// (thick_to_objc_metatype (existential_metatype @thick)) ->
// (existential_metatype @objc_metatype)
- return visitMetatypeConversionInst(Builder, TTOCMI,
- MetatypeRepresentation::Thick);
+ if (CastOpt.optimizeMetatypeConversion(TTOCMI, MetatypeRepresentation::Thick))
+ MadeChange = true;
+
+ return nullptr;
}
SILInstruction *
@@ -440,20 +419,26 @@
//
// (objc_to_thick_metatype (existential_metatype @objc_metatype)) ->
// (existential_metatype @thick)
- return visitMetatypeConversionInst(Builder, OCTTMI,
- MetatypeRepresentation::ObjC);
+ if (CastOpt.optimizeMetatypeConversion(OCTTMI, MetatypeRepresentation::ObjC))
+ MadeChange = true;
+
+ return nullptr;
}
SILInstruction *
SILCombiner::visitCheckedCastBranchInst(CheckedCastBranchInst *CBI) {
- CastOpt.optimizeCheckedCastBranchInst(CBI);
+ if (CastOpt.optimizeCheckedCastBranchInst(CBI))
+ MadeChange = true;
+
return nullptr;
}
SILInstruction *
SILCombiner::
visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CCABI) {
- CastOpt.optimizeCheckedCastAddrBranchInst(CCABI);
+ if (CastOpt.optimizeCheckedCastAddrBranchInst(CCABI))
+ MadeChange = true;
+
return nullptr;
}
diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp
index f5f2545..fb87294 100644
--- a/lib/SILOptimizer/Utils/CastOptimizer.cpp
+++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp
@@ -1576,3 +1576,40 @@
return nullptr;
}
+
+/// Simplify conversions between thick and objc metatypes.
+SILInstruction *CastOptimizer::optimizeMetatypeConversion(
+ ConversionInst *MCI, MetatypeRepresentation Representation) {
+ SILValue Op = MCI->getOperand(0);
+ // Instruction has a proper target type already.
+ SILType Ty = MCI->getType();
+ auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
+
+ if (MetatypeTy->getRepresentation() != Representation)
+ return nullptr;
+
+ // Rematerialize the incoming metatype instruction with the outgoing type.
+ auto replaceCast = [&](SingleValueInstruction *NewCast) {
+ assert(Ty.getAs<AnyMetatypeType>()->getRepresentation()
+ == NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation());
+ MCI->replaceAllUsesWith(NewCast);
+ EraseInstAction(MCI);
+ return NewCast;
+ };
+ if (auto *MI = dyn_cast<MetatypeInst>(Op)) {
+ return replaceCast(
+ SILBuilderWithScope(MCI).createMetatype(MCI->getLoc(), Ty));
+ }
+ // For metatype instructions that require an operand, generate the new
+ // metatype at the same position as the original to avoid extending the
+ // lifetime of `Op` past its destroy.
+ if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op)) {
+ return replaceCast(SILBuilderWithScope(VMI).createValueMetatype(
+ MCI->getLoc(), Ty, VMI->getOperand()));
+ }
+ if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op)) {
+ return replaceCast(SILBuilderWithScope(EMI).createExistentialMetatype(
+ MCI->getLoc(), Ty, EMI->getOperand()));
+ }
+ return nullptr;
+}
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 5100bd6..b03ffab 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1877,7 +1877,7 @@
(isa<OverloadedDeclRefExpr>(subExpr->getValueProvidingExpr()))) {
return subExpr;
}
-
+
// Save any existing type data of the subexpr tree, and reset it to null in
// prep for re-type-checking the tree. If things fail, we can revert the
// types back to their original state.
@@ -1921,9 +1921,12 @@
// holding on to an expression containing open existential types but
// no OpenExistentialExpr, which breaks invariants enforced by the
// ASTChecker.
- if (isa<OpenExistentialExpr>(subExpr))
- eraseOpenedExistentials(CS, subExpr);
-
+ // Another reason why we need to do this is because diagnostics might pick
+ // constraint anchor for re-typechecking which would only have opaque value
+ // expression and not enclosing open existential, which is going to trip up
+ // sanitizer.
+ eraseOpenedExistentials(CS, subExpr);
+
// If recursive type checking failed, then an error was emitted. Return
// null to indicate this to the caller.
if (!resultTy)
diff --git a/stdlib/private/StdlibUnittest/RaceTest.swift b/stdlib/private/StdlibUnittest/RaceTest.swift
index b4a214f..e4093a4 100644
--- a/stdlib/private/StdlibUnittest/RaceTest.swift
+++ b/stdlib/private/StdlibUnittest/RaceTest.swift
@@ -395,7 +395,7 @@
var stopNow = _stdlib_AtomicInt(0)
var trialBarrier: _stdlib_Barrier
- var trialSpinBarrier: _stdlib_AtomicInt = _stdlib_AtomicInt()
+ var trialSpinBarrier = _stdlib_AtomicInt()
var raceData: [RT.RaceData] = []
var workerStates: [_RaceTestWorkerState<RT>] = []
diff --git a/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb b/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
index bcc138a..1c58dca 100644
--- a/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
+++ b/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
@@ -12,6 +12,8 @@
import Swift
+// This type intentionally shadows the stdlib one
+@available(swift, introduced: 5.0)
public final class _stdlib_AtomicInt {
internal var _value: Int
@@ -47,7 +49,7 @@
public func compareExchange(expected: inout Int, desired: Int) -> Bool {
var expectedVar = expected
- let result = _stdlib_atomicCompareExchangeStrongInt(
+ let result = _swift_stdlib_atomicCompareExchangeStrongInt(
object: _valuePtr,
expected: &expectedVar,
desired: desired)
@@ -56,74 +58,3 @@
}
}
-public func _swift_stdlib_atomicLoadInt(
- object target: UnsafeMutablePointer<Int>) -> Int {
-#if arch(i386) || arch(arm)
- let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
- return Int(value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
- let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
- return Int(value)
-#endif
-}
-
-public func _swift_stdlib_atomicStoreInt(
- object target: UnsafeMutablePointer<Int>,
- desired: Int) {
-#if arch(i386) || arch(arm)
- Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
- Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
-#endif
-}
-
-public func _stdlib_atomicCompareExchangeStrongInt(
- object target: UnsafeMutablePointer<Int>,
- expected: UnsafeMutablePointer<Int>,
- desired: Int) -> Bool {
-#if arch(i386) || arch(arm)
- let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
- target._rawValue, expected.pointee._value, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
- let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
- target._rawValue, expected.pointee._value, desired._value)
-#endif
- expected.pointee._value = oldValue
- return Bool(won)
-}
-
-% for operation in ['Add', 'And', 'Or', 'Xor']:
-// Warning: no overflow checking.
-public func _swift_stdlib_atomicFetch${operation}Int(
- object target: UnsafeMutablePointer<Int>,
- operand: Int) -> Int {
- let rawTarget = UnsafeMutableRawPointer(target)
-#if arch(i386) || arch(arm)
- let value = _swift_stdlib_atomicFetch${operation}Int32(
- object: rawTarget.assumingMemoryBound(to: Int32.self),
- operand: Int32(operand))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
- let value = _swift_stdlib_atomicFetch${operation}Int64(
- object: rawTarget.assumingMemoryBound(to: Int64.self),
- operand: Int64(operand))
-#endif
- return Int(value)
-}
-
-% for bits in [ 32, 64 ]:
-
-// Warning: no overflow checking.
-public func _swift_stdlib_atomicFetch${operation}Int${bits}(
- object target: UnsafeMutablePointer<Int${bits}>,
- operand: Int${bits}) -> Int${bits} {
-
- let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
- target._rawValue, operand._value)
-
- return Int${bits}(value)
-}
-
-% end
-
-% end
-
diff --git a/stdlib/public/core/AtomicInt.swift.gyb b/stdlib/public/core/AtomicInt.swift.gyb
new file mode 100644
index 0000000..17d3484
--- /dev/null
+++ b/stdlib/public/core/AtomicInt.swift.gyb
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+@available(swift, deprecated: 4.2, obsoleted: 5.0)
+public final class _stdlib_AtomicInt {
+ internal var _value: Int
+
+ internal var _valuePtr: UnsafeMutablePointer<Int> {
+ return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
+ to: Int.self)
+ }
+
+ public init(_ value: Int = 0) {
+ _value = value
+ }
+
+ public func store(_ desired: Int) {
+ return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
+ }
+
+ public func load() -> Int {
+ return _swift_stdlib_atomicLoadInt(object: _valuePtr)
+ }
+
+% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
+ @discardableResult
+ public func fetchAnd${operation_name}(_ operand: Int) -> Int {
+ return _swift_stdlib_atomicFetch${operation_name}Int(
+ object: _valuePtr,
+ operand: operand)
+ }
+
+ public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
+ return fetchAnd${operation_name}(operand) ${operation} operand
+ }
+% end
+
+ public func compareExchange(expected: inout Int, desired: Int) -> Bool {
+ var expectedVar = expected
+ let result = _swift_stdlib_atomicCompareExchangeStrongInt(
+ object: _valuePtr,
+ expected: &expectedVar,
+ desired: desired)
+ expected = expectedVar
+ return result
+ }
+}
+
+@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
+internal func _swift_stdlib_atomicCompareExchangeStrongInt(
+ object target: UnsafeMutablePointer<Int>,
+ expected: UnsafeMutablePointer<Int>,
+ desired: Int) -> Bool {
+#if arch(i386) || arch(arm)
+ let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
+ target._rawValue, expected.pointee._value, desired._value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+ let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
+ target._rawValue, expected.pointee._value, desired._value)
+#endif
+ expected.pointee._value = oldValue
+ return Bool(won)
+}
+
+
+// FIXME: ideally it should not be here, at the very least not public, but
+// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
+public // Existing uses outside stdlib
+func _swift_stdlib_atomicLoadInt(
+ object target: UnsafeMutablePointer<Int>) -> Int {
+#if arch(i386) || arch(arm)
+ let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
+ return Int(value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+ let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
+ return Int(value)
+#endif
+}
+
+@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
+internal func _swift_stdlib_atomicStoreInt(
+ object target: UnsafeMutablePointer<Int>,
+ desired: Int) {
+#if arch(i386) || arch(arm)
+ Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+ Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
+#endif
+}
+
+% for operation in ['Add', 'And', 'Or', 'Xor']:
+// Warning: no overflow checking.
+// FIXME: ideally it should not be here, at the very least not public, but
+// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
+public // Existing uses outside stdlib
+func _swift_stdlib_atomicFetch${operation}Int(
+ object target: UnsafeMutablePointer<Int>,
+ operand: Int) -> Int {
+ let rawTarget = UnsafeMutableRawPointer(target)
+#if arch(i386) || arch(arm)
+ let value = _swift_stdlib_atomicFetch${operation}Int32(
+ object: rawTarget.assumingMemoryBound(to: Int32.self),
+ operand: Int32(operand))
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+ let value = _swift_stdlib_atomicFetch${operation}Int64(
+ object: rawTarget.assumingMemoryBound(to: Int64.self),
+ operand: Int64(operand))
+#endif
+ return Int(value)
+}
+
+% for bits in [ 32, 64 ]:
+
+// Warning: no overflow checking.
+@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
+internal func _swift_stdlib_atomicFetch${operation}Int${bits}(
+ object target: UnsafeMutablePointer<Int${bits}>,
+ operand: Int${bits}) -> Int${bits} {
+
+ let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
+ target._rawValue, operand._value)
+
+ return Int${bits}(value)
+}
+
+% end
+
+% end
+
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 169941c..7323a89 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -30,6 +30,7 @@
ASCII.swift
Assert.swift
AssertCommon.swift
+ AtomicInt.swift.gyb
BidirectionalCollection.swift
Bitset.swift
Bool.swift
diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json
index 55d01d5..bd20989 100644
--- a/stdlib/public/core/GroupInfo.json
+++ b/stdlib/public/core/GroupInfo.json
@@ -197,6 +197,7 @@
"Bitset.swift"
],
"Misc": [
+ "AtomicInt.swift",
"Interval.swift",
"ErrorType.swift",
"InputStream.swift",
diff --git a/stdlib/public/core/Runtime.swift.gyb b/stdlib/public/core/Runtime.swift.gyb
index 1c06d78..41e9940 100644
--- a/stdlib/public/core/Runtime.swift.gyb
+++ b/stdlib/public/core/Runtime.swift.gyb
@@ -115,54 +115,6 @@
}
//===----------------------------------------------------------------------===//
-// These pieces are used in ThreadLocalStorage.swift in debug builds.
-// For tests, see similar functions from SwiftPrivate/AtomicInt.swift.gyb
-//===----------------------------------------------------------------------===//
-internal func _swift_stdlib_atomicLoadInt(
- object target: UnsafeMutablePointer<Int>) -> Int {
-#if arch(i386) || arch(arm)
- let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
- return Int(value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
- let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
- return Int(value)
-#endif
-}
-
-% for bits in [ 32, 64 ]:
-
-// Warning: no overflow checking.
-internal func _swift_stdlib_atomicFetchAddInt${bits}(
- object target: UnsafeMutablePointer<Int${bits}>,
- operand: Int${bits}) -> Int${bits} {
-
- let value = Builtin.atomicrmw_add_seqcst_Int${bits}(
- target._rawValue, operand._value)
-
- return Int${bits}(value)
-}
-
-% end
-
-// Warning: no overflow checking.
-internal func _swift_stdlib_atomicFetchAddInt(
- object target: UnsafeMutablePointer<Int>,
- operand: Int) -> Int {
- let rawTarget = UnsafeMutableRawPointer(target)
-#if arch(i386) || arch(arm)
- let value = _swift_stdlib_atomicFetchAddInt32(
- object: rawTarget.assumingMemoryBound(to: Int32.self),
- operand: Int32(operand))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
- let value = _swift_stdlib_atomicFetchAddInt64(
- object: rawTarget.assumingMemoryBound(to: Int64.self),
- operand: Int64(operand))
-#endif
- return Int(value)
-}
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
// Conversion of primitive types to `String`
//===----------------------------------------------------------------------===//
diff --git a/test/Constraints/rdar46544601.swift b/test/Constraints/rdar46544601.swift
new file mode 100644
index 0000000..7002cde
--- /dev/null
+++ b/test/Constraints/rdar46544601.swift
@@ -0,0 +1,34 @@
+// RUN: %target-typecheck-verify-swift
+
+struct D {}
+
+class Future<T> {
+ func then<U>(_ fn: @escaping (T) -> Future<U>) -> Future<U> { fatalError() }
+ func thenThrowing<U>(_ fn: @escaping (T) throws -> U) -> Future<U> { fatalError() }
+ func whenFailure(_ fn: @escaping (Error) -> Void) {}
+
+ func and<U>(result: U) -> Future<(T,U)> { fatalError() }
+}
+
+protocol P {
+ func foo(arr: [D], data: ArraySlice<UInt8>) -> Future<D>
+ // expected-note@-1 {{found this candidate}}
+ func bar(root: D, from: P) -> Future<D>
+}
+
+extension P {
+ func foo(arr: [D] = [], data: [UInt8]) -> Future<D> { fatalError() }
+ // expected-note@-1 {{found this candidate}}
+}
+
+func crash(_ p: P, payload: [UInt8]) throws {
+ p.foo(data: payload).then { _ in
+ return Future<(D, [D])>()
+ }.then { (id, arr) in
+ p.foo(arr: arr, data: []).and(result: (id, arr))
+ // expected-error@-1 {{mbiguous reference to member 'foo(arr:data:)'}}
+ }.then { args0 in
+ let (parentID, args1) = args0
+ p.bar(root: parentID, from: p).and(args1)
+ }.whenFailure { _ in }
+}
diff --git a/test/IRGen/objc_properties.swift b/test/IRGen/objc_properties.swift
index 8e87328..45d3737 100644
--- a/test/IRGen/objc_properties.swift
+++ b/test/IRGen/objc_properties.swift
@@ -47,6 +47,8 @@
@objc class var extensionClassProp : SomeObject.Type {
return self
}
+
+ @objc static var extensionStoredStaticProp: Int64 = 0
}
// <rdar://problem/16952186> Crash with @lazy in @objc class
@@ -77,14 +79,14 @@
}
// CHECK-NEW: [[SHARED_NAME:@.*]] = private unnamed_addr constant [11 x i8] c"sharedProp\00"
-// CHECK-NEW: [[SHARED_ATTRS:@.*]] = private unnamed_addr constant [17 x i8] c"Tq,N,VsharedProp\00"
+// CHECK-NEW: [[SHARED_ATTRS:@.*]] = private unnamed_addr constant [5 x i8] c"Tq,N\00"
// CHECK-NEW: @_CLASS_PROPERTIES__TtC15objc_properties10SomeObject = private constant { {{.*}}] } {
// CHECK-NEW: i32 16,
// CHECK-NEW: i32 1,
// CHECK-NEW: [1 x { i8*, i8* }] [{
// CHECK-NEW: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SHARED_NAME]], i64 0, i64 0),
-// CHECK-NEW: i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[SHARED_ATTRS]], i64 0, i64 0)
+// CHECK-NEW: i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[SHARED_ATTRS]], i64 0, i64 0)
// CHECK-NEW: }]
// CHECK-NEW: }, section "__DATA, __objc_const", align 8
@@ -209,14 +211,17 @@
// CHECK-NEW: [[EXTENSIONCLASSPROPERTY_NAME:@.*]] = private unnamed_addr constant [19 x i8] c"extensionClassProp\00"
// CHECK-NEW: [[EXTENSIONCLASSPROPERTY_ATTRS:@.*]] = private unnamed_addr constant [7 x i8] c"T#,N,R\00"
+// CHECK-NEW: [[EXTENSIONSTATICPROPERTY_NAME:@.*]] = private unnamed_addr constant [26 x i8] c"extensionStoredStaticProp\00"
// CHECK-NEW: @"_CATEGORY_CLASS_PROPERTIES__TtC15objc_properties10SomeObject_$_objc_properties" = private constant { {{.*}}] } {
// CHECK-NEW: i32 16,
-// CHECK-NEW: i32 1,
-// CHECK-NEW: [1 x { i8*, i8* }] [{
+// CHECK-NEW: i32 2,
+// CHECK-NEW: [2 x { i8*, i8* }] [{
// CHECK-NEW: i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[EXTENSIONCLASSPROPERTY_NAME]], i64 0, i64 0),
// CHECK-NEW: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[EXTENSIONCLASSPROPERTY_ATTRS]], i64 0, i64 0)
-// CHECK-NEW: }]
+// CHECK-NEW: }, {
+// CHECK-NEW: i8* getelementptr inbounds ([26 x i8], [26 x i8]* [[EXTENSIONSTATICPROPERTY_NAME]], i64 0, i64 0),
+// CHECK-NEW: i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[SHARED_ATTRS]], i64 0, i64 0) }]
// CHECK-NEW: }, section "__DATA, __objc_const", align 8
// CHECK: @"_CATEGORY__TtC15objc_properties10SomeObject_$_objc_properties" = private constant { {{.+}} } {
diff --git a/test/Prototypes/CollectionTransformers.swift b/test/Prototypes/CollectionTransformers.swift
index 83ef091..4e4832b 100644
--- a/test/Prototypes/CollectionTransformers.swift
+++ b/test/Prototypes/CollectionTransformers.swift
@@ -641,7 +641,7 @@
internal let _maxThreads: Int
/// Total number of threads: number of running threads plus the number of
/// threads that are preparing to start).
- internal let _totalThreads: _stdlib_AtomicInt = _stdlib_AtomicInt(0)
+ internal let _totalThreads = _stdlib_AtomicInt(0)
internal var _runningThreads: [_ForkJoinWorkerThread] = []
internal var _runningThreadsMutex: _ForkJoinMutex = _ForkJoinMutex()
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 2cfe911..53d4316 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -3673,3 +3673,42 @@
return %4 : $Builtin.Int64
}
+// <rdar://46746188> crash in swift_getObjCClassFromObject
+// class TestDocument: NSPersistentDocument {
+// override init() {
+// super.init()
+// }
+// convenience init(type: String) throws {
+// self.init()
+// }
+// }
+// After inlining the __allocating_init, we have two uses of the value_metatype.
+// The second use goes through a thick_to_objc_metatype. When SILCombine replaces
+// thick_to_objc_metatype with value_metatype, it cannot extend the liverange
+// of value_metatype's operand.
+@objc class TestObjCInit {
+ init()
+
+ convenience init(type: String) throws
+}
+// CHECK-LABEL: sil hidden [thunk] @objc_init_partial_dealloc : $@convention(objc_method) (@owned TestObjCInit) -> Optional<TestObjCInit> {
+// CHECK: bb0(%0 : $TestObjCInit):
+// CHECK: [[VMT2:%.*]] = value_metatype $@objc_metatype TestObjCInit.Type, %0 : $TestObjCInit
+// CHECK: [[VMT:%.*]] = value_metatype $@thick TestObjCInit.Type, %0 : $TestObjCInit
+// CHECK: dealloc_partial_ref %0 : $TestObjCInit, [[VMT]] : $@thick TestObjCInit.Type
+// CHECK-NOT: value_metatype
+// CHECK: [[O:%.*]] = alloc_ref_dynamic [objc] [[VMT2]] : $@objc_metatype TestObjCInit.Type, $TestObjCInit
+// CHECK: [[M:%.*]] = objc_method [[O]] : $TestObjCInit, #TestObjCInit.init!initializer.1.foreign : (TestObjCInit.Type) -> () -> TestObjCInit, $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+// CHECK: apply [[M]]([[O]]) : $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+// CHECK-LABEL: } // end sil function 'objc_init_partial_dealloc'
+sil hidden [thunk] @objc_init_partial_dealloc : $@convention(objc_method) (@owned TestObjCInit) -> Optional<TestObjCInit> {
+bb0(%2 : $TestObjCInit):
+ %8 = value_metatype $@thick TestObjCInit.Type, %2 : $TestObjCInit
+ dealloc_partial_ref %2 : $TestObjCInit, %8 : $@thick TestObjCInit.Type
+ %11 = thick_to_objc_metatype %8 : $@thick TestObjCInit.Type to $@objc_metatype TestObjCInit.Type
+ %12 = alloc_ref_dynamic [objc] %11 : $@objc_metatype TestObjCInit.Type, $TestObjCInit
+ %13 = objc_method %12 : $TestObjCInit, #TestObjCInit.init!initializer.1.foreign : (TestObjCInit.Type) -> () -> TestObjCInit, $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+ %14 = apply %13(%12) : $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+ %19 = enum $Optional<TestObjCInit>, #Optional.some!enumelt.1, %14 : $TestObjCInit
+ return %19 : $Optional<TestObjCInit>
+}
diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
index e85e841..aa10b37 100644
--- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
@@ -120,39 +120,28 @@
Var __swift_stdlib_UErrorCode.isFailure has been removed
Var __swift_stdlib_UErrorCode.isSuccess has been removed
Var __swift_stdlib_UErrorCode.isWarning has been removed
+Var _stdlib_AtomicInt._value has been removed
+Var _stdlib_AtomicInt._valuePtr has been removed
-Class _stdlib_AtomicInt has been removed
-Func _stdlib_atomicCompareExchangeStrongInt(object:expected:desired:) has been removed
+
+Class _stdlib_AtomicInt is now without @_fixed_layout
+Func _stdlib_atomicCompareExchangeStrongInt(object:expected:desired:) has been renamed to Func _swift_stdlib_atomicCompareExchangeStrongInt(object:expected:desired:)
Func _stdlib_atomicCompareExchangeStrongInt32(object:expected:desired:) has been removed
Func _stdlib_atomicCompareExchangeStrongInt64(object:expected:desired:) has been removed
Func _stdlib_atomicCompareExchangeStrongUInt32(object:expected:desired:) has been removed
Func _stdlib_atomicCompareExchangeStrongUInt64(object:expected:desired:) has been removed
-Func _swift_stdlib_atomicFetchAddInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAddInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAddInt64(object:operand:) has been removed
Func _swift_stdlib_atomicFetchAddUInt32(object:operand:) has been removed
Func _swift_stdlib_atomicFetchAddUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAndInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAndInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAndInt64(object:operand:) has been removed
Func _swift_stdlib_atomicFetchAndUInt32(object:operand:) has been removed
Func _swift_stdlib_atomicFetchAndUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchOrInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchOrInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchOrInt64(object:operand:) has been removed
Func _swift_stdlib_atomicFetchOrUInt32(object:operand:) has been removed
Func _swift_stdlib_atomicFetchOrUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchXorInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchXorInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchXorInt64(object:operand:) has been removed
Func _swift_stdlib_atomicFetchXorUInt32(object:operand:) has been removed
Func _swift_stdlib_atomicFetchXorUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicLoadInt(object:) has been removed
Func _swift_stdlib_atomicLoadInt32(object:) has been removed
Func _swift_stdlib_atomicLoadInt64(object:) has been removed
Func _swift_stdlib_atomicLoadUInt32(object:) has been removed
Func _swift_stdlib_atomicLoadUInt64(object:) has been removed
-Func _swift_stdlib_atomicStoreInt(object:desired:) has been removed
Func _swift_stdlib_atomicStoreInt32(object:desired:) has been removed
Func _swift_stdlib_atomicStoreInt64(object:desired:) has been removed
Func _swift_stdlib_atomicStoreUInt32(object:desired:) has been removed
diff --git a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
index d7cb1d1..632b6eb 100644
--- a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
+++ b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %gyb %s -o %t/PersistentVector.swift
-// RUN: %line-directive %t/PersistentVector.swift -- %target-build-swift -parse-stdlib %t/PersistentVector.swift -o %t/a.out
+// RUN: %line-directive %t/PersistentVector.swift -- %target-build-swift -parse-stdlib -Xfrontend -disable-access-control %t/PersistentVector.swift -o %t/a.out
// RUN: %target-codesign %t/a.out
// RUN: %line-directive %t/PersistentVector.swift -- %target-run %t/a.out
// REQUIRES: executable_test