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

Stabilize linker-plugin based LTO (aka cross-language LTO) #58057

Merged
merged 3 commits into from
Feb 13, 2019

Conversation

michaelwoerister
Copy link
Member

This PR stabilizes linker plugin based LTO, also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making rustc emit LLVM bitcode instead of machine code, the same as clang does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various codegen and run-make tests that make sure that it keeps working.

It also works for building big projects like Firefox.

The PR makes the feature available under the -C linker-plugin-lto flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. -C linker-plugin-lto is descriptive of what it does. If someone has a better name, let me know :)

@rust-highfive
Copy link
Collaborator

r? @estebank

(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 Feb 1, 2019
@michaelwoerister michaelwoerister added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 1, 2019
@michaelwoerister
Copy link
Member Author

As discussed in the tracking issue, we'll ask @rust-lang/compiler to sign off on it.
@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Feb 1, 2019

Team member @michaelwoerister has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Feb 1, 2019
@michaelwoerister
Copy link
Member Author

r? @alexcrichton

@alexcrichton
Copy link
Member

Looks reasonable to me! Do you know if the way to use this is written down somewhere? I presume it's almost "just set RUSTFLAGS with this flag" but we may want to mention compatible linkers and such? (also things like LLVM version compatibility, etc)

@bors
Copy link
Contributor

bors commented Feb 2, 2019

☔ The latest upstream changes (presumably #57937) made this pull request unmergeable. Please resolve the merge conflicts.

@Centril Centril added the relnotes Marks issues that should be documented in the release notes of the next release. label Feb 3, 2019
@michaelwoerister
Copy link
Member Author

Do you know if the way to use this is written down somewhere?

Yeah, I ran into a similar problem with path-prefix-remapping a while back. There seems to be no canonical place for documenting niche-features like these. Should I create a page on https://forge.rust-lang.org/? @rust-lang/docs might have a better suggestion.

@mark-i-m
Copy link
Member

mark-i-m commented Feb 5, 2019

The reference?

@michaelwoerister
Copy link
Member Author

The reference looks like it's more about the language, not about the compiler.

@michaelwoerister
Copy link
Member Author

O, I just found this: https://doc.rust-lang.org/rustc/index.html

It looks a bit unmaintained though...

@steveklabnik
Copy link
Member

It looks a bit unmaintained though...

I knocked out the basics, and we'd like to continue to expand it, but just need people to do the work, as always :)

It was created to exactly be the place for this kind of information.

@michaelwoerister
Copy link
Member Author

OK, I'll just add a subsection for the feature. It's complicated enough to warrant its own page, I think.

@Zoxc
Copy link
Contributor

Zoxc commented Feb 9, 2019

@michaelwoerister Is there any mechanism to ensure matching LLVM IR versions are used?

I feel like this option should be -C lto, but that's already used for other things. It also seems to me that this doesn't have to be implemented by a plugin, so that probably shouldn't be a part of the option, unless you're actually passing a plugin path for the linker to use.

@rfcbot
Copy link

rfcbot commented Feb 9, 2019

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Feb 9, 2019
@michaelwoerister
Copy link
Member Author

Is there any mechanism to ensure matching LLVM IR versions are used?

What do you have in mind? Only the linker sees both versions of the LLVM IR, so don't think that rustc can do a check unfortunately.

It also seems to me that this doesn't have to be implemented by a plugin, so that probably shouldn't be a part of the option, unless you're actually passing a plugin path for the linker to use.

I'm open for suggestions regarding a different name for the command line option. I don't like -C linker-lto because that sounds weird if you know what "LTO" stands for. The name xLTO has been used for the feature by some folks but I think it's suitable for a commandline option. -C defer-lto would be kind of OK, but -C linker-plugin-lto has more useful information in it. As even LLD uses -plugin for its CLI here, I think it's fine.

@jamesmunns
Copy link
Member

jamesmunns commented Feb 12, 2019

Are there any plans to integrate this as a cargo flag? Or is this intended to stay as a RUSTFLAG?

This would be great to have on in most cases for embedded, especially if this would inline external assembly files as well.

Edit: specifically as a profile flag that could be set in a Cargo.toml, not a cargo CLI flag

@gnzlbg
Copy link
Contributor

gnzlbg commented Feb 12, 2019

It also works for building big projects like Firefox.

Is Firefox using it to compile its jemalloc-sys fork somewhere ?

@michaelwoerister
Copy link
Member Author

Are there any plans to integrate this as a cargo flag?

Not that I'm aware of. @rust-lang/cargo would have to decide about this.

Is Firefox using it to compile its jemalloc-sys fork somewhere ?

Mabye Ted knows something about this? cc @luser

@alexcrichton
Copy link
Member

@jamesmunns FWIW this unfortunately wouldn't work for external assembly files, linker-based LTO only works for code compiled by the same compiler to the same IR, such as C and Rust compiled both to LLVM IR. External assembly files are compiled directly to object files and skip the LLVM IR step, so they can't be optimized/inlined together.

I think we'll probably want to stabilize this first and then see how it plays out to figure out how to best add it to Cargo

@gnzlbg
Copy link
Contributor

gnzlbg commented Feb 12, 2019

I think we'll probably want to stabilize this first and then see how it plays out to figure out how to best add it to Cargo

It might be best to add it to the cc crate first. A lot of crates use cc in their build.rs to either compile C/C++ directly, or to obtain "Makefile" options that are then passed to autoconf/automake, make, cmake, and friends.

That is, we probably want cc to detect whether the C compiler that will / should be used is the clang binary shipped with Rust, and if that's the case, then detect whether the linker is the appropriate one. If all stars align, then the cc crate should automatically use this. We probably want to be able to enforce it through some configuration option, which could then be enabled also externally e.g. via an environment variable that users and cargo could set.

@alexcrichton
Copy link
Member

r=me when this is green on CI

@cramertj
Copy link
Member

@bors r=alexcrichton

@bors
Copy link
Contributor

bors commented Feb 12, 2019

📌 Commit 3a9d171 has been approved by alexcrichton

@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-review Status: Awaiting review from the assignee but also interested parties. labels Feb 12, 2019
@joshtriplett
Copy link
Member

First of all, this is awesome, and I'd love to see it happen.

Second, while I wouldn't want to block this on it, we need to take this change into account in any future designs for better ways of handling builds of hybrid C/Rust projects.

Centril added a commit to Centril/rust that referenced this pull request Feb 13, 2019
…alexcrichton

Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](rust-lang#49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`
Centril added a commit to Centril/rust that referenced this pull request Feb 13, 2019
…alexcrichton

Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](rust-lang#49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`
bors added a commit that referenced this pull request Feb 13, 2019
Rollup of 13 pull requests

Successful merges:

 - #57693 (Doc rewording)
 - #57815 (Speed up the fast path for assert_eq! and assert_ne!)
 - #58034 (Stabilize the time_checked_add feature)
 - #58057 (Stabilize linker-plugin based LTO (aka cross-language LTO))
 - #58137 (Cleanup: rename node_id_to_type(_opt))
 - #58166 (allow shorthand syntax for deprecation reason)
 - #58196 (Add specific feature gate error for const-unstable features)
 - #58200 (fix str mutating through a ptr derived from &self)
 - #58273 (Rename rustc_errors dependency in rust 2018 crates)
 - #58289 (impl iter() for dyn Error)
 - #58387 (Disallow `auto` trait alias syntax)
 - #58404 (use Ubuntu keyserver for CloudABI ports)
 - #58405 (Remove some dead code from libcore)

Failed merges:

r? @ghost
Centril added a commit to Centril/rust that referenced this pull request Feb 13, 2019
…alexcrichton

Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](rust-lang#49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`
bors added a commit that referenced this pull request Feb 13, 2019
Rollup of 12 pull requests

Successful merges:

 - #57693 (Doc rewording)
 - #57815 (Speed up the fast path for assert_eq! and assert_ne!)
 - #58034 (Stabilize the time_checked_add feature)
 - #58057 (Stabilize linker-plugin based LTO (aka cross-language LTO))
 - #58137 (Cleanup: rename node_id_to_type(_opt))
 - #58166 (allow shorthand syntax for deprecation reason)
 - #58200 (fix str mutating through a ptr derived from &self)
 - #58273 (Rename rustc_errors dependency in rust 2018 crates)
 - #58289 (impl iter() for dyn Error)
 - #58387 (Disallow `auto` trait alias syntax)
 - #58404 (use Ubuntu keyserver for CloudABI ports)
 - #58405 (Remove some dead code from libcore)

Failed merges:

r? @ghost
@bors bors merged commit 3a9d171 into rust-lang:master Feb 13, 2019
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Feb 19, 2019
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Apr 14, 2019
Pkgsrc changes:
 * Bump required rust version to build to 1.33.0.
 * Adapt patches to changed file locations.
 * (I worry about 32-bit ports, now that Atomic64 apparently is First-Class;
   this has been built on NetBSD/amd64 so far)

Upstream changes:

Version 1.34.0 (2019-04-11)
==========================

Language
--------
- [You can now use `#[deprecated = "reason"]`][58166] as a shorthand for
  `#[deprecated(note = "reason")]`. This was previously allowed by mistake
  but had no effect.
- [You can now accept token streams in `#[attr()]`,`#[attr[]]`, and
  `#[attr{}]` procedural macros.][57367]
- [You can now write `extern crate self as foo;`][57407] to import your
  crate's root into the extern prelude.


Compiler
--------
- [You can now target `riscv64imac-unknown-none-elf` and
  `riscv64gc-unknown-none-elf`.][58406]
- [You can now enable linker plugin LTO optimisations with
  `-C linker-plugin-lto`.][58057] This allows rustc to compile your Rust code
  into LLVM bitcode allowing LLVM to perform LTO optimisations across C/C++ FFI
  boundaries.
- [You can now target `powerpc64-unknown-freebsd`.][57809]


Libraries
---------
- [The trait bounds have been removed on some of `HashMap<K, V, S>`'s and
  `HashSet<T, S>`'s basic methods.][58370] Most notably you no longer require
  the `Hash` trait to create an iterator.
- [The `Ord` trait bounds have been removed on some of `BinaryHeap<T>`'s basic
  methods.][58421] Most notably you no longer require the `Ord` trait to create
  an iterator.
- [The methods `overflowing_neg` and `wrapping_neg` are now `const` functions
  for all numeric types.][58044]
- [Indexing a `str` is now generic over all types that
  implement `SliceIndex<str>`.][57604]
- [`str::trim`, `str::trim_matches`, `str::trim_{start, end}`, and
  `str::trim_{start, end}_matches` are now `#[must_use]`][57106] and will
  produce a warning if their returning type is unused.
- [The methods `checked_pow`, `saturating_pow`, `wrapping_pow`, and
  `overflowing_pow` are now available for all numeric types.][57873] These are
  equivalvent to methods such as `wrapping_add` for the `pow` operation.


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

#### std & core
* [`Any::type_id`]
* [`Error::type_id`]
* [`atomic::AtomicI16`]
* [`atomic::AtomicI32`]
* [`atomic::AtomicI64`]
* [`atomic::AtomicI8`]
* [`atomic::AtomicU16`]
* [`atomic::AtomicU32`]
* [`atomic::AtomicU64`]
* [`atomic::AtomicU8`]
* [`convert::Infallible`]
* [`convert::TryFrom`]
* [`convert::TryInto`]
* [`iter::from_fn`]
* [`iter::successors`]
* [`num::NonZeroI128`]
* [`num::NonZeroI16`]
* [`num::NonZeroI32`]
* [`num::NonZeroI64`]
* [`num::NonZeroI8`]
* [`num::NonZeroIsize`]
* [`slice::sort_by_cached_key`]
* [`str::escape_debug`]
* [`str::escape_default`]
* [`str::escape_unicode`]
* [`str::split_ascii_whitespace`]

#### std
* [`Instant::checked_add`]
* [`Instant::checked_sub`]
* [`SystemTime::checked_add`]
* [`SystemTime::checked_sub`]

Cargo
-----
- [You can now use alternative registries to crates.io.][cargo/6654]

Misc
----
- [You can now use the `?` operator in your documentation tests without manually
  adding `fn main() -> Result<(), _> {}`.][56470]

Compatibility Notes
-------------------
- [`Command::before_exec` is now deprecated in favor of the
  unsafe method `Command::pre_exec`.][58059]
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
  can now use `const` functions in `static` variables.

[58370]: rust-lang/rust#58370
[58406]: rust-lang/rust#58406
[58421]: rust-lang/rust#58421
[58166]: rust-lang/rust#58166
[58044]: rust-lang/rust#58044
[58057]: rust-lang/rust#58057
[58059]: rust-lang/rust#58059
[57809]: rust-lang/rust#57809
[57873]: rust-lang/rust#57873
[57604]: rust-lang/rust#57604
[57367]: rust-lang/rust#57367
[57407]: rust-lang/rust#57407
[57425]: rust-lang/rust#57425
[57106]: rust-lang/rust#57106
[56470]: rust-lang/rust#56470
[cargo/6654]: rust-lang/cargo#6654
[`Any::type_id`]: https://doc.rust-lang.org/std/any/trait.Any.html#tymethod.type_id
[`Error::type_id`]: https://doc.rust-lang.org/std/error/trait.Error.html#tymethod.type_id
[`atomic::AtomicI16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI16.html
[`atomic::AtomicI32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI32.html
[`atomic::AtomicI64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI64.html
[`atomic::AtomicI8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI8.html
[`atomic::AtomicU16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU16.html
[`atomic::AtomicU32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU32.html
[`atomic::AtomicU64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU64.html
[`atomic::AtomicU8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU8.html
[`convert::Infallible`]: https://doc.rust-lang.org/std/convert/enum.Infallible.html
[`convert::TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
[`convert::TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html
[`iter::from_fn`]: https://doc.rust-lang.org/std/iter/fn.from_fn.html
[`iter::successors`]: https://doc.rust-lang.org/std/iter/fn.successors.html
[`num::NonZeroI128`]: https://doc.rust-lang.org/std/num/struct.NonZeroI128.html
[`num::NonZeroI16`]: https://doc.rust-lang.org/std/num/struct.NonZeroI16.html
[`num::NonZeroI32`]: https://doc.rust-lang.org/std/num/struct.NonZeroI32.html
[`num::NonZeroI64`]: https://doc.rust-lang.org/std/num/struct.NonZeroI64.html
[`num::NonZeroI8`]: https://doc.rust-lang.org/std/num/struct.NonZeroI8.html
[`num::NonZeroIsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroIsize.html
[`slice::sort_by_cached_key`]: https://doc.rust-lang.org/std/slice/fn.sort_by_cached_key
[`str::escape_debug`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_debug
[`str::escape_default`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_default
[`str::escape_unicode`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_unicode
[`str::split_ascii_whitespace`]: https://doc.rust-lang.org/std/primitive.str.html#method.split_ascii_whitespace
[`Instant::checked_add`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_add
[`Instant::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_sub
[`SystemTime::checked_add`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_add
[`SystemTime::checked_sub`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_sub
@Centril Centril added this to the 1.34 milestone Apr 26, 2019
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request May 19, 2019
Pkgsrc changes:
 * Bump required rust version to build to 1.33.0.
 * Adapt patches to changed file locations.
 * (I worry about 32-bit ports, now that Atomic64 apparently is First-Class;
   this has been built on NetBSD/amd64 so far)

Upstream changes:

Version 1.34.0 (2019-04-11)
==========================

Language
--------
- [You can now use `#[deprecated = "reason"]`][58166] as a shorthand for
  `#[deprecated(note = "reason")]`. This was previously allowed by mistake
  but had no effect.
- [You can now accept token streams in `#[attr()]`,`#[attr[]]`, and
  `#[attr{}]` procedural macros.][57367]
- [You can now write `extern crate self as foo;`][57407] to import your
  crate's root into the extern prelude.


Compiler
--------
- [You can now target `riscv64imac-unknown-none-elf` and
  `riscv64gc-unknown-none-elf`.][58406]
- [You can now enable linker plugin LTO optimisations with
  `-C linker-plugin-lto`.][58057] This allows rustc to compile your Rust code
  into LLVM bitcode allowing LLVM to perform LTO optimisations across C/C++ FFI
  boundaries.
- [You can now target `powerpc64-unknown-freebsd`.][57809]


Libraries
---------
- [The trait bounds have been removed on some of `HashMap<K, V, S>`'s and
  `HashSet<T, S>`'s basic methods.][58370] Most notably you no longer require
  the `Hash` trait to create an iterator.
- [The `Ord` trait bounds have been removed on some of `BinaryHeap<T>`'s basic
  methods.][58421] Most notably you no longer require the `Ord` trait to create
  an iterator.
- [The methods `overflowing_neg` and `wrapping_neg` are now `const` functions
  for all numeric types.][58044]
- [Indexing a `str` is now generic over all types that
  implement `SliceIndex<str>`.][57604]
- [`str::trim`, `str::trim_matches`, `str::trim_{start, end}`, and
  `str::trim_{start, end}_matches` are now `#[must_use]`][57106] and will
  produce a warning if their returning type is unused.
- [The methods `checked_pow`, `saturating_pow`, `wrapping_pow`, and
  `overflowing_pow` are now available for all numeric types.][57873] These are
  equivalvent to methods such as `wrapping_add` for the `pow` operation.


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

#### std & core
* [`Any::type_id`]
* [`Error::type_id`]
* [`atomic::AtomicI16`]
* [`atomic::AtomicI32`]
* [`atomic::AtomicI64`]
* [`atomic::AtomicI8`]
* [`atomic::AtomicU16`]
* [`atomic::AtomicU32`]
* [`atomic::AtomicU64`]
* [`atomic::AtomicU8`]
* [`convert::Infallible`]
* [`convert::TryFrom`]
* [`convert::TryInto`]
* [`iter::from_fn`]
* [`iter::successors`]
* [`num::NonZeroI128`]
* [`num::NonZeroI16`]
* [`num::NonZeroI32`]
* [`num::NonZeroI64`]
* [`num::NonZeroI8`]
* [`num::NonZeroIsize`]
* [`slice::sort_by_cached_key`]
* [`str::escape_debug`]
* [`str::escape_default`]
* [`str::escape_unicode`]
* [`str::split_ascii_whitespace`]

#### std
* [`Instant::checked_add`]
* [`Instant::checked_sub`]
* [`SystemTime::checked_add`]
* [`SystemTime::checked_sub`]

Cargo
-----
- [You can now use alternative registries to crates.io.][cargo/6654]

Misc
----
- [You can now use the `?` operator in your documentation tests without manually
  adding `fn main() -> Result<(), _> {}`.][56470]

Compatibility Notes
-------------------
- [`Command::before_exec` is now deprecated in favor of the
  unsafe method `Command::pre_exec`.][58059]
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
  can now use `const` functions in `static` variables.

[58370]: rust-lang/rust#58370
[58406]: rust-lang/rust#58406
[58421]: rust-lang/rust#58421
[58166]: rust-lang/rust#58166
[58044]: rust-lang/rust#58044
[58057]: rust-lang/rust#58057
[58059]: rust-lang/rust#58059
[57809]: rust-lang/rust#57809
[57873]: rust-lang/rust#57873
[57604]: rust-lang/rust#57604
[57367]: rust-lang/rust#57367
[57407]: rust-lang/rust#57407
[57425]: rust-lang/rust#57425
[57106]: rust-lang/rust#57106
[56470]: rust-lang/rust#56470
[cargo/6654]: rust-lang/cargo#6654
[`Any::type_id`]: https://doc.rust-lang.org/std/any/trait.Any.html#tymethod.type_id
[`Error::type_id`]: https://doc.rust-lang.org/std/error/trait.Error.html#tymethod.type_id
[`atomic::AtomicI16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI16.html
[`atomic::AtomicI32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI32.html
[`atomic::AtomicI64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI64.html
[`atomic::AtomicI8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI8.html
[`atomic::AtomicU16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU16.html
[`atomic::AtomicU32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU32.html
[`atomic::AtomicU64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU64.html
[`atomic::AtomicU8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU8.html
[`convert::Infallible`]: https://doc.rust-lang.org/std/convert/enum.Infallible.html
[`convert::TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
[`convert::TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html
[`iter::from_fn`]: https://doc.rust-lang.org/std/iter/fn.from_fn.html
[`iter::successors`]: https://doc.rust-lang.org/std/iter/fn.successors.html
[`num::NonZeroI128`]: https://doc.rust-lang.org/std/num/struct.NonZeroI128.html
[`num::NonZeroI16`]: https://doc.rust-lang.org/std/num/struct.NonZeroI16.html
[`num::NonZeroI32`]: https://doc.rust-lang.org/std/num/struct.NonZeroI32.html
[`num::NonZeroI64`]: https://doc.rust-lang.org/std/num/struct.NonZeroI64.html
[`num::NonZeroI8`]: https://doc.rust-lang.org/std/num/struct.NonZeroI8.html
[`num::NonZeroIsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroIsize.html
[`slice::sort_by_cached_key`]: https://doc.rust-lang.org/std/slice/fn.sort_by_cached_key
[`str::escape_debug`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_debug
[`str::escape_default`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_default
[`str::escape_unicode`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_unicode
[`str::split_ascii_whitespace`]: https://doc.rust-lang.org/std/primitive.str.html#method.split_ascii_whitespace
[`Instant::checked_add`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_add
[`Instant::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_sub
[`SystemTime::checked_add`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_add
[`SystemTime::checked_sub`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_sub
@glandium
Copy link
Contributor

glandium commented Jul 3, 2019

I would like to bring to your attention that stabilizing this requires the LLVM version used in Rust to be a non-arbitrary version of LLVM trunk. It does happen that LLVM IR breaks compatibility on trunk (and it ends up being fixed at some point), and IIRC, it has happened that Rust picked a version of LLVM that happened to be broken.

@gnzlbg
Copy link
Contributor

gnzlbg commented Jul 3, 2019

I would like to bring to your attention that stabilizing this requires the LLVM version used in Rust to be a non-arbitrary version of LLVM trunk.

Why? This option is disabled by default. If a user enables it, and the LLVM used is incompatible, we could:

  • error
  • emit a warning and disable the option (compilation proceeds)
  • disable the option without error or warning (compilation proceeds silently).

AFAICT, this option enables and optimization and that can be "best-effort". We should document the behavior, and that's it.

If the current behavior is neither of these (e.g. unsound, an LLVM error is emitted, etc.), you can open an issue about this. That's bad and should be fixed.

@nikic
Copy link
Contributor

nikic commented Jul 3, 2019

@glandium While this is true in general, rust is currently using (and has been since its release) the LLVM 8 branch, not trunk. If you're seeing issues, they cannot be related to trunk changes.

@gnzlbg
Copy link
Contributor

gnzlbg commented Jul 3, 2019

@nikic users might be using the system LLVM (up to 6.0), depending on their platform (linux distribution, etc.). This case needs to be handled somehow.

@nikic
Copy link
Contributor

nikic commented Jul 3, 2019

@gnzlbg That's true. Using the system rust (which will likely be linked against system LLVM) should work though. We also have #56371 which suggests to ship a compatible clang in rustup.

@ghost
Copy link

ghost commented Aug 16, 2023

@michaelwoerister -flto=full never works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet