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

Implement Error for &(impl Error) #75180

Merged
merged 3 commits into from
Jan 25, 2021
Merged

Implement Error for &(impl Error) #75180

merged 3 commits into from
Jan 25, 2021

Conversation

KodrAus
Copy link
Contributor

@KodrAus KodrAus commented Aug 5, 2020

Opening this up just to see what it breaks. It's unfortunate that &(impl Error) doesn't actually implement Error. If this direct approach doesn't work out then I'll try something different, like an Error::by_ref method.

EDIT: This is a super low-priority experiment so feel free to cancel it for more important crater runs! 🙂


Stabilization Report

Why?

We've been working for the last few years to try "fix" the Error trait, which is probably one of the most fundamental in the whole standard library. One of its issues is that we commonly expect you to work with abstract errors through dyn Trait, but references and smart pointers over dyn Trait don't actually implement the Error trait. If you have a &dyn Error or a Box<dyn Error> you simply can't pass it to a method that wants a impl Error.

What does this do?

This stabilizes the following trait impl:

impl<'a, T: Error + ?Sized + 'static> Error for &'a T;

This means that &dyn Error will now satisfy a impl Error bound.

It doesn't do anything with Box<dyn Error> directly. We discussed how we could do Box<dyn Error> in the thread here (and elsewhere in the past), but it seems like we need something like lattice-based specialization or a sprinkling of snowflake compiler magic to make that work. Having said that, with this new impl you can now get a impl Error from a Box<dyn Error> by dereferencing it.

What breaks?

A crater run revealed a few crates broke with something like the following:

// where e: &'short &'long dyn Error
err.source()

previously we'd auto-deref that &'short &'long dyn Error to return a Option<&'long dyn Error> from source, but now will call directly on &'short impl Error, so will return a Option<&'short dyn Error>. The fix is to manually deref:

// where e: &'short &'long dyn Error
(*err).source()

In the recent Libs meeting we considered this acceptable breakage.

@rust-highfive
Copy link
Collaborator

r? @sfackler

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 5, 2020
@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 5, 2020

@bors try

@bors
Copy link
Contributor

bors commented Aug 5, 2020

⌛ Trying commit 39466bc with merge 353a0a223066e9f46a1d935f2271a26c3c5002bb...

@bors
Copy link
Contributor

bors commented Aug 5, 2020

☀️ Try build successful - checks-actions, checks-azure
Build commit: 353a0a223066e9f46a1d935f2271a26c3c5002bb (353a0a223066e9f46a1d935f2271a26c3c5002bb)

@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 5, 2020

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-75180 created and queued.
🤖 Automatically detected try build 353a0a223066e9f46a1d935f2271a26c3c5002bb
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 5, 2020
@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 5, 2020

With this trait impl, the following code would begin to compile:

use std::{fmt, error::Error};

#[derive(Debug)]
pub struct MyError;

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "my error")
    }
}

impl Error for MyError {}

fn is_err<T: Error>() {}

fn main() {
    is_err::<&MyError>();
    is_err::<&dyn Error>();
    is_err::<&(dyn Error + 'static)>();
}

This is an example of code that no longer compiles with this change:

use std::{fmt, error::Error};

#[derive(Debug)]
pub struct MyError;

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "my error")
    }
}

impl Error for MyError {}
impl<'a> Error for &'a MyError {}

It fails with:

error[E0119]: conflicting implementations of trait `std::error::Error` for type `&MyError`:
  --> src\lib.rs:13:1
   |
13 | impl<'a> Error for &'a MyError {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `std`:
           - impl<'a, T> std::error::Error for &'a T
             where T: std::error::Error, T: ?Sized;

Looks like eyre flushes out another source of breakage from auto-deref:

error: lifetime may not live long enough
  --> examples\custom_handler.rs:65:60
   |
65 |         let errors = iter::successors(Some(error), |error| error.source());
   |                                                     ------ ^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
   |                                                     |    |
   |                                                     |    return type of closure is std::option::Option<&'2 dyn std::error::Error>
   |                                                     has type `&'1 &dyn std::error::Error`

which can be fixed by:

- let errors = iter::successors(Some(error), |error| error.source());
+ let errors = iter::successors(Some(error), |error| (*error).source());

cc @yaahc

So far I haven't found breakage in the test suites of anyhow, thiserror, error-chain, or failure.

We could try and come up with some object-safe adapter to implement Error for references to an impl Error, or do we just expect that the only effective way to work with errors generically is going to be through dyn Error rather than impl Error?

@yaahc
Copy link
Member

yaahc commented Aug 5, 2020

@KodrAus what's the goal of this change?

@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 5, 2020

@yaahc Sorry to drop you into a random PR like that!

The goal is to try make impl Error more usable. Right now:

  • &dyn Error
  • &MyError
  • Box<dyn Error>

all don’t implement the Error trait. So if you have a &dyn Error you can’t pass it to a method that wants impl Error.

We have coherence issues with impl Error for Box<dyn Error>, but with this change you could at least still get an impl Error from a Box<dyn Error> by dereferencing it. When I noticed this impl at least doesn’t break anything in rustc I thought I’d try it on the wider ecosystem.

@yaahc
Copy link
Member

yaahc commented Aug 5, 2020

aah yea, I've wanted a way to abstract over types that deref to error like Box<dyn Error> and types that impl error for a while, I've tried finding ways to do it but have so far been unsuccessful. I've been placing my bets on specialization fixing this issue so we can just implement Error for Box<dyn Error> but I'm excited about the prospect of finding other solutions in the short term.

Last time I tried implementing a trait for this I think the problem was that I'd need higher kinded types to express it.

@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 7, 2020

I've been placing my bets on specialization fixing this issue so we can just implement Error for Box

Hmm, so I think impl Error for Box<dyn Error> (ideally via impl<T: Error + ?Sized> Error for Box<T>) causes these impls to conflict:

// in core
impl<T> From<T> for T;

// in std
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a>;

which I think specialization doesn't quite cover so we might need a sprinkling of compiler magic to work around it 🤔 The impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> side of the conflict would be covered by a more general impl on Box<T> though:

// in alloc
impl<T, U: ?Sized> From<T> for Box<U> where T: Unsize<U>;

That still conflicts with impl<T> From<T> for T, but might make a better target for some compiler magic if it wouldn't break inference all through the ecosystem... At any rate that doesn't seem to prevent us from trying to do the impl this PR adds.

On top of this PR, there is also the conservative method-based approach to look at for converting Box<dyn Error> into impl Error:

impl dyn Error {
    pub fn as_error(self: &Box<Self>) -> Compat<&Self>;

    pub fn into_error(self: Box<Self>) -> Compat<Box<Self>>;
}

pub struct Compat<T>(T);

impl<'a, T: ?Sized + Error> Error for Compat<&'a T>;

impl<T: ?Sized + Error> Error for Compat<Box<T>>;

I guess this is all stuff to track in the Error Handling Group once it's bootstrapped? 🙂

@yaahc
Copy link
Member

yaahc commented Aug 7, 2020

Hmm, so I think impl Error for Box<dyn Error> (ideally via impl<T: Error + ?Sized> Error for Box<T>) causes these impls to conflict:

which I think specialization doesn't quite cover

would you mind elaborating on this one? I had thought that the second impl would work if we marked the first one as default.

@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 8, 2020

I had thought that the second impl would work if we marked the first one as default.

I'd thought so too... but it didn't work out when I tried it. I had a browse back through the RFC and I think my understanding of specialization is just wrong. I've been thinking of it a bit like the CSS !important operator that just forces one rule to be more applicable than another by slapping a default into the mix. But I think specialization still relies on one of the impls being specialized over applying to a subset of the types of another. Maybe like some kind of scoped !important.

The limitations section of the RFC talks a bit about this, but it's hard to understand specialization casually so I might still be misunderstanding things.

@yaahc
Copy link
Member

yaahc commented Aug 8, 2020

I had thought that the second impl would work if we marked the first one as default.

I'd thought so too... but it didn't work out when I tried it. I had a browse back through the RFC and I think my understanding of specialization is just wrong. I've been thinking of it a bit like the CSS !important operator that just forces one rule to be more applicable than another by slapping a default into the mix. But I think specialization still relies on one of the impls being specialized over applying to a subset of the types of another. Maybe like some kind of scoped !important.

The limitations section of the RFC talks a bit about this, but it's hard to understand specialization casually so I might still be misunderstanding things.

hmm, im in a similar boat of not being sure how close to reality my understanding of specialization is. I know there's some edge cases about lifetimes wrt specialization, so the <E: Error + 'a> might be responsible for the breakdown? If that's the case then I wonder if specialization + the Unsize based From impl which currently overlaps would end up working out, since it doesn't expose any of the lifetimes in it's interface.

If we cant find a way to impl Error for box<dyn Error> that would not be great, but maybe not the worst thing in the world. If we can add a std::error::Report type that essentially replaces box<dyn Error> we could explicitly not include the 'a bound in the From impl which might let us still impl Error on the type that we'd want people to be using for dyn Errors in the future.

@jyn514 jyn514 added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Aug 9, 2020
@craterbot
Copy link
Collaborator

🚧 Experiment pr-75180 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-75180 is completed!
📊 16 regressed and 7 fixed (116018 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the blacklist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Aug 27, 2020
@KodrAus
Copy link
Contributor Author

KodrAus commented Aug 27, 2020

So the results of the crater run are finally in!

We have a few regressions:

We now need to manually deref &&dyn Error in order to get a source with the right lifetime:

Some crates now have unnecessary implementations of Error for &T: Error:

Some that can no longer use String::as_ref to get an impl Into<Box<dyn Error>>:

I’d like to work through the implications for &&dyn Error a bit more, to see if there’s a nicer way than (*error).source() but I think this change is worth pursuing more to fix one of the papercuts of working with Error.

What do you think @yaahc @rust-lang/libs?

@BurntSushi
Copy link
Member

@KodrAus I think my initial reaction here is that since there is breakage, it might be better if a change like this were considered by the error handling working group. Mostly just so that it's considered in the context of other changes we might like to make.

@yaahc
Copy link
Member

yaahc commented Aug 27, 2020

@BurntSushi still waiting on that last vote to establish the project group :(

rust-lang/rfcs#2965 (comment)

@crlf0710
Copy link
Member

The project group has been established. I'll mark this PR as S-blocked on that project group's decisions.

@crlf0710 crlf0710 removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 18, 2020
@m-ou-se
Copy link
Member

m-ou-se commented Jan 24, 2021

@bors r+

@bors
Copy link
Contributor

bors commented Jan 24, 2021

📌 Commit bbf5001 has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels Jan 24, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 24, 2021
…as-schievink

Rollup of 14 pull requests

Successful merges:

 - rust-lang#75180 (Implement Error for &(impl Error))
 - rust-lang#78578 (Permit mutable references in all const contexts)
 - rust-lang#79174 (Make std::future a re-export of core::future)
 - rust-lang#79884 (Replace magic numbers with existing constants)
 - rust-lang#80855 (Expand assert!(expr, args..) to include $crate for hygiene on 2021.)
 - rust-lang#80933 (Fix sysroot option not being honored across rustc)
 - rust-lang#81259 (Replace version_check dependency with own version parsing code)
 - rust-lang#81264 (Add unstable option to control doctest run directory)
 - rust-lang#81279 (Small refactor in typeck)
 - rust-lang#81297 (Don't provide backend_optimization_level query for extern crates)
 - rust-lang#81302 (Fix rendering of stabilization version for trait implementors)
 - rust-lang#81310 (Do not mark unit variants as used when in path pattern)
 - rust-lang#81320 (Make bad shlex parsing a pretty error)
 - rust-lang#81338 (Clean up `dominators_given_rpo`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 5a1f2ec into rust-lang:master Jan 25, 2021
@rustbot rustbot added this to the 1.51.0 milestone Jan 25, 2021
lopopolo added a commit to artichoke/artichoke that referenced this pull request Jan 26, 2021
See rust-lang/rust#75180.

```
error[E0119]: conflicting implementations of trait `std::error::Error` for type `&(dyn error::RubyException + 'static)`:
   --> artichoke-backend/src/error.rs:128:1
    |
128 | impl error::Error for &dyn RubyException {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `std`:
            - impl<'a, T> std::error::Error for &'a T
              where T: std::error::Error, T: ?Sized;

error[E0119]: conflicting implementations of trait `std::error::Error` for type `&(dyn error::RubyException + 'static)`:
   --> artichoke-backend/src/error.rs:128:1
    |
128 | impl error::Error for &dyn RubyException {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `std`:
            - impl<'a, T> std::error::Error for &'a T
              where T: std::error::Error, T: ?Sized;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
error: could not document `artichoke-backend`
```
@lopopolo
Copy link
Contributor

Hi folks, the Crater docs mention that it discovers and tests Rust codebases on GitHub. Is this still true? This PR broke an unpublished project of mine, see artichoke/artichoke#1069. Should I have expected a ticket or to be listed as a regression in this ticket?

RubyException has std::error::Error as a supertrait which doesn't appear to be mentioned in the breakage categories above.

I turned out to not need this impl for Artichoke to compile, but if I did, i'd be in a tricky spot in CI which must pass on both stable and nightly (for building rustdoc).

error[E0119]: conflicting implementations of trait `std::error::Error` for type `&(dyn error::RubyException + 'static)`:
   --> artichoke-backend/src/error.rs:128:1
    |
128 | impl error::Error for &dyn RubyException {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `std`:
            - impl<'a, T> std::error::Error for &'a T
              where T: std::error::Error, T: ?Sized;

error[E0119]: conflicting implementations of trait `std::error::Error` for type `&(dyn error::RubyException + 'static)`:
   --> artichoke-backend/src/error.rs:128:1
    |
128 | impl error::Error for &dyn RubyException {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `std`:
            - impl<'a, T> std::error::Error for &'a T
              where T: std::error::Error, T: ?Sized;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
error: could not document `artichoke-backend`

@yaahc
Copy link
Member

yaahc commented Jan 26, 2021

Hi folks, the Crater docs mention that it discovers and tests Rust codebases on GitHub. Is this still true? This PR broke an unpublished project of mine, see artichoke/artichoke#1069. Should I have expected a ticket or to be listed as a regression in this ticket?

to my knowledge it does still lookup git repos. I am not super familiar with the crater UI so I might be misinterpreting this but I think what happened is that your crate was failing to compile on with both versions of std, before and after this change. This ends up causing crater to just ignore the error and assume it was unrelated to the change introduced.

Screenshot from 2021-01-26 12-16-49

Here are the errors it ran into:

I don't really know what this means though, it seems like they discard the root cause error. :/

@Dylan-DPC-zz
Copy link

that's not your repo fault but the way crater is configured sometimes it has issues with some of the repositories since crater is sand-boxed and other stuff

@lopopolo
Copy link
Contributor

@yaahc @Dylan-DPC I pulled the rustops/crates-build-env container and Artichoke builds successfully in it, but I did notice that the rustup-installed cargo initiated an install of the toolchain specified in Artichoke's rust-toolchain file. I'm guessing this type of network activity is what the crater sandbox prevents.

Given that crater's intent is to build projects with specific versions of rustc, I think it makes sense to ignore rust-toolchain files in the repository if they are present.

@yaahc
Copy link
Member

yaahc commented Jan 27, 2021

@lopopolo I went ahead and opened an issue on crater so hopefully this gets fixed before too long.

@lopopolo
Copy link
Contributor

@yaahc thank you!

@pietroalbini
Copy link
Member

@yaahc for future reference, the "errors" section means an internal Crater error. If the crate failed to build both before and after the change it will be marked as "build-fail".

wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request Apr 10, 2021
Pkgsrc changes:
 * Remove one SunOS patch, apparently no longer needed.
 * Adapt one patch for Darwin, adjust cargo checksum accordingly.
 * Adjust bootstraps to version 1.50.0.

Version 1.51.0 (2021-03-25)
============================

Language
--------
- [You can now parameterize items such as functions, traits, and
  `struct`s by constant values in addition to by types and
  lifetimes.][79135] Also known as "const generics" E.g. you can
  now write the following. Note:  Only values of primitive integers,
  `bool`, or `char` types are currently permitted.

  ```rust
  struct GenericArray<T, const LENGTH: usize> {
      inner: [T; LENGTH]
  }

  impl<T, const LENGTH: usize> GenericArray<T, LENGTH> {
      const fn last(&self) -> Option<&T> {
          if LENGTH == 0 {
              None
          } else {
              Some(&self.inner[LENGTH - 1])
          }
      }
  }
  ```

Compiler
--------

- [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570]
  This option controls whether debug information is split across
  multiple files or packed into a single file. **Note** This option
  is unstable on other platforms.
- [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`,
  `aarch64-unknown-linux-gnu_ilp32`, and
  `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455]
- [Added tier 3 support for `i386-unknown-linux-gnu` and
  `i486-unknown-linux-gnu` targets.][80662]
- [The `target-cpu=native` option will now detect individual features
  of CPUs.][80749]
- [Rust now uses `inline-asm` for stack probes when used with LLVM
  11.0.1+][77885]

\* Refer to Rust's [platform support page][forge-platform-support]
for more information on Rust's tiered platform support.

Libraries
---------

- [`Box::downcast` is now also implemented for any `dyn Any + Send
  + Sync` object.][80945]
- [`str` now implements `AsMut<str>`.][80279]
- [`u64` and `u128` now implement `From<char>`.][79502]
- [`Error` is now implemented for `&T` where `T` implements `Error`.][75180]
- [`Poll::{map_ok, map_err}` are now implemented for `Poll<Option<Result<T,
  E>>>`.][80968]
- [`unsigned_abs` is now implemented for all signed integer types.][80959]
- [`io::Empty` now implements `io::Seek`.][78044]
- [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr`
  are now implemented for `T: ?Sized` types.][80764]

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

- [`Arc::decrement_strong_count`]
- [`Arc::increment_strong_count`]
- [`Once::call_once_force`]
- [`Peekable::next_if_eq`]
- [`Peekable::next_if`]
- [`Seek::stream_position`]
- [`array::IntoIter`]
- [`panic::panic_any`]
- [`ptr::addr_of!`]
- [`ptr::addr_of_mut!`]
- [`slice::fill_with`]
- [`slice::split_inclusive_mut`]
- [`slice::split_inclusive`]
- [`slice::strip_prefix`]
- [`slice::strip_suffix`]
- [`str::split_inclusive`]
- [`sync::OnceState`]
- [`task::Wake`]

Cargo
-----
- [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo
  codegen option.][cargo/9112]
- [Added the `resolver` field to `Cargo.toml` to enable the new
  feature resolver and CLI option behavior.][cargo/8997] Version
  2 of the feature resolver will try to avoid unifying features of
  dependencies where that unification could be unwanted.  Such as
  using the same dependency with a `std` feature in a build scripts
  and proc-macros, while using the `no-std` feature in the final
  binary. See the [Cargo book documentation][feature-resolver@2.0]
  for more information on the feature.

Rustdoc
-------
- [Rustdoc will now include documentation for methods available
  from `Deref` traits.][80653]
- [You can now provide a `--default-theme` flag which sets the
  default theme to use for documentation.][79642]

Various improvements to intra-doc links:

- [You can link to non-path primitives such as `slice`.][80181]
- [You can link to associated items.][74489]
- [You can now include generic parameters when linking to items,
  like `Vec<T>`.][76934]

Misc
----
- [You can now pass `--include-ignored` to tests (e.g. with
  `cargo test -- --include-ignored`) to include testing tests marked
  `#[ignore]`.][80053]

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

- [WASI platforms no longer use the `wasm-bindgen` ABI, and instead
  use the wasm32 ABI.][79998]
- [`rustc` no longer promotes division, modulo and indexing operations
  to `const` that could fail.][80579]

- [The minimum version of glibc for the following platforms has
  been bumped to version 2.31 for the distributed artifacts.][81521]
    - `armv5te-unknown-linux-gnueabi`
    - `sparc64-unknown-linux-gnu`
    - `thumbv7neon-unknown-linux-gnueabihf`
    - `armv7-unknown-linux-gnueabi`
    - `x86_64-unknown-linux-gnux32`

Internal Only
-------------

- [Consistently avoid constructing optimized MIR when not doing codegen][80718]

[79135]: rust-lang/rust#79135
[74489]: rust-lang/rust#74489
[76934]: rust-lang/rust#76934
[79570]: rust-lang/rust#79570
[80181]: rust-lang/rust#80181
[79642]: rust-lang/rust#79642
[80945]: rust-lang/rust#80945
[80279]: rust-lang/rust#80279
[80053]: rust-lang/rust#80053
[79502]: rust-lang/rust#79502
[75180]: rust-lang/rust#75180
[79135]: rust-lang/rust#79135
[81521]: rust-lang/rust#81521
[80968]: rust-lang/rust#80968
[80959]: rust-lang/rust#80959
[80718]: rust-lang/rust#80718
[80653]: rust-lang/rust#80653
[80579]: rust-lang/rust#80579
[79998]: rust-lang/rust#79998
[78044]: rust-lang/rust#78044
[81455]: rust-lang/rust#81455
[80764]: rust-lang/rust#80764
[80749]: rust-lang/rust#80749
[80662]: rust-lang/rust#80662
[77885]: rust-lang/rust#77885
[cargo/8997]: rust-lang/cargo#8997
[cargo/9112]: rust-lang/cargo#9112
[feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
[`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force
[`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html
[`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html
[`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count
[`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count
[`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with
[`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html
[`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html
[`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html
[`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive
[`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut
[`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive
[`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html
[`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position
[`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if
[`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request May 26, 2021
Pkgsrc changes:
 * Add support for the big-endian arm64 NetBSD target (aarch64_be).
 * On NetBSD/i386, use the i586 (pentium) bootstrap kit variant in
   preference to i686.
 * Adjust patches, re-compute line offsets, re-compute crate checksums.
 * Remove a patch which was either integrated upstream and/or no longer
   applies.
 * Bump bootstraps to 1.50.0.
 * Move conditionals until after bsd.prefs.mk so that they work...
 * Default to "dist" build target if cross-compiling, but allow
   also to override via rust.BUILD_TARGET.
 * Allow overriding MAKE_JOBS_SAFE via rust.MAKE_JOBS_SAFE if you
   want a different trade-off between occasional breakage and performance.
 * Adjust platform.mk according to work already done in wip/rust/
 * Add a patch to optimize the install.sh script used to install binary
   bootstraps to not do so many forks; use case/esac and parameter expansion
   instead of grep, sed and cut.
 * Drop building documentation for the binary bootstrap kits.  This will
   also impact the lang/rust-bin package.  For full documentation, build
   or install lang/rust as a package.

Upstream changes:

Version 1.51.0 (2021-03-25)
============================

Language
--------
- [You can now parameterize items such as functions, traits, and
  `struct`s by constant values in addition to by types and
  lifetimes.][79135] Also known as "const generics" E.g. you can
  now write the following. Note:  Only values of primitive integers,
  `bool`, or `char` types are currently permitted.
  ```rust
  struct GenericArray<T, const LENGTH: usize> {
      inner: [T; LENGTH]
  }

  impl<T, const LENGTH: usize> GenericArray<T, LENGTH> {
      const fn last(&self) -> Option<&T> {
          if LENGTH == 0 {
              None
          } else {
              Some(&self.inner[LENGTH - 1])
          }
      }
  }
  ```

Compiler
--------

- [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570]
  This option controls whether debug information is split across
  multiple files or packed into a single file. **Note** This option
  is unstable on other platforms.
- [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`,
  `aarch64-unknown-linux-gnu_ilp32`, and
  `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455]

- [Added tier 3 support for `i386-unknown-linux-gnu` and
  `i486-unknown-linux-gnu` targets.][80662]

- [The `target-cpu=native` option will now detect individual features
  of CPUs.][80749]

\* Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.

Libraries
---------

- [`Box::downcast` is now also implemented for any `dyn Any + Send
  + Sync` object.][80945]
- [`str` now implements `AsMut<str>`.][80279]
- [`u64` and `u128` now implement `From<char>`.][79502]
- [`Error` is now implemented for `&T` where `T` implements `Error`.][75180]
- [`Poll::{map_ok, map_err}` are now implemented for
  `Poll<Option<Result<T,E>>>`.][80968]
- [`unsigned_abs` is now implemented for all signed integer types.][80959]
- [`io::Empty` now implements `io::Seek`.][78044]
- [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr`
  are now implemented for `T: ?Sized` types.][80764]
- [`Div` and `Rem` by their `NonZero` variant is now implemented
  for all unsigned integers.][79134]

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

- [`Arc::decrement_strong_count`]
- [`Arc::increment_strong_count`]
- [`Once::call_once_force`]
- [`Peekable::next_if_eq`]
- [`Peekable::next_if`]
- [`Seek::stream_position`]
- [`array::IntoIter`]
- [`panic::panic_any`]
- [`ptr::addr_of!`]
- [`ptr::addr_of_mut!`]
- [`slice::fill_with`]
- [`slice::split_inclusive_mut`]
- [`slice::split_inclusive`]
- [`slice::strip_prefix`]
- [`slice::strip_suffix`]
- [`str::split_inclusive`]
- [`sync::OnceState`]
- [`task::Wake`]
- [`VecDeque::range`]
- [`VecDeque::range_mut`]

Cargo
-----
- [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo
  codegen option.][cargo/9112]
- [Added the `resolver` field to `Cargo.toml` to enable the new
  feature resolver and CLI option behavior.][cargo/8997] Version
  2 of the feature resolver will try to avoid unifying features of
  dependencies where that unification could be unwanted.  Such as
  using the same dependency with a `std` feature in a build scripts
  and proc-macros, while using the `no-std` feature in the final
  binary. See the [Cargo book documentation][feature-resolver@2.0]
  for more information on the feature.

Rustdoc
-------

- [Rustdoc will now include documentation for methods available
  from _nested_ `Deref` traits.][80653]
- [You can now provide a `--default-theme` flag which sets the
  default theme to use for documentation.][79642]

Various improvements to intra-doc links:

- [You can link to non-path primitives such as `slice`.][80181]
- [You can link to associated items.][74489]
- [You can now include generic parameters when linking to items,
  like `Vec<T>`.][76934]

Misc
----
- [You can now pass `--include-ignored` to tests (e.g. with
  `cargo test -- --include-ignored`) to include testing tests marked
  `#[ignore]`.][80053]

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

- [WASI platforms no longer use the `wasm-bindgen` ABI, and instead
  use the wasm32 ABI.][79998]
- [`rustc` no longer promotes division, modulo and indexing operations
  to `const` that could fail.][80579]
- [The minimum version of glibc for the following platforms has
  been bumped to version 2.31 for the distributed artifacts.][81521]
    - `armv5te-unknown-linux-gnueabi`
    - `sparc64-unknown-linux-gnu`
    - `thumbv7neon-unknown-linux-gnueabihf`
    - `armv7-unknown-linux-gnueabi`
    - `x86_64-unknown-linux-gnux32`
- [`atomic::spin_loop_hint` has been deprecated.][80966] It's
  recommended to use `hint::spin_loop` instead.

Internal Only
-------------

- [Consistently avoid constructing optimized MIR when not doing codegen][80718]

[79135]: rust-lang/rust#79135
[74489]: rust-lang/rust#74489
[76934]: rust-lang/rust#76934
[79570]: rust-lang/rust#79570
[80181]: rust-lang/rust#80181
[79642]: rust-lang/rust#79642
[80945]: rust-lang/rust#80945
[80279]: rust-lang/rust#80279
[80053]: rust-lang/rust#80053
[79502]: rust-lang/rust#79502
[75180]: rust-lang/rust#75180
[79135]: rust-lang/rust#79135
[81521]: rust-lang/rust#81521
[80968]: rust-lang/rust#80968
[80959]: rust-lang/rust#80959
[80718]: rust-lang/rust#80718
[80653]: rust-lang/rust#80653
[80579]: rust-lang/rust#80579
[79998]: rust-lang/rust#79998
[78044]: rust-lang/rust#78044
[81455]: rust-lang/rust#81455
[80764]: rust-lang/rust#80764
[80749]: rust-lang/rust#80749
[80662]: rust-lang/rust#80662
[79134]: rust-lang/rust#79134
[80966]: rust-lang/rust#80966
[cargo/8997]: rust-lang/cargo#8997
[cargo/9112]: rust-lang/cargo#9112
[feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
[`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force
[`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html
[`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html
[`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count
[`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count
[`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with
[`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html
[`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html
[`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html
[`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive
[`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut
[`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive
[`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html
[`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position
[`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if
[`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq
[`VecDeque::range`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range
[`VecDeque::range_mut`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range_mut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-error-handling Area: Error handling disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. PG-error-handling Project group: Error handling (https://github.com/rust-lang/project-error-handling) S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.