Skip to content

[stdlib] 0-ary tuples should be equatable #8354

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 5 commits into from
Jul 12, 2017
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
76 changes: 76 additions & 0 deletions stdlib/public/core/Tuple.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,82 @@ comparableOperators = [

}%

/// Returns a Boolean value indicating whether the corresponding components of
/// two tuples are equal.
///
/// All arity zero tuples are equal.
///
/// - Parameters:
/// - lhs: An empty tuple.
/// - rhs: An empty tuple.
public func ==(lhs: (), rhs: ()) -> Bool {
return true
}

/// Returns a Boolean value indicating whether any corresponding components of
/// the two tuples are not equal.
///
/// All arity zero tuples are equal.
///
/// - Parameters:
/// - lhs: An empty tuple.
/// - rhs: An empty tuple.
public func !=(lhs: (), rhs: ()) -> Bool {
return false
}

/// Returns a Boolean value indicating whether the first tuple is ordered
/// before the second in a lexicographical ordering.
///
/// An arity zero tuple is never strictly before another arity zero tuple in a
/// lexicographical ordering.
///
/// - Parameters:
/// - lhs: An empty tuple.
/// - rhs: An empty tuple.
public func <(lhs: (), rhs: ()) -> Bool {
return false
}

/// Returns a Boolean value indicating whether the first tuple is ordered
/// before or the same as the second in a lexicographical ordering.
///
/// An arity zero tuple is always before or the same as another arity zero tuple
/// in a lexicographical ordering.
///
/// - Parameters:
/// - lhs: An empty tuple.
/// - rhs: An empty tuple.
public func <=(lhs: (), rhs: ()) -> Bool {
return true
}

/// Returns a Boolean value indicating whether the first tuple is ordered
/// after the second in a lexicographical ordering.
///
/// An arity zero tuple is never strictly after another arity zero tuple in a
/// lexicographical ordering.
///
/// - Parameters:
/// - lhs: An empty tuple.
/// - rhs: An empty tuple.
public func >(lhs: (), rhs: ()) -> Bool {
return false
}

/// Returns a Boolean value indicating whether the first tuple is ordered
/// after or the same as the second in a lexicographical ordering.
///
/// An arity zero tuple is always after or the same as another arity zero tuple
/// in a lexicographical ordering.
///
/// - Parameters:
/// - lhs: An empty tuple.
/// - rhs: An empty tuple.
public func >=(lhs: (), rhs: ()) -> Bool {
return true
}

% for arity in range(2,7):
% typeParams = [chr(ord("A") + i) for i in range(arity)]
% tupleT = "({})".format(",".join(typeParams))
Expand Down
15 changes: 14 additions & 1 deletion test/IDE/complete_operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_12 | %FileCheck %s -check-prefix=INFIX_12
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_13 | %FileCheck %s -check-prefix=NO_OPERATORS
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_14 | %FileCheck %s -check-prefix=NO_OPERATORS

// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_15 | %FileCheck %s -check-prefix=INFIX_15
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_16 | %FileCheck %s -check-prefix=INFIX_16
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_17 | %FileCheck %s -check-prefix=NO_OPERATORS
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_17 | %FileCheck %s -check-prefix=VOID_OPERATORS
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_18 | %FileCheck %s -check-prefix=NO_OPERATORS
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_19 | %FileCheck %s -check-prefix=EMPTYCLASS_INFIX
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=INFIX_20 | %FileCheck %s -check-prefix=NO_OPERATORS
Expand Down Expand Up @@ -243,6 +244,7 @@ func testInfix10<T: P where T.T: Fooable>(x: T) {
func testInfix11() {
S2#^INFIX_11^#
}

// INFIX_11: Begin completions, 1 items
// INFIX_11-DAG: Decl[Constructor]/CurrNominal: ()[#S2#]; name=()
// INFIX_11: End completions
Expand Down Expand Up @@ -274,13 +276,24 @@ func testInfix15<T: P where T.T == S2>() {
func testInfix16<T: P where T.T == S2>() {
T.foo#^INFIX_16^#
}

// INFIX_16: Begin completions, 1 items
// INFIX_16-NEXT: Pattern/ExprSpecific: ({#(self): T#})[#() -> S2#]; name=(self: T)
// INFIX_16: End completions

func testInfix17(x: Void) {
x#^INFIX_17^#
}

// VOID_OPERATORS: Begin completions
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally want some feedback as to where the CHECK: lines need to go. Even before this PR seems like the NO_OPERATORS-NOT was in a strange place, but could be my misunderstanding.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FileCheck is part of LLVM. See here for the documentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see how this is related to the change. () is same as Void, and therefore we get all the equality/comparison ops on the value of type Void. This might have other consequences...

Copy link
Contributor Author

@anayini anayini Apr 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Took me a bit to figure out, but yeah SourceKit code completion was offering suggestions of all the equality/comparison ops that were added, but it wasn't expecting any suggestions so this test was failing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// VOID_OPERATORS-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#()#}[#Bool#]; name=!= ()
// VOID_OPERATORS-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#()#}[#Bool#]; name=== ()
// VOID_OPERATORS-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: <= {#()#}[#Bool#]; name=<= ()
// VOID_OPERATORS-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: >= {#()#}[#Bool#]; name=>= ()
// VOID_OPERATORS-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#()#}[#Bool#]; name=< ()
// VOID_OPERATORS-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#()#}[#Bool#]; name=> ()
// VOID_OPERATORS: End completions

func testInfix18(x: (S2, S2) {
x#^INFIX_18^#
}
Expand Down
8 changes: 8 additions & 0 deletions test/stdlib/Tuple.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ TupleTestSuite.test("Tuple/equality") {

TupleTestSuite.test("Tuple/equality/sanity-check") {
// sanity check all arities

expectTrue(() == ())
expectFalse(() != ())
expectFalse(() < ())
expectTrue(() <= ())
expectFalse(() > ())
expectTrue(() >= ())

% for arity in range(2, maxArity + 1):
% a = str(tuple(range(1, arity + 1)))
% b = "({}, 0)".format(", ".join([str(i) for i in range(1, arity)]))
Expand Down