Skip to content

Revert "[Sema] ban multi-arguments to tuple coercion" #3922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6417,7 +6417,7 @@ namespace {
// Coerce the pattern, in case we resolved something.
auto fnType = closure->getType()->castTo<FunctionType>();
auto *params = closure->getParameters();
if (tc.coerceParameterListToType(params, closure, fnType))
if (tc.coerceParameterListToType(params, closure, fnType->getInput()))
return { false, nullptr };

// If this is a single-expression closure, convert the expression
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSDiag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5411,7 +5411,7 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) {
return true;
}

if (CS->TC.coerceParameterListToType(params, CE, fnType))
if (CS->TC.coerceParameterListToType(params, CE, inferredArgType))
return true;

expectedResultType = fnType->getResult();
Expand Down
16 changes: 8 additions & 8 deletions lib/Sema/TypeCheckPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,9 +1537,8 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
/// TODO: These diagnostics should be a lot better now that we know this is
/// all specific to closures.
///
bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
AnyFunctionType *FN) {
Type paramListType = FN->getInput();
bool TypeChecker::coerceParameterListToType(ParameterList *P, DeclContext *DC,
Type paramListType) {
bool hadError = paramListType->is<ErrorType>();

// Sometimes a scalar type gets applied to a single-argument parameter list.
Expand All @@ -1548,7 +1547,7 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,

// Check that the type, if explicitly spelled, is ok.
if (param->getTypeLoc().getTypeRepr()) {
hadError |= validateParameterType(param, CE, TypeResolutionOptions(),
hadError |= validateParameterType(param, DC, TypeResolutionOptions(),
nullptr, *this);

// Now that we've type checked the explicit argument type, see if it
Expand Down Expand Up @@ -1590,10 +1589,11 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
// The number of elements must match exactly.
// TODO: incomplete tuple patterns, with some syntax.
if (!hadError && tupleTy->getNumElements() != P->size()) {
auto fnType = FunctionType::get(paramListType->getDesugaredType(),
FN->getResult());
diagnose(P->getStartLoc(), diag::closure_argument_list_tuple,
fnType, tupleTy->getNumElements(), P->size());
if (P->size() == 1)
return handleParameter(P->get(0), paramListType);

diagnose(P->getStartLoc(), diag::tuple_pattern_length_mismatch,
paramListType);
hadError = true;
}

Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -1386,8 +1386,7 @@ class TypeChecker final : public LazyResolver {
/// contextual type.
///
/// \returns true if an error occurred, false otherwise.
bool coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
AnyFunctionType *FN);
bool coerceParameterListToType(ParameterList *P, DeclContext *dc, Type type);


/// Type-check an initialized variable pattern declaration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1807,7 +1807,7 @@ self.test("\(testNamePrefix)._preprocessingPass/semantics") {
let s = makeWrappedSequence(test.sequence.map(OpaqueValue.init))
var wasInvoked = false
let result = s._preprocessingPass {
() -> OpaqueValue<Int> in
(sequence) -> OpaqueValue<Int> in
wasInvoked = true

expectEqualSequence(
Expand All @@ -1830,7 +1830,7 @@ self.test("\(testNamePrefix)._preprocessingPass/semantics") {
var result: OpaqueValue<Int>? = nil
do {
result = try s._preprocessingPass {
() -> OpaqueValue<Int> in
(sequence) -> OpaqueValue<Int> in
wasInvoked = true
throw TestError.error2
}
Expand Down
2 changes: 1 addition & 1 deletion stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -2387,7 +2387,7 @@ public func expectEqualsUnordered<
let x: [(T, T)] =
expected.sorted(by: comparePairLess)
let y: [(T, T)] =
actual.map { ($0, $1) }
actual.map { ($0.0, $0.1) }
.sorted(by: comparePairLess)

func comparePairEquals(_ lhs: (T, T), rhs: (key: T, value: T)) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion stdlib/private/StdlibUnittest/TypeIndexed.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public func expectEqual<V: Comparable>(
file: String = #file, line: UInt = #line
) {
expectEqualsUnordered(
expected.map { (key: TypeIdentifier($0), value: $1) },
expected.map { (key: TypeIdentifier($0.0), value: $0.1) },
actual.byType,
message(), stackTrace: stackTrace) { $0 <=> $1 }
}
4 changes: 2 additions & 2 deletions stdlib/public/SDK/AppKit/AppKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ extension NSView : _DefaultCustomPlaygroundQuickLookable {
public extension NSGradient {
convenience init?(colorsAndLocations objects: (NSColor, CGFloat)...) {
self.init(
colors: objects.map { c, _ in c },
atLocations: objects.map { _, l in l },
colors: objects.map { $0.0 },
atLocations: objects.map { $0.1 },
colorSpace: NSColorSpace.genericRGB())
}
}
Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/SDK/Foundation/Foundation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,8 @@ extension NSDictionary : ExpressibleByDictionaryLiteral {
dictionaryLiteral elements: (NSCopying, AnyObject)...
) {
self.init(
objects: elements.map { _, v in v },
forKeys: elements.map { k, _ in k },
objects: elements.map { $0.1 },
forKeys: elements.map { $0.0 },
count: elements.count)
}
}
Expand Down
8 changes: 4 additions & 4 deletions stdlib/public/SDK/WatchKit/WatchKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ extension WKInterfaceController {
withNamesAndContexts namesAndContexts: [(name: String, context: AnyObject)]
) {
WKInterfaceController.reloadRootControllers(
withNames: namesAndContexts.map { name, _ in name },
contexts: namesAndContexts.map { _, context in context })
withNames: namesAndContexts.map { $0.name },
contexts: namesAndContexts.map { $0.context })
}

@available(*, deprecated,
Expand All @@ -47,8 +47,8 @@ extension WKInterfaceController {
withNamesAndContexts namesAndContexts: [(name: String, context: AnyObject)]
) {
self.presentController(
withNames: namesAndContexts.map { name, _ in name },
contexts: namesAndContexts.map { _, context in context })
withNames: namesAndContexts.map { $0.name },
contexts: namesAndContexts.map { $0.context })
}
}

4 changes: 2 additions & 2 deletions stdlib/public/core/HashedCollections.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -2018,7 +2018,7 @@ public struct Dictionary<Key : Hashable, Value> :
/// // Prints "JP"
/// // Prints "GH"
public var keys: LazyMapCollection<Dictionary, Key> {
return self.lazy.map { key, _ in key }
return self.lazy.map { $0.key }
}

/// A collection containing just the values of the dictionary.
Expand All @@ -2036,7 +2036,7 @@ public struct Dictionary<Key : Hashable, Value> :
/// // Prints "Japan"
/// // Prints "Ghana"
public var values: LazyMapCollection<Dictionary, Value> {
return self.lazy.map { _, value in value }
return self.lazy.map { $0.value }
}

//
Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/core/ManagedBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ open class ManagedBuffer<Header, Element> {
public final func withUnsafeMutablePointerToElements<R>(
_ body: @noescape (UnsafeMutablePointer<Element>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { return try body($1) }
return try withUnsafeMutablePointers { return try body($0.1) }
}

/// Call `body` with `UnsafeMutablePointer`s to the stored `Header`
Expand Down Expand Up @@ -267,7 +267,7 @@ public struct ManagedBufferPointer<Header, Element> : Equatable {
public func withUnsafeMutablePointerToElements<R>(
_ body: @noescape (UnsafeMutablePointer<Element>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { return try body($1) }
return try withUnsafeMutablePointers { return try body($0.1) }
}

/// Call `body` with `UnsafeMutablePointer`s to the stored `Header`
Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/core/Mirror.swift
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ public struct Mirror {
self._makeSuperclassMirror = Mirror._superclassIterator(
subject, ancestorRepresentation)

let lazyChildren = children.lazy.map { Child(label: $0, value: $1) }
let lazyChildren = children.lazy.map { Child(label: $0.0, value: $0.1) }
self.children = Children(lazyChildren)

self.displayStyle = displayStyle
Expand Down Expand Up @@ -440,7 +440,7 @@ extension Mirror {
let children = Mirror(reflecting: result).children
let position: Children.Index
if case let label as String = e {
position = children.index { l, _ in l == label } ?? children.endIndex
position = children.index { $0.label == label } ?? children.endIndex
}
else if let offset = (e as? Int).map({ IntMax($0) }) ?? (e as? IntMax) {
position = children.index(children.startIndex,
Expand Down
4 changes: 2 additions & 2 deletions test/1_stdlib/Mirror.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extension Mirror {
let nil_ = "nil"
return "[" +
children.lazy
.map { "\($0 ?? nil_): \(String(reflecting: $1))" }
.map { "\($0.0 ?? nil_): \(String(reflecting: $0.1))" }
.joined(separator: ", ")
+ "]"
}
Expand Down Expand Up @@ -158,7 +158,7 @@ mirrors.test("Legacy") {
]
expectFalse(
zip(x0, m.children).contains {
$0.value as! Int != $1.value as! Int
$0.0.value as! Int != $0.1.value as! Int
})

class B { let bx: Int = 0 }
Expand Down
2 changes: 1 addition & 1 deletion test/1_stdlib/Renames.swift
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ func _SequenceAlgorithms<S : Sequence>(x: S) {
_ = x.minElement { _, _ in true } // expected-error {{'minElement' has been renamed to 'min(by:)'}} {{9-19=min}} {{none}}
_ = x.maxElement { _, _ in true } // expected-error {{'maxElement' has been renamed to 'max(by:)'}} {{9-19=max}} {{none}}
_ = x.reverse() // expected-error {{'reverse()' has been renamed to 'reversed()'}} {{9-16=reversed}} {{none}}
_ = x.startsWith([]) { _, _ in true } // expected-error {{'startsWith(_:isEquivalent:)' has been renamed to 'starts(with:by:)'}} {{9-19=starts}} {{20-20=with: }} {{none}}
_ = x.startsWith([]) { _ in true } // expected-error {{'startsWith(_:isEquivalent:)' has been renamed to 'starts(with:by:)'}} {{9-19=starts}} {{20-20=with: }} {{none}}
_ = x.lexicographicalCompare([]) { _, _ in true } // expected-error {{'lexicographicalCompare(_:isOrderedBefore:)' has been renamed to 'lexicographicallyPrecedes(_:by:)'}} {{9-31=lexicographicallyPrecedes}}{{none}}
}
func _SequenceAlgorithms<S : Sequence>(x: S) where S.Iterator.Element : Comparable {
Expand Down
2 changes: 1 addition & 1 deletion test/1_stdlib/UnsafePointer.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ ${SelfName}TestSuite.test("Comparable") {
func comparisonOracle(i: Int, j: Int) -> ExpectedComparisonResult {
return instances[i].0 <=> instances[j].0
}
checkComparable(instances.map { $1 }, oracle: comparisonOracle)
checkComparable(instances.map { $0.1 }, oracle: comparisonOracle)
}

% end
Expand Down
16 changes: 11 additions & 5 deletions test/Constraints/closures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ _ = myMap(intArray, { x -> String in String(x) } )

// Closures with too few parameters.
func foo(_ x: (Int, Int) -> Int) {}
foo({$0}) // expected-error{{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 1 were used in closure body}}
foo({$0}) // expected-error{{cannot convert value of type '(Int, Int)' to closure result type 'Int'}}

struct X {}
func mySort(_ array: [String], _ predicate: (String, String) -> Bool) -> [String] {}
Expand Down Expand Up @@ -121,16 +121,15 @@ var _: (Int,Int) -> Int = {$0+$1+$2}
// expected-error @+1 {{contextual closure type '(Int, Int, Int) -> Int' expects 3 arguments, but 2 were used in closure body}}
var _: (Int, Int, Int) -> Int = {$0+$1}

// expected-error @+1 {{contextual closure type '() -> Int' expects 0 arguments, but 1 were used in closure body}}
var _: () -> Int = {_ in 0}

var _: () -> Int = {a in 0}

// expected-error @+1 {{contextual closure type '(Int) -> Int' expects 1 argument, but 2 were used in closure body}}
var _: (Int) -> Int = {a,b in 0}

// expected-error @+1 {{contextual closure type '(Int) -> Int' expects 1 argument, but 3 were used in closure body}}
var _: (Int) -> Int = {a,b,c in 0}

// expected-error @+1 {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 1 were used in closure body}}
var _: (Int, Int) -> Int = {a in 0}

// expected-error @+1 {{contextual closure type '(Int, Int, Int) -> Int' expects 3 arguments, but 2 were used in closure body}}
Expand Down Expand Up @@ -203,7 +202,7 @@ func acceptNothingToInt (_: @noescape () -> Int) {}
func testAcceptNothingToInt(ac1: @autoclosure () -> Int) {
// expected-note@-1{{parameter 'ac1' is implicitly non-escaping because it was declared @autoclosure}}
acceptNothingToInt({ac1($0)})
// expected-error@-1{{contextual closure type '() -> Int' expects 0 arguments, but 1 were used in closure body}}
// expected-error@-1{{cannot convert value of type '(_) -> Int' to expected argument type '() -> Int'}}
// FIXME: expected-error@-2{{closure use of non-escaping parameter 'ac1' may allow it to escape}}
}

Expand Down Expand Up @@ -284,6 +283,13 @@ func rdar21078316() {
bar = foo.map { ($0, $1) } // expected-error {{contextual closure type '([String : String]) -> [(String, String)]' expects 1 argument, but 2 were used in closure body}}
}


// <rdar://problem/20978044> QoI: Poor diagnostic when using an incorrect tuple element in a closure
var numbers = [1, 2, 3]
zip(numbers, numbers).filter { $0.2 > 1 } // expected-error {{value of tuple type '(Int, Int)' has no member '2'}}



// <rdar://problem/20868864> QoI: Cannot invoke 'function' with an argument list of type 'type'
func foo20868864(_ callback: ([String]) -> ()) { }
func rdar20868864(_ s: String) {
Expand Down
2 changes: 1 addition & 1 deletion test/Constraints/tuple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ extension r25271859 {
}

func f(a : r25271859<(Float, Int)>) {
a.map { f, _ in f }
a.map { $0.0 }
.andThen { _ in // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{18-18=-> r25271859<String> }}
print("hello") // comment this out and it runs, leave any form of print in and it doesn't
return r25271859<String>()
Expand Down
2 changes: 1 addition & 1 deletion test/DebugInfo/WeakCapture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func function() {
// CHECK: call void @llvm.dbg.{{.*}}(metadata %swift.weak*
// CHECK-NOT: metadata [[B]]
// CHECK: call
A(handler: { [weak b] in
A(handler: { [weak b] _ in
if b != nil { }
})
}
Expand Down
3 changes: 1 addition & 2 deletions test/DebugInfo/mangling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,4 @@ var myTuple3 : ( String, Int64) = ("C", 3)

markUsed(myTuple1.Id)
markUsed(myTuple2.Id)
func f(_ a: (String, Int64)) {}
markUsed(f(myTuple3))
markUsed({ $0.1 }(myTuple3))
12 changes: 6 additions & 6 deletions test/Interpreter/collection_casts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ print("Dictionaries.")

let a_dict = ["one" : A(1), "two" : A(2), "three" : A(3)]
print("begin")
a_dict.forEach { $1.preen() }
a_dict.forEach { $0.1.preen() }
print("end")
// CHECK-NEXT: begin
// CHECK-DAG: A1
Expand All @@ -91,7 +91,7 @@ print("end")

let preening_dict_1 = a_dict as [String: Preening]
print("begin")
preening_dict_1.forEach { $1.preen() }
preening_dict_1.forEach { $0.1.preen() }
print("end")
// CHECK-NEXT: begin
// CHECK-DAG: A1
Expand All @@ -105,7 +105,7 @@ print(any_dict_1.count)

let preening_dict_2 = any_dict_1 as! [String: Preening]
print("begin")
preening_dict_2.forEach { $1.preen() }
preening_dict_2.forEach { $0.1.preen() }
print("end")
// CHECK-NEXT: begin
// CHECK-DAG: A1
Expand All @@ -115,7 +115,7 @@ print("end")

let preening_dict_3 = any_dict_1 as? [String: Preening]
print("begin")
preening_dict_3?.forEach { $1.preen() }
preening_dict_3?.forEach { $0.1.preen() }
print("end")
// CHECK-NEXT: begin
// CHECK-DAG: A1
Expand All @@ -125,7 +125,7 @@ print("end")

let a_dict_2 = any_dict_1 as! [String: A]
print("begin")
a_dict_2.forEach { $1.preen() }
a_dict_2.forEach { $0.1.preen() }
print("end")
// CHECK-NEXT: begin
// CHECK-DAG: A1
Expand All @@ -135,7 +135,7 @@ print("end")

let a_dict_3 = any_dict_1 as? [String: A]
print("begin")
a_dict_3?.forEach { $1.preen() }
a_dict_3?.forEach { $0.1.preen() }
print("end")
// CHECK-NEXT: begin
// CHECK-DAG: A1
Expand Down
4 changes: 2 additions & 2 deletions test/Prototypes/Result.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ func mayFail(_ fail: Bool) throws -> Int {
print(catchResult { try mayFail(true) })
print(catchResult { try mayFail(false) })

print(catchResult { 1 }.flatMap { _ in Result(success: 4) }.flatMap { _ in Result<String>(error: Icky.Poor) })
print(catchResult { 1 }.map { _ in three }.flatMap {$0} )
print(catchResult { _ in 1 }.flatMap { _ in Result(success: 4) }.flatMap { _ in Result<String>(error: Icky.Poor) })
print(catchResult { _ in 1 }.map { _ in three }.flatMap {$0} )

let results = [three, nasty, four]
print(results.flatMap { $0.success })
Expand Down
4 changes: 2 additions & 2 deletions test/SILGen/apply_abstraction_nested.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ infix operator ~> { precedence 255 associativity left }

protocol P { }

func bar<T:P>(_: inout T) -> () -> () { return { } }
func baz<T:P>(_: inout T) -> (Int) -> () { return { _ in } }
func bar<T:P>(_: inout T) -> () -> () { return {_ in ()} }
func baz<T:P>(_: inout T) -> (Int) -> () { return {_ in ()} }

func ~> <T: P, Args, Result>(
x: inout T,
Expand Down
2 changes: 1 addition & 1 deletion test/SILGen/closures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -590,5 +590,5 @@ class GenericDerived<Ocean> : ConcreteBase {
// Don't crash on this
func r25993258_helper(_ fn: (inout Int, Int) -> ()) {}
func r25993258() {
r25993258_helper { _, _ in () }
r25993258_helper { _ in () }
}
Loading