[Pitch] make == more restrictive at compile time


(Gerd Castan) #1

Motivation:

The following code emits no compiler error in Swift 2.2:

import Foundation
func EQTest(lhs: NSArray, rhs: String) -> Bool {
    return (lhs == rhs)
}

I can imagine no use case where this code example makes sense, so I
would expect an error at compile time.

the function that makes this code valid is
@warn_unused_result
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

Proposal:

find a way for the compiler to emit an error for the code example.

Discussion:

I can think of several ways to solve this:

1. remove "public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool" from
the library
2. annotate "public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool" so
that the compiler emits an error in the cate that there is no more
specific implementation.

I leave the way to implement this to a discussion since I'm not sure
which one (or some completely different approach) will lead to a
consistent language design.

I have the feeling that approach 2 is easier, better and gives more
control since it moves the responsibility for the error handling from
the compiler to the library where everybody (including the compiler) can
read it.

There might be more functions like "public func ==<T : Equatable>(lhs:
T?, rhs: T?) -> Bool" that lets the compiler accept nonsense tests for
equality for more specific cases. They should be handled in a similar
and consistent way if they exist.

This change is intended to let programers getting things done faster and
with less coding errors in Swift.

Gerd
https://github.com/GerdC


(Robert Widmann) #2

Even if that were removed "heterogenous" equality checks are valid under the remaining typing rules because both objects are Equatable and descend from NSObject meaning Swift will upcast, invoke this "nonsense", and make the comparison anyway. You can verify this by reimplementing vanilla == and invoking the comparison you give in the pitch.

I think you want a way of controlling (in this case, turning off) subtyping with variance annotations.

~Robert Widmann

2016/05/05 5:24、Gerd Castan via swift-evolution <swift-evolution@swift.org> のメッセージ:

···

Motivation:

The following code emits no compiler error in Swift 2.2:

import Foundation
func EQTest(lhs: NSArray, rhs: String) -> Bool {
   return (lhs == rhs)
}

I can imagine no use case where this code example makes sense, so I
would expect an error at compile time.

the function that makes this code valid is
@warn_unused_result
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

Proposal:

find a way for the compiler to emit an error for the code example.

Discussion:

I can think of several ways to solve this:

1. remove "public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool" from
the library
2. annotate "public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool" so
that the compiler emits an error in the cate that there is no more
specific implementation.

I leave the way to implement this to a discussion since I'm not sure
which one (or some completely different approach) will lead to a
consistent language design.

I have the feeling that approach 2 is easier, better and gives more
control since it moves the responsibility for the error handling from
the compiler to the library where everybody (including the compiler) can
read it.

There might be more functions like "public func ==<T : Equatable>(lhs:
T?, rhs: T?) -> Bool" that lets the compiler accept nonsense tests for
equality for more specific cases. They should be handled in a similar
and consistent way if they exist.

This change is intended to let programers getting things done faster and
with less coding errors in Swift.

Gerd
https://github.com/GerdC

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Joe Groff) #3

Motivation:

The following code emits no compiler error in Swift 2.2:

import Foundation
func EQTest(lhs: NSArray, rhs: String) -> Bool {
   return (lhs == rhs)
}

This works because String can implicitly bridge to NSString, and both NSArray and NSString are subclasses of NSObject. SE-0072 proposes to remove the implicit bridging behavior, which would prevent this from compiling.

-Joe

···

On May 5, 2016, at 2:24 AM, Gerd Castan via swift-evolution <swift-evolution@swift.org> wrote:

I can imagine no use case where this code example makes sense, so I
would expect an error at compile time.

the function that makes this code valid is
@warn_unused_result
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

Proposal:

find a way for the compiler to emit an error for the code example.

Discussion:

I can think of several ways to solve this:

1. remove "public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool" from
the library
2. annotate "public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool" so
that the compiler emits an error in the cate that there is no more
specific implementation.

I leave the way to implement this to a discussion since I'm not sure
which one (or some completely different approach) will lead to a
consistent language design.

I have the feeling that approach 2 is easier, better and gives more
control since it moves the responsibility for the error handling from
the compiler to the library where everybody (including the compiler) can
read it.

There might be more functions like "public func ==<T : Equatable>(lhs:
T?, rhs: T?) -> Bool" that lets the compiler accept nonsense tests for
equality for more specific cases. They should be handled in a similar
and consistent way if they exist.

This change is intended to let programers getting things done faster and
with less coding errors in Swift.

Gerd
https://github.com/GerdC

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution