Skip to content

[stdlib]Custom message for recursive Strideable witness #11623

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
Sep 16, 2017

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Aug 25, 2017

The wording for the errors and the docs needs to be shopped, but otherwise this should do it.

Improves QoI for rdar://33668987

@CodaFi CodaFi requested a review from moiseev August 25, 2017 20:49
@CodaFi
Copy link
Contributor Author

CodaFi commented Aug 25, 2017

@swift-ci please smoke test

@moiseev
Copy link
Contributor

moiseev commented Aug 25, 2017

/cc @natecook1000

Copy link
Contributor

@moiseev moiseev left a comment

Choose a reason for hiding this comment

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

As discussed in person. The problem with StdlibUnittest style test is that it would succeed even without your patch. Validating the message is essential in this case, and so it should be a file-check style test.

A minor nitpick: all the non-mutating binary operators in InvalidStrideable are not needed, since there are default implementations for them.

@moiseev moiseev changed the title [DO NOT MERGE] Custom message for recursive Strideable witness [DO NOT MERGE] [stdlib]Custom message for recursive Strideable witness Aug 25, 2017
@@ -23,6 +23,9 @@
}%
/// Conforming types are notionally continuous, one-dimensional
/// values that can be offset and measured.
///
/// - Warning: If 'Stride == Self' you must provide an implementation of
/// 'Equatable' and 'Comparable'.
Copy link
Member

Choose a reason for hiding this comment

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

Could we use this language instead for now?

/// - Important: The `Strideable` protocol provides default implementations for 
///   the equal-to (`==`) and less-than (`<`) operators that depend on the 
///   `Stride` type's implementations. If a type conforming to `Strideable` 
///   is its own `Stride` type, it must provide concrete implementations of 
///   the two operators to avoid infinite recursion.

fatalError("""
Strideable conformance where 'Stride == Self' requires user-defined
implementation of Equatable and Comparable.
""")
Copy link
Member

Choose a reason for hiding this comment

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

We should be specific about what needs to be implemented here.

fatalError("""
  Strideable conformance where 'Stride == Self' requires user-defined
  implementation of the '<' operator.
  """)

Also, probably indent the trailing """ so the message isn't indented.

@CodaFi
Copy link
Contributor Author

CodaFi commented Aug 26, 2017

@moiseev It seems that the mutating and non-mutating operators are required, otherwise I get ambiguities with requirements inherited, unsurprisingly, from Strideable extensions in Stdlib.

Going to move this to a validation test to test the crash message

@CodaFi
Copy link
Contributor Author

CodaFi commented Aug 27, 2017

@swift-ci please test

@moiseev
Copy link
Contributor

moiseev commented Aug 28, 2017

This change adds even more overloads to an already crowded space. Worth timing stdlib compile times... Just to be sure.

@CodaFi CodaFi changed the title [DO NOT MERGE] [stdlib]Custom message for recursive Strideable witness [stdlib]Custom message for recursive Strideable witness Aug 28, 2017
@natecook1000
Copy link
Member

Out of curiosity, did we consider removing Strideable's default implementations of == and < as an alternative solution?

@CodaFi
Copy link
Contributor Author

CodaFi commented Aug 29, 2017

I originally wanted to, but doing so is source-breaking. FWIW, these are correct witnesses in every case but the one in the validation test/radar. You really have to struggle with basically re-implementing a numeric type to come close to this trap.

@CodaFi
Copy link
Contributor Author

CodaFi commented Aug 29, 2017

(Or, in my case, break overload resolution for all the numeric types and wonder why LLVM was inserting infinite loops in odd places)

@jrose-apple
Copy link
Contributor

Hm. This is a little unfortunate because they become part of the ABI, but I guess they're tiny. Can you also mark them deprecated, so that the user will get a warning at compile time too? (Unfortunately they can't be unavailable because that affects overload resolution.)

@jckarter
Copy link
Contributor

The ABI impact could be nullified by making them inlinable, when we have that.

Strideable declares a default witness for Equatable and Comparable

extension Strideable {
  @_inlineable
  public static func < (x: Self, y: Self) -> Bool {
    return x.distance(to: y) > 0
  }

  @_inlineable
  public static func == (x: Self, y: Self) -> Bool {
    return x.distance(to: y) == 0
  }
}

This witness is implemented recursively because the expectation
is that Stride != Self.  However, it is possible to implement
SignedNumeric and Strideable together and inherit this conformance
which will cause undefined behavior - usually a crash.

Provide an overload when Stride == Self and crash with custom message
that mentions that Equatable and Comparable have to be implemented
in this case.

- It's better than nothing.
@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 15, 2017

@swift-ci please test

@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 15, 2017

@swift-ci please test source compatibility

@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 16, 2017

⛵️

@CodaFi CodaFi merged commit 74f02ad into swiftlang:master Sep 16, 2017
@CodaFi CodaFi deleted the fundef branch September 16, 2017 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants