Skip to content
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

Use Borrow for binary_search and contains methods in the standard library #37761

Merged
merged 1 commit into from
Dec 21, 2016

Conversation

christophebiocca
Copy link
Contributor

Fixes all standard library methods in #32822 that can be fixed without backwards compatibility issues.

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

{
self.iter().any(|e| e == x)
self.iter().any(|e| e.borrow() == x)
}
Copy link
Member

@bluss bluss Nov 14, 2016

Choose a reason for hiding this comment

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

There's another choice isn't there, to use fn contains<Q: ?Sized>(&self, x: &Q) -> bool where T: PartialEq<Q> instead? I think that is more flexible than using Borrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that seems like it would work better for all the contains implementations, given that anyone who implements Borrow<Q> usually implements PartialEq<Q>. Bit of tunnel vision on my part given the issue description.

The binary searches still do need to use Borrow (unless Ord<RHS> were to become a thing).

@bluss
Copy link
Member

bluss commented Nov 14, 2016

The test failure looks legit unfortunately — so that is a hint that it can cause type inference-related regressions. Should probably get a crater run when it's ready.

@alexcrichton
Copy link
Member

Thanks for the PR! I've started a crater run to evaluate the impact across the ecosystem here.

@alexcrichton
Copy link
Member

Unfortunately crater turned up with 28 regressions, so we may not be able to make this change :(

@alexcrichton alexcrichton added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Nov 15, 2016
@bluss
Copy link
Member

bluss commented Nov 15, 2016

@alexcrichton Note other comments, about revising the PR to use PartialEq for contains.

I guess with crates having code such as .contains(&"down.sql".into()) there's not much hope for that one either..

@christophebiocca
Copy link
Contributor Author

The type-inference regression will still occur, so I suspect this new code will cause essentially the same regressions.

@jethrogb
Copy link
Contributor

jethrogb commented Nov 15, 2016

PartialEq has a default type parameter though?

Edit: just tested this (playpen), not sure why that's not sufficient.

@bluss
Copy link
Member

bluss commented Nov 15, 2016

There are no regressions due to .binary_search in the crater root regressions. Then, a minority is due to type inference failure or coercion failure when using .contains().

The absolute majority of the root regressions are due to an unrelated error:

curl: (56) GnuTLS recv error (-54): Error in the pull function.

[taskcluster 2016-11-15 00:23:23.175Z] === Task Finished ===

[taskcluster 2016-11-15 00:23:23.176Z] Unsuccessful task run with exit code: 56 completed in 2.348 seconds

@alexcrichton
Copy link
Member

Crater report for current PR reports 10 regressions

@BurntSushi
Copy link
Member

If we remove the changes to contains, can we still make the changes to binary_search? Of the 10 root regressions in the most recent crater report, 5 look spurious and the other 5 only appear on contains.

@letheed
Copy link
Contributor

letheed commented Nov 22, 2016

True. The fixes are trivial though and usually lead to code simplification:

  • afterparty and clapx2: remove leading &
  • Inflector: remove .as_ref()
  • diesel: remove .into()

@BurntSushi
Copy link
Member

@letheed I think we should be mindful/conservative about making this change even if crater said things were all clear. If it's going to break popular crates, then I don't think we should do it, no matter how trivial the fix is.

@bluss
Copy link
Member

bluss commented Nov 22, 2016

Crater is only an indication of the issues, it's far from all Rust code in existence.

@letheed
Copy link
Contributor

letheed commented Nov 22, 2016

@BurntSushi And I enjoy that things don't break at every new release of Rust. Still this proposed implementation for contains has merits. It should have been the one provided from the start.
Should a dedicated issue be created and tagged rust-2-breakage-wishlist?

@bluss
Copy link
Member

bluss commented Nov 22, 2016

Can this be solved by type parameter fallback? If so, it doesn't need Rust 2.

@christophebiocca
Copy link
Contributor Author

@bluss, as best as I can tell type parameter fallback defaults do not work for functions, and it isn't 100% clear to me that they ever could work for functions.

@bluss
Copy link
Member

bluss commented Nov 22, 2016

@christophebiocca Did you try the feature in #27336?

@christophebiocca
Copy link
Contributor Author

#27336 (comment) seems to indicate that default parameters do not work for fn, and there isn't any PR implementing it. But I might be wrong, it seems like that feature was talked about a lot over the last 2 years.

@bluss
Copy link
Member

bluss commented Nov 22, 2016

Ok, some experiments. It is implemented for functions, because fn get<T: Default = u32>() -> T { T::default() } works as expected and falls back to the given T type.

But the example in https://is.gd/cKIj8U says that the default fallback can not be used to cover up for type inference breaks.

@christophebiocca christophebiocca force-pushed the borrow-stdlib-fn-refactor branch 2 times, most recently from db95b4c to c470d4a Compare November 27, 2016 20:46
@christophebiocca
Copy link
Contributor Author

Rebased the branch to only have the binary_search changes, since those can land on their own.

I'm not sure what we want to do for the contains changes.

@alexcrichton
Copy link
Member

cc @rust-lang/libs

This is kinda unfortunate where in theory we'd want to extend multiple APIs, but backwards compatibility forces us to only extend a few. That has the risk of leading to a surprisingly inconsistent experience across the standard library. Not doing this, however, also leads to a surprise where it's something that "should work" but doesn't. I'm not entirely sure what the best resolution is here.

@aturon
Copy link
Member

aturon commented Dec 3, 2016

I think I'm in favor. My biggest worry isn't about the inconsistency (which already exists, since we have this functionality for maps but not other structures). Rather, I worry about degrading the docs experience elsewhere. Still, given that we've committed to it for maps, which are one of the most common data structures, we may as well double down (and work on improving docs across the board).

@alexcrichton
Copy link
Member

@bors: r+

Discussed during triage today and decision was to move forward, thanks for being patient @christophebiocca!

@bors
Copy link
Contributor

bors commented Dec 20, 2016

📌 Commit c470d4a has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Dec 20, 2016

⌛ Testing commit c470d4a with merge 7bad2c3...

@bors
Copy link
Contributor

bors commented Dec 20, 2016

💔 Test failed - auto-mac-32-opt

@alexcrichton
Copy link
Member

alexcrichton commented Dec 20, 2016 via email

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Dec 20, 2016
…efactor, r=alexcrichton

Use Borrow for binary_search and contains methods in the standard library

Fixes all standard library methods in rust-lang#32822 that can be fixed without backwards compatibility issues.
bors added a commit that referenced this pull request Dec 20, 2016
@bors bors merged commit c470d4a into rust-lang:master Dec 21, 2016
jsonn pushed a commit to jsonn/pkgsrc that referenced this pull request Mar 20, 2017
Version 1.16.0 (2017-03-16)
===========================

Language
--------

* Lifetimes in statics and consts default to `'static`. [RFC 1623]
* [The compiler's `dead_code` lint now accounts for type aliases][38051].
* [Uninhabitable enums (those without any variants) no longer permit wildcard
  match patterns][38069]
* [Clean up semantics of `self` in an import list][38313]
* [`Self` may appear in `impl` headers][38920]
* [`Self` may appear in struct expressions][39282]

Compiler
--------

* [`rustc` now supports `--emit=metadata`, which causes rustc to emit
  a `.rmeta` file containing only crate metadata][38571]. This can be
  used by tools like the Rust Language Service to perform
  metadata-only builds.
* [Levenshtein based typo suggestions now work in most places, while
  previously they worked only for fields and sometimes for local
  variables][38927]. Together with the overhaul of "no
  resolution"/"unexpected resolution" errors (#[38154]) they result in
  large and systematic improvement in resolution diagnostics.
* [Fix `transmute::<T, U>` where `T` requires a bigger alignment than
  `U`][38670]
* [rustc: use -Xlinker when specifying an rpath with ',' in it][38798]
* [`rustc` no longer attempts to provide "consider using an explicit
  lifetime" suggestions][37057]. They were inaccurate.

Stabilized APIs
---------------

* [`VecDeque::truncate`]
* [`VecDeque::resize`]
* [`String::insert_str`]
* [`Duration::checked_add`]
* [`Duration::checked_sub`]
* [`Duration::checked_div`]
* [`Duration::checked_mul`]
* [`str::replacen`]
* [`str::repeat`]
* [`SocketAddr::is_ipv4`]
* [`SocketAddr::is_ipv6`]
* [`IpAddr::is_ipv4`]
* [`IpAddr::is_ipv6`]
* [`Vec::dedup_by`]
* [`Vec::dedup_by_key`]
* [`Result::unwrap_or_default`]
* [`<*const T>::wrapping_offset`]
* [`<*mut T>::wrapping_offset`]
* `CommandExt::creation_flags`
* [`File::set_permissions`]
* [`String::split_off`]

Libraries
---------

* [`[T]::binary_search` and `[T]::binary_search_by_key` now take
  their argument by `Borrow` parameter][37761]
* [All public types in std implement `Debug`][38006]
* [`IpAddr` implements `From<Ipv4Addr>` and `From<Ipv6Addr>`][38327]
* [`Ipv6Addr` implements `From<[u16; 8]>`][38131]
* [Ctrl-Z returns from `Stdin.read()` when reading from the console on
  Windows][38274]
* [std: Fix partial writes in `LineWriter`][38062]
* [std: Clamp max read/write sizes on Unix][38062]
* [Use more specific panic message for `&str` slicing errors][38066]
* [`TcpListener::set_only_v6` is deprecated][38304]. This
  functionality cannot be achieved in std currently.
* [`writeln!`, like `println!`, now accepts a form with no string
  or formatting arguments, to just print a newline][38469]
* [Implement `iter::Sum` and `iter::Product` for `Result`][38580]
* [Reduce the size of static data in `std_unicode::tables`][38781]
* [`char::EscapeDebug`, `EscapeDefault`, `EscapeUnicode`,
  `CaseMappingIter`, `ToLowercase`, `ToUppercase`, implement
  `Display`][38909]
* [`Duration` implements `Sum`][38712]
* [`String` implements `ToSocketAddrs`][39048]

Cargo
-----

* [The `cargo check` command does a type check of a project without
  building it][cargo/3296]
* [crates.io will display CI badges from Travis and AppVeyor, if
  specified in Cargo.toml][cargo/3546]
* [crates.io will display categories listed in Cargo.toml][cargo/3301]
* [Compilation profiles accept integer values for `debug`, in addition
  to `true` and `false`. These are passed to `rustc` as the value to
  `-C debuginfo`][cargo/3534]
* [Implement `cargo --version --verbose`][cargo/3604]
* [All builds now output 'dep-info' build dependencies compatible with
  make and ninja][cargo/3557]
* [Build all workspace members with `build --all`][cargo/3511]
* [Document all workspace members with `doc --all`][cargo/3515]
* [Path deps outside workspace are not members][cargo/3443]

Misc
----

* [`rustdoc` has a `--sysroot` argument that, like `rustc`, specifies
  the path to the Rust implementation][38589]
* [The `armv7-linux-androideabi` target no longer enables NEON
  extensions, per Google's ABI guide][38413]
* [The stock standard library can be compiled for Redox OS][38401]
* [Rust has initial SPARC support][38726]. Tier 3. No builds
  available.
* [Rust has experimental support for Nvidia PTX][38559]. Tier 3. No
  builds available.
* [Fix backtraces on i686-pc-windows-gnu by disabling FPO][39379]

Compatibility Notes
-------------------

* [Uninhabitable enums (those without any variants) no longer permit wildcard
  match patterns][38069]
* In this release, references to uninhabited types can not be
  pattern-matched. This was accidentally allowed in 1.15.
* [The compiler's `dead_code` lint now accounts for type aliases][38051].
* [Ctrl-Z returns from `Stdin.read()` when reading from the console on
  Windows][38274]
* [Clean up semantics of `self` in an import list][38313]

[37057]: rust-lang/rust#37057
[37761]: rust-lang/rust#37761
[38006]: rust-lang/rust#38006
[38051]: rust-lang/rust#38051
[38062]: rust-lang/rust#38062
[38062]: rust-lang/rust#38622
[38066]: rust-lang/rust#38066
[38069]: rust-lang/rust#38069
[38131]: rust-lang/rust#38131
[38154]: rust-lang/rust#38154
[38274]: rust-lang/rust#38274
[38304]: rust-lang/rust#38304
[38313]: rust-lang/rust#38313
[38314]: rust-lang/rust#38314
[38327]: rust-lang/rust#38327
[38401]: rust-lang/rust#38401
[38413]: rust-lang/rust#38413
[38469]: rust-lang/rust#38469
[38559]: rust-lang/rust#38559
[38571]: rust-lang/rust#38571
[38580]: rust-lang/rust#38580
[38589]: rust-lang/rust#38589
[38670]: rust-lang/rust#38670
[38712]: rust-lang/rust#38712
[38726]: rust-lang/rust#38726
[38781]: rust-lang/rust#38781
[38798]: rust-lang/rust#38798
[38909]: rust-lang/rust#38909
[38920]: rust-lang/rust#38920
[38927]: rust-lang/rust#38927
[39048]: rust-lang/rust#39048
[39282]: rust-lang/rust#39282
[39379]: rust-lang/rust#39379
[`<*const T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset
[`<*mut T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset
[`Duration::checked_add`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_add
[`Duration::checked_div`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_div
[`Duration::checked_mul`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_mul
[`Duration::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_sub
[`File::set_permissions`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.set_permissions
[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_ipv4
[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_ipv6
[`Result::unwrap_or_default`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default
[`SocketAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv4
[`SocketAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv6
[`String::insert_str`]: https://doc.rust-lang.org/std/string/struct.String.html#method.insert_str
[`String::split_off`]: https://doc.rust-lang.org/std/string/struct.String.html#method.split_off
[`Vec::dedup_by_key`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by_key
[`Vec::dedup_by`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by
[`VecDeque::resize`]:  https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.resize
[`VecDeque::truncate`]: https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.truncate
[`str::repeat`]: https://doc.rust-lang.org/std/primitive.str.html#method.repeat
[`str::replacen`]: https://doc.rust-lang.org/std/primitive.str.html#method.replacen
[cargo/3296]: rust-lang/cargo#3296
[cargo/3301]: rust-lang/cargo#3301
[cargo/3443]: rust-lang/cargo#3443
[cargo/3511]: rust-lang/cargo#3511
[cargo/3515]: rust-lang/cargo#3515
[cargo/3534]: rust-lang/cargo#3534
[cargo/3546]: rust-lang/cargo#3546
[cargo/3557]: rust-lang/cargo#3557
[cargo/3604]: rust-lang/cargo#3604
[RFC 1623]: https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md
bors added a commit that referenced this pull request Aug 20, 2017
Remove Borrow bound from SliceExt::binary_search

#37761 added a Borrow bound to `binary_search` and `binary_search_by_key` in `core::SliceExt`, but did not add it to the methods in `std::slice`. #41590 attempted to add this bound to `std::slice` but was not merged due to breakage. This PR removes the bound in `core::SliceExt`, so that these methods will have the same signature in `core` and `std`.

Fixes #41561
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Sep 16, 2017
…ig, r=alexcrichton

Remove Borrow bound from SliceExt::binary_search

rust-lang#37761 added a Borrow bound to `binary_search` and `binary_search_by_key` in `core::SliceExt`, but did not add it to the methods in `std::slice`. rust-lang#41590 attempted to add this bound to `std::slice` but was not merged due to breakage. This PR removes the bound in `core::SliceExt`, so that these methods will have the same signature in `core` and `std`.

Fixes rust-lang#41561
bors added a commit that referenced this pull request Sep 16, 2017
…richton

Remove Borrow bound from SliceExt::binary_search

#37761 added a Borrow bound to `binary_search` and `binary_search_by_key` in `core::SliceExt`, but did not add it to the methods in `std::slice`. #41590 attempted to add this bound to `std::slice` but was not merged due to breakage. This PR removes the bound in `core::SliceExt`, so that these methods will have the same signature in `core` and `std`.

Fixes #41561
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants