Auto merge of #84864 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum
[stable] 1.52.0 release This includes the release notes (#84183) as well as cherry-picked commits from: * [beta] revert PR #77885 #84710 * [beta] remove assert_matches #84759 * Revert PR 81473 to resolve (on beta) issues 81626 and 81658. #83171 * [beta] rustdoc revert deref recur #84868 * Fix ICE of for-loop mut borrowck where no suggestions are available #83401 Additionally in "fresh work" we're also: * reverting: directly expose copy and copy_nonoverlapping intrinsics #81238 to avoid https://github.com/rust-lang/rust/issues/84297 on 1.52
This commit is contained in:
commit
88f19c6dab
354
RELEASES.md
354
RELEASES.md
|
@ -1,3 +1,329 @@
|
||||||
|
Version 1.52.0 (2021-05-06)
|
||||||
|
============================
|
||||||
|
|
||||||
|
Language
|
||||||
|
--------
|
||||||
|
- [Added the `unsafe_op_in_unsafe_fn` lint, which checks whether the unsafe code
|
||||||
|
in an `unsafe fn` is wrapped in a `unsafe` block.][79208] This lint
|
||||||
|
is allowed by default, and may become a warning or hard error in a
|
||||||
|
future edition.
|
||||||
|
- [You can now cast mutable references to arrays to a pointer of the same type as
|
||||||
|
the element.][81479]
|
||||||
|
|
||||||
|
Compiler
|
||||||
|
--------
|
||||||
|
- [Upgraded the default LLVM to LLVM 12.][81451]
|
||||||
|
|
||||||
|
Added tier 3\* support for the following targets.
|
||||||
|
|
||||||
|
- [`s390x-unknown-linux-musl`][82166]
|
||||||
|
- [`riscv32gc-unknown-linux-musl` & `riscv64gc-unknown-linux-musl`][82202]
|
||||||
|
- [`powerpc-unknown-openbsd`][82733]
|
||||||
|
|
||||||
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
|
Libraries
|
||||||
|
---------
|
||||||
|
- [`OsString` now implements `Extend` and `FromIterator`.][82121]
|
||||||
|
- [`cmp::Reverse` now has `#[repr(transparent)]` representation.][81879]
|
||||||
|
- [`Arc<impl Error>` now implements `error::Error`.][80553]
|
||||||
|
- [All integer division and remainder operations are now `const`.][80962]
|
||||||
|
|
||||||
|
Stabilised APIs
|
||||||
|
-------------
|
||||||
|
- [`Arguments::as_str`]
|
||||||
|
- [`char::MAX`]
|
||||||
|
- [`char::REPLACEMENT_CHARACTER`]
|
||||||
|
- [`char::UNICODE_VERSION`]
|
||||||
|
- [`char::decode_utf16`]
|
||||||
|
- [`char::from_digit`]
|
||||||
|
- [`char::from_u32_unchecked`]
|
||||||
|
- [`char::from_u32`]
|
||||||
|
- [`slice::partition_point`]
|
||||||
|
- [`str::rsplit_once`]
|
||||||
|
- [`str::split_once`]
|
||||||
|
|
||||||
|
The following previously stable APIs are now `const`.
|
||||||
|
|
||||||
|
- [`char::len_utf8`]
|
||||||
|
- [`char::len_utf16`]
|
||||||
|
- [`char::to_ascii_uppercase`]
|
||||||
|
- [`char::to_ascii_lowercase`]
|
||||||
|
- [`char::eq_ignore_ascii_case`]
|
||||||
|
- [`u8::to_ascii_uppercase`]
|
||||||
|
- [`u8::to_ascii_lowercase`]
|
||||||
|
- [`u8::eq_ignore_ascii_case`]
|
||||||
|
|
||||||
|
Rustdoc
|
||||||
|
-------
|
||||||
|
- [Rustdoc lints are now treated as a tool lint, meaning that
|
||||||
|
lints are now prefixed with `rustdoc::` (e.g. `#[warn(rustdoc::non_autolinks)]`).][80527]
|
||||||
|
Using the old style is still allowed, and will become a warning in
|
||||||
|
a future release.
|
||||||
|
- [Rustdoc now supports argument files.][82261]
|
||||||
|
- [Rustdoc now generates smart punctuation for documentation.][79423]
|
||||||
|
- [You can now use "task lists" in Rustdoc Markdown.][81766] E.g.
|
||||||
|
```markdown
|
||||||
|
- [x] Complete
|
||||||
|
- [ ] Todo
|
||||||
|
```
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
- [You can now pass multiple filters to tests.][81356] E.g.
|
||||||
|
`cargo test -- foo bar` will run all tests that match `foo` and `bar`.
|
||||||
|
- [Rustup now distributes PDB symbols for the `std` library on Windows,
|
||||||
|
allowing you to see `std` symbols when debugging.][82218]
|
||||||
|
|
||||||
|
Internal Only
|
||||||
|
-------------
|
||||||
|
These changes provide no direct user facing benefits, but represent significant
|
||||||
|
improvements to the internals and overall performance of rustc and
|
||||||
|
related tools.
|
||||||
|
|
||||||
|
- [Check the result cache before the DepGraph when ensuring queries][81855]
|
||||||
|
- [Try fast_reject::simplify_type in coherence before doing full check][81744]
|
||||||
|
- [Only store a LocalDefId in some HIR nodes][81611]
|
||||||
|
- [Store HIR attributes in a side table][79519]
|
||||||
|
|
||||||
|
Compatibility Notes
|
||||||
|
-------------------
|
||||||
|
- [Cargo build scripts are now forbidden from setting `RUSTC_BOOTSTRAP`.][cargo/9181]
|
||||||
|
- [Removed support for the `x86_64-rumprun-netbsd` target.][82594]
|
||||||
|
- [Deprecated the `x86_64-sun-solaris` target in favor of `x86_64-pc-solaris`.][82216]
|
||||||
|
- [Rustdoc now only accepts `,`, ` `, and `\t` as delimiters for specifying
|
||||||
|
languages in code blocks.][78429]
|
||||||
|
- [Rustc now catches more cases of `pub_use_of_private_extern_crate`][80763]
|
||||||
|
- [Changes in how proc macros handle whitespace may lead to panics when used
|
||||||
|
with older `proc-macro-hack` versions. A `cargo update` should be sufficient to fix this in all cases.][84136]
|
||||||
|
|
||||||
|
[84136]: https://github.com/rust-lang/rust/issues/84136
|
||||||
|
[80763]: https://github.com/rust-lang/rust/pull/80763
|
||||||
|
[82166]: https://github.com/rust-lang/rust/pull/82166
|
||||||
|
[82121]: https://github.com/rust-lang/rust/pull/82121
|
||||||
|
[81879]: https://github.com/rust-lang/rust/pull/81879
|
||||||
|
[82261]: https://github.com/rust-lang/rust/pull/82261
|
||||||
|
[82218]: https://github.com/rust-lang/rust/pull/82218
|
||||||
|
[82216]: https://github.com/rust-lang/rust/pull/82216
|
||||||
|
[82202]: https://github.com/rust-lang/rust/pull/82202
|
||||||
|
[81855]: https://github.com/rust-lang/rust/pull/81855
|
||||||
|
[81766]: https://github.com/rust-lang/rust/pull/81766
|
||||||
|
[81744]: https://github.com/rust-lang/rust/pull/81744
|
||||||
|
[81611]: https://github.com/rust-lang/rust/pull/81611
|
||||||
|
[81479]: https://github.com/rust-lang/rust/pull/81479
|
||||||
|
[81451]: https://github.com/rust-lang/rust/pull/81451
|
||||||
|
[81356]: https://github.com/rust-lang/rust/pull/81356
|
||||||
|
[80962]: https://github.com/rust-lang/rust/pull/80962
|
||||||
|
[80553]: https://github.com/rust-lang/rust/pull/80553
|
||||||
|
[80527]: https://github.com/rust-lang/rust/pull/80527
|
||||||
|
[79519]: https://github.com/rust-lang/rust/pull/79519
|
||||||
|
[79423]: https://github.com/rust-lang/rust/pull/79423
|
||||||
|
[79208]: https://github.com/rust-lang/rust/pull/79208
|
||||||
|
[78429]: https://github.com/rust-lang/rust/pull/78429
|
||||||
|
[82733]: https://github.com/rust-lang/rust/pull/82733
|
||||||
|
[82594]: https://github.com/rust-lang/rust/pull/82594
|
||||||
|
[cargo/9181]: https://github.com/rust-lang/cargo/pull/9181
|
||||||
|
[`char::MAX`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX
|
||||||
|
[`char::REPLACEMENT_CHARACTER`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.REPLACEMENT_CHARACTER
|
||||||
|
[`char::UNICODE_VERSION`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.UNICODE_VERSION
|
||||||
|
[`char::decode_utf16`]: https://doc.rust-lang.org/std/primitive.char.html#method.decode_utf16
|
||||||
|
[`char::from_u32`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32
|
||||||
|
[`char::from_u32_unchecked`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32_unchecked
|
||||||
|
[`char::from_digit`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_digit
|
||||||
|
[`Peekable::next_if`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if
|
||||||
|
[`Peekable::next_if_eq`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_eq
|
||||||
|
[`Arguments::as_str`]: https://doc.rust-lang.org/stable/std/fmt/struct.Arguments.html#method.as_str
|
||||||
|
[`str::split_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_once
|
||||||
|
[`str::rsplit_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit_once
|
||||||
|
[`slice::partition_point`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.partition_point
|
||||||
|
[`char::len_utf8`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf8
|
||||||
|
[`char::len_utf16`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf16
|
||||||
|
[`char::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_uppercase
|
||||||
|
[`char::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_lowercase
|
||||||
|
[`char::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.eq_ignore_ascii_case
|
||||||
|
[`u8::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_uppercase
|
||||||
|
[`u8::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_lowercase
|
||||||
|
[`u8::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.eq_ignore_ascii_case
|
||||||
|
|
||||||
|
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]: https://github.com/rust-lang/rust/pull/79135
|
||||||
|
[74489]: https://github.com/rust-lang/rust/pull/74489
|
||||||
|
[76934]: https://github.com/rust-lang/rust/pull/76934
|
||||||
|
[79570]: https://github.com/rust-lang/rust/pull/79570
|
||||||
|
[80181]: https://github.com/rust-lang/rust/pull/80181
|
||||||
|
[79642]: https://github.com/rust-lang/rust/pull/79642
|
||||||
|
[80945]: https://github.com/rust-lang/rust/pull/80945
|
||||||
|
[80279]: https://github.com/rust-lang/rust/pull/80279
|
||||||
|
[80053]: https://github.com/rust-lang/rust/pull/80053
|
||||||
|
[79502]: https://github.com/rust-lang/rust/pull/79502
|
||||||
|
[75180]: https://github.com/rust-lang/rust/pull/75180
|
||||||
|
[79135]: https://github.com/rust-lang/rust/pull/79135
|
||||||
|
[81521]: https://github.com/rust-lang/rust/pull/81521
|
||||||
|
[80968]: https://github.com/rust-lang/rust/pull/80968
|
||||||
|
[80959]: https://github.com/rust-lang/rust/pull/80959
|
||||||
|
[80718]: https://github.com/rust-lang/rust/pull/80718
|
||||||
|
[80653]: https://github.com/rust-lang/rust/pull/80653
|
||||||
|
[80579]: https://github.com/rust-lang/rust/pull/80579
|
||||||
|
[79998]: https://github.com/rust-lang/rust/pull/79998
|
||||||
|
[78044]: https://github.com/rust-lang/rust/pull/78044
|
||||||
|
[81455]: https://github.com/rust-lang/rust/pull/81455
|
||||||
|
[80764]: https://github.com/rust-lang/rust/pull/80764
|
||||||
|
[80749]: https://github.com/rust-lang/rust/pull/80749
|
||||||
|
[80662]: https://github.com/rust-lang/rust/pull/80662
|
||||||
|
[79134]: https://github.com/rust-lang/rust/pull/79134
|
||||||
|
[80966]: https://github.com/rust-lang/rust/pull/80966
|
||||||
|
[cargo/8997]: https://github.com/rust-lang/cargo/pull/8997
|
||||||
|
[cargo/9112]: https://github.com/rust-lang/cargo/pull/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
|
||||||
|
|
||||||
Version 1.50.0 (2021-02-11)
|
Version 1.50.0 (2021-02-11)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
@ -14,7 +340,7 @@ Compiler
|
||||||
- [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484]
|
- [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484]
|
||||||
- [Dropped support for all cloudabi targets.][78439]
|
- [Dropped support for all cloudabi targets.][78439]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -191,7 +517,7 @@ Compiler
|
||||||
- [Output from threads spawned in tests is now captured.][78227]
|
- [Output from threads spawned in tests is now captured.][78227]
|
||||||
- [Change os and vendor values to "none" and "unknown" for some targets][78951]
|
- [Change os and vendor values to "none" and "unknown" for some targets][78951]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -296,7 +622,7 @@ Compiler
|
||||||
Note: If you're using cargo you must explicitly pass the `--target` flag.
|
Note: If you're using cargo you must explicitly pass the `--target` flag.
|
||||||
- [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420]
|
- [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -435,7 +761,7 @@ Compiler
|
||||||
- [Upgrade the FreeBSD toolchain to version 11.4][75204]
|
- [Upgrade the FreeBSD toolchain to version 11.4][75204]
|
||||||
- [`RUST_BACKTRACE`'s output is now more compact.][75048]
|
- [`RUST_BACKTRACE`'s output is now more compact.][75048]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -720,7 +1046,7 @@ Compiler
|
||||||
- [Added tier 3 support for the `thumbv7a-uwp-windows-msvc` target.][72133]
|
- [Added tier 3 support for the `thumbv7a-uwp-windows-msvc` target.][72133]
|
||||||
- [Upgraded to LLVM 10.][67759]
|
- [Upgraded to LLVM 10.][67759]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
|
|
||||||
|
@ -1229,7 +1555,7 @@ Compiler
|
||||||
pointing to the location where they were called, rather than
|
pointing to the location where they were called, rather than
|
||||||
`core`'s internals. ][67887]
|
`core`'s internals. ][67887]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -1327,7 +1653,7 @@ Compiler
|
||||||
- [You can now provide `--extern` flag without a path, indicating that it is
|
- [You can now provide `--extern` flag without a path, indicating that it is
|
||||||
available from the search path or specified with an `-L` flag.][64882]
|
available from the search path or specified with an `-L` flag.][64882]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
[argfile-docs]: https://doc.rust-lang.org/nightly/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path
|
[argfile-docs]: https://doc.rust-lang.org/nightly/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path
|
||||||
|
@ -1451,7 +1777,7 @@ Compiler
|
||||||
- [Added tier 3 support for the `mips64-unknown-linux-muslabi64`, and
|
- [Added tier 3 support for the `mips64-unknown-linux-muslabi64`, and
|
||||||
`mips64el-unknown-linux-muslabi64` targets.][65843]
|
`mips64el-unknown-linux-muslabi64` targets.][65843]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -1601,7 +1927,7 @@ Compiler
|
||||||
output of successful tests.][62600]
|
output of successful tests.][62600]
|
||||||
|
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -1695,7 +2021,7 @@ Compiler
|
||||||
- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784]
|
- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784]
|
||||||
- [Upgraded to LLVM 9.][62592]
|
- [Upgraded to LLVM 9.][62592]
|
||||||
|
|
||||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||||
information on Rust's tiered platform support.
|
information on Rust's tiered platform support.
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
|
@ -1737,6 +2063,11 @@ Cargo
|
||||||
- [You can now pass the `--features` option multiple times to enable
|
- [You can now pass the `--features` option multiple times to enable
|
||||||
multiple features.][cargo/7084]
|
multiple features.][cargo/7084]
|
||||||
|
|
||||||
|
Rustdoc
|
||||||
|
-------
|
||||||
|
|
||||||
|
- [Documentation on `pub use` statements is prepended to the documentation of the re-exported item][63048]
|
||||||
|
|
||||||
Misc
|
Misc
|
||||||
----
|
----
|
||||||
- [`rustc` will now warn about some incorrect uses of
|
- [`rustc` will now warn about some incorrect uses of
|
||||||
|
@ -1771,6 +2102,7 @@ Compatibility Notes
|
||||||
[63421]: https://github.com/rust-lang/rust/pull/63421/
|
[63421]: https://github.com/rust-lang/rust/pull/63421/
|
||||||
[cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/
|
[cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/
|
||||||
[cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/
|
[cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/
|
||||||
|
[63048]: https://github.com/rust-lang/rust/pull/63048
|
||||||
[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
|
[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
|
||||||
[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
|
[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
|
||||||
[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32
|
[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32
|
||||||
|
@ -1782,7 +2114,7 @@ Compatibility Notes
|
||||||
[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32
|
[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32
|
||||||
[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64
|
[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64
|
||||||
[`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html
|
[`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html
|
||||||
[forge-platform-support]: https://forge.rust-lang.org/release/platform-support.html
|
[platform-support-doc]: https://doc.rust-lang.org/nightly/rustc/platform-support.html
|
||||||
[pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199
|
[pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199
|
||||||
|
|
||||||
Version 1.37.0 (2019-08-15)
|
Version 1.37.0 (2019-08-15)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(assert_matches)]
|
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
|
|
|
@ -45,11 +45,7 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
|
||||||
item.hash_stable(self, hasher);
|
item.hash_stable(self, hasher);
|
||||||
style.hash_stable(self, hasher);
|
style.hash_stable(self, hasher);
|
||||||
span.hash_stable(self, hasher);
|
span.hash_stable(self, hasher);
|
||||||
assert_matches!(
|
assert!(tokens.as_ref().is_none(), "Tokens should have been removed during lowering!");
|
||||||
tokens.as_ref(),
|
|
||||||
None,
|
|
||||||
"Tokens should have been removed during lowering!"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
#![feature(assert_matches)]
|
|
||||||
#![feature(backtrace)]
|
#![feature(backtrace)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
|
|
|
@ -339,7 +339,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
|
||||||
for dest in bytes {
|
for dest in bytes {
|
||||||
*dest = src.next().expect("iterator was shorter than it said it would be");
|
*dest = src.next().expect("iterator was shorter than it said it would be");
|
||||||
}
|
}
|
||||||
assert_matches!(src.next(), None, "iterator was longer than it said it would be");
|
assert!(src.next().is_none(), "iterator was longer than it said it would be");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -642,9 +642,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
.starts_with(&original_method_ident.name.to_string())
|
.starts_with(&original_method_ident.name.to_string())
|
||||||
})
|
})
|
||||||
.map(|ident| format!("{}()", ident))
|
.map(|ident| format!("{}()", ident))
|
||||||
|
.peekable()
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(suggestions) = opt_suggestions {
|
if let Some(mut suggestions) = opt_suggestions {
|
||||||
|
if suggestions.peek().is_some() {
|
||||||
err.span_suggestions(
|
err.span_suggestions(
|
||||||
path_segment.ident.span,
|
path_segment.ident.span,
|
||||||
&format!("use mutable method"),
|
&format!("use mutable method"),
|
||||||
|
@ -653,6 +655,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -854,11 +854,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
Some(ptr) => ptr,
|
Some(ptr) => ptr,
|
||||||
None => {
|
None => {
|
||||||
// zero-sized access
|
// zero-sized access
|
||||||
assert_matches!(
|
assert!(src.next().is_none(), "iterator said it was empty but returned an element");
|
||||||
src.next(),
|
|
||||||
None,
|
|
||||||
"iterator said it was empty but returned an element"
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -884,11 +880,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
Some(ptr) => ptr,
|
Some(ptr) => ptr,
|
||||||
None => {
|
None => {
|
||||||
// zero-sized access
|
// zero-sized access
|
||||||
assert_matches!(
|
assert!(src.next().is_none(), "iterator said it was empty but returned an element");
|
||||||
src.next(),
|
|
||||||
None,
|
|
||||||
"iterator said it was empty but returned an element"
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -902,7 +894,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
|
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
|
||||||
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
|
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
|
||||||
}
|
}
|
||||||
assert_matches!(src.next(), None, "iterator was longer than it said it would be");
|
assert!(src.next().is_none(), "iterator was longer than it said it would be");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ Rust MIR: a lowered representation of Rust.
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
#![feature(assert_matches)]
|
|
||||||
#![feature(bindings_after_at)]
|
#![feature(bindings_after_at)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
|
|
|
@ -133,22 +133,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_assign(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
|
||||||
if self
|
|
||||||
.typeck_results()
|
|
||||||
.expr_adjustments(expr)
|
|
||||||
.iter()
|
|
||||||
.any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_)))
|
|
||||||
{
|
|
||||||
self.visit_expr(expr);
|
|
||||||
} else if let hir::ExprKind::Field(base, ..) = expr.kind {
|
|
||||||
// Ignore write to field
|
|
||||||
self.handle_assign(base);
|
|
||||||
} else {
|
|
||||||
self.visit_expr(expr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_field_pattern_match(
|
fn handle_field_pattern_match(
|
||||||
&mut self,
|
&mut self,
|
||||||
lhs: &hir::Pat<'_>,
|
lhs: &hir::Pat<'_>,
|
||||||
|
@ -277,11 +261,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
||||||
hir::ExprKind::MethodCall(..) => {
|
hir::ExprKind::MethodCall(..) => {
|
||||||
self.lookup_and_handle_method(expr.hir_id);
|
self.lookup_and_handle_method(expr.hir_id);
|
||||||
}
|
}
|
||||||
hir::ExprKind::Assign(ref left, ref right, ..) => {
|
|
||||||
self.handle_assign(left);
|
|
||||||
self.visit_expr(right);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hir::ExprKind::Field(ref lhs, ..) => {
|
hir::ExprKind::Field(ref lhs, ..) => {
|
||||||
self.handle_field_access(&lhs, expr.hir_id);
|
self.handle_field_access(&lhs, expr.hir_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ pub fn target() -> Target {
|
||||||
arch: "x86".to_string(),
|
arch: "x86".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) },
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
stack_probes: StackProbeType::Call,
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,8 @@ pub fn target() -> Target {
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
|
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
|
||||||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
base.eliminate_frame_pointer = false;
|
base.eliminate_frame_pointer = false;
|
||||||
|
|
||||||
// Clang automatically chooses a more specific target based on
|
// Clang automatically chooses a more specific target based on
|
||||||
|
|
|
@ -11,7 +11,8 @@ pub fn target() -> Target {
|
||||||
// http://developer.android.com/ndk/guides/abis.html#x86
|
// http://developer.android.com/ndk/guides/abis.html#x86
|
||||||
base.cpu = "pentiumpro".to_string();
|
base.cpu = "pentiumpro".to_string();
|
||||||
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".to_string();
|
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".to_string();
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-linux-android".to_string(),
|
llvm_target: "i686-linux-android".to_string(),
|
||||||
|
|
|
@ -7,7 +7,8 @@ pub fn target() -> Target {
|
||||||
let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
|
let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
|
||||||
pre_link_args.push("-m32".to_string());
|
pre_link_args.push("-m32".to_string());
|
||||||
pre_link_args.push("-Wl,-znotext".to_string());
|
pre_link_args.push("-Wl,-znotext".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-unknown-freebsd".to_string(),
|
llvm_target: "i686-unknown-freebsd".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "pentium4".to_string();
|
base.cpu = "pentium4".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
|
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-unknown-haiku".to_string(),
|
llvm_target: "i686-unknown-haiku".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "pentium4".to_string();
|
base.cpu = "pentium4".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-unknown-linux-gnu".to_string(),
|
llvm_target: "i686-unknown-linux-gnu".to_string(),
|
||||||
|
|
|
@ -6,7 +6,8 @@ pub fn target() -> Target {
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
// The unwinder used by i686-unknown-linux-musl, the LLVM libunwind
|
// The unwinder used by i686-unknown-linux-musl, the LLVM libunwind
|
||||||
// implementation, apparently relies on frame pointers existing... somehow.
|
// implementation, apparently relies on frame pointers existing... somehow.
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "pentium4".to_string();
|
base.cpu = "pentium4".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-unknown-netbsdelf".to_string(),
|
llvm_target: "i686-unknown-netbsdelf".to_string(),
|
||||||
|
|
|
@ -6,7 +6,8 @@ pub fn target() -> Target {
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-fuse-ld=lld".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-fuse-ld=lld".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-unknown-openbsd".to_string(),
|
llvm_target: "i686-unknown-openbsd".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "pentium4".to_string();
|
base.cpu = "pentium4".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-unknown-linux-gnu".to_string(),
|
llvm_target: "i686-unknown-linux-gnu".to_string(),
|
||||||
|
|
|
@ -13,7 +13,8 @@ pub fn opts() -> TargetOptions {
|
||||||
env: "gnu".to_string(),
|
env: "gnu".to_string(),
|
||||||
disable_redzone: true,
|
disable_redzone: true,
|
||||||
panic_strategy: PanicStrategy::Abort,
|
panic_strategy: PanicStrategy::Abort,
|
||||||
stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) },
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
stack_probes: StackProbeType::Call,
|
||||||
eliminate_frame_pointer: false,
|
eliminate_frame_pointer: false,
|
||||||
linker_is_gnu: true,
|
linker_is_gnu: true,
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
|
|
|
@ -10,7 +10,8 @@ pub fn target() -> Target {
|
||||||
vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()],
|
vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()],
|
||||||
);
|
);
|
||||||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
// Clang automatically chooses a more specific target based on
|
// Clang automatically chooses a more specific target based on
|
||||||
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
|
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
|
||||||
|
|
|
@ -11,7 +11,8 @@ pub fn target() -> Target {
|
||||||
arch: "x86_64".to_string(),
|
arch: "x86_64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) },
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
stack_probes: StackProbeType::Call,
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ pub fn target() -> Target {
|
||||||
arch: "x86_64".to_string(),
|
arch: "x86_64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) },
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
stack_probes: StackProbeType::Call,
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ pub fn target() -> Target {
|
||||||
arch: "x86_64".to_string(),
|
arch: "x86_64".to_string(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) },
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
stack_probes: StackProbeType::Call,
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ pub fn target() -> Target {
|
||||||
let mut base = super::fuchsia_base::opts();
|
let mut base = super::fuchsia_base::opts();
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-fuchsia".to_string(),
|
llvm_target: "x86_64-fuchsia".to_string(),
|
||||||
|
|
|
@ -7,7 +7,8 @@ pub fn target() -> Target {
|
||||||
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".to_string();
|
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-linux-android".to_string(),
|
llvm_target: "x86_64-linux-android".to_string(),
|
||||||
|
|
|
@ -6,7 +6,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.vendor = "pc".to_string();
|
base.vendor = "pc".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-pc-solaris".to_string(),
|
llvm_target: "x86_64-pc-solaris".to_string(),
|
||||||
|
|
|
@ -6,7 +6,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.vendor = "sun".to_string();
|
base.vendor = "sun".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-pc-solaris".to_string(),
|
llvm_target: "x86_64-pc-solaris".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-dragonfly".to_string(),
|
llvm_target: "x86_64-unknown-dragonfly".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-freebsd".to_string(),
|
llvm_target: "x86_64-unknown-freebsd".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
|
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
// This option is required to build executables on Haiku x86_64
|
// This option is required to build executables on Haiku x86_64
|
||||||
base.position_independent_executables = true;
|
base.position_independent_executables = true;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.features = "+rdrnd,+rdseed".to_string();
|
base.features = "+rdrnd,+rdseed".to_string();
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-hermit".to_string(),
|
llvm_target: "x86_64-unknown-hermit".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-linux-gnu".to_string(),
|
llvm_target: "x86_64-unknown-linux-gnu".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
base.has_elf_tls = false;
|
base.has_elf_tls = false;
|
||||||
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
|
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
|
||||||
// breaks code gen. See LLVM bug 36743
|
// breaks code gen. See LLVM bug 36743
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
base.static_position_independent_executables = true;
|
base.static_position_independent_executables = true;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-netbsd".to_string(),
|
llvm_target: "x86_64-unknown-netbsd".to_string(),
|
||||||
|
|
|
@ -7,7 +7,8 @@ pub fn target() -> Target {
|
||||||
base.features =
|
base.features =
|
||||||
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
|
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
|
||||||
.to_string();
|
.to_string();
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-none-elf".to_string(),
|
llvm_target: "x86_64-unknown-none-elf".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-openbsd".to_string(),
|
llvm_target: "x86_64-unknown-openbsd".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-unknown-redox".to_string(),
|
llvm_target: "x86_64-unknown-redox".to_string(),
|
||||||
|
|
|
@ -5,7 +5,8 @@ pub fn target() -> Target {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||||
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
|
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||||
|
base.stack_probes = StackProbeType::Call;
|
||||||
base.disable_redzone = true;
|
base.disable_redzone = true;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
|
|
|
@ -1742,6 +1742,18 @@ extern "rust-intrinsic" {
|
||||||
/// Allocate at compile time. Should not be called at runtime.
|
/// Allocate at compile time. Should not be called at runtime.
|
||||||
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
||||||
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
|
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some functions are defined here because they accidentally got made
|
||||||
|
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
|
||||||
|
// (`transmute` also falls into this category, but it cannot be wrapped due to the
|
||||||
|
// check that `T` and `U` have the same size.)
|
||||||
|
|
||||||
|
/// Checks whether `ptr` is properly aligned with respect to
|
||||||
|
/// `align_of::<T>()`.
|
||||||
|
pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
|
||||||
|
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
|
||||||
|
}
|
||||||
|
|
||||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||||
/// and destination must *not* overlap.
|
/// and destination must *not* overlap.
|
||||||
|
@ -1827,7 +1839,27 @@ extern "rust-intrinsic" {
|
||||||
#[doc(alias = "memcpy")]
|
#[doc(alias = "memcpy")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
#[inline]
|
||||||
|
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
|
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Perform these checks only at run time
|
||||||
|
/*if cfg!(debug_assertions)
|
||||||
|
&& !(is_aligned_and_not_null(src)
|
||||||
|
&& is_aligned_and_not_null(dst)
|
||||||
|
&& is_nonoverlapping(src, dst, count))
|
||||||
|
{
|
||||||
|
// Not panicking to keep codegen impact smaller.
|
||||||
|
abort();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// SAFETY: the safety contract for `copy_nonoverlapping` must be
|
||||||
|
// upheld by the caller.
|
||||||
|
unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||||
/// and destination may overlap.
|
/// and destination may overlap.
|
||||||
|
@ -1892,18 +1924,21 @@ extern "rust-intrinsic" {
|
||||||
#[doc(alias = "memmove")]
|
#[doc(alias = "memmove")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
#[inline]
|
||||||
|
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
|
fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some functions are defined here because they accidentally got made
|
// FIXME: Perform these checks only at run time
|
||||||
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
|
/*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
|
||||||
// (`transmute` also falls into this category, but it cannot be wrapped due to the
|
// Not panicking to keep codegen impact smaller.
|
||||||
// check that `T` and `U` have the same size.)
|
abort();
|
||||||
|
}*/
|
||||||
|
|
||||||
/// Checks whether `ptr` is properly aligned with respect to
|
// SAFETY: the safety contract for `copy` must be upheld by the caller.
|
||||||
/// `align_of::<T>()`.
|
unsafe { copy(src, dst, count) }
|
||||||
pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
|
|
||||||
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
|
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
|
||||||
|
|
|
@ -110,60 +110,6 @@ macro_rules! assert_ne {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Asserts that an expression matches any of the given patterns.
|
|
||||||
///
|
|
||||||
/// Like in a `match` expression, the pattern can be optionally followed by `if`
|
|
||||||
/// and a guard expression that has access to names bound by the pattern.
|
|
||||||
///
|
|
||||||
/// On panic, this macro will print the value of the expression with its
|
|
||||||
/// debug representation.
|
|
||||||
///
|
|
||||||
/// Like [`assert!`], this macro has a second form, where a custom
|
|
||||||
/// panic message can be provided.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(assert_matches)]
|
|
||||||
///
|
|
||||||
/// let a = 1u32.checked_add(2);
|
|
||||||
/// let b = 1u32.checked_sub(2);
|
|
||||||
/// assert_matches!(a, Some(_));
|
|
||||||
/// assert_matches!(b, None);
|
|
||||||
///
|
|
||||||
/// let c = Ok("abc".to_string());
|
|
||||||
/// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
|
|
||||||
/// ```
|
|
||||||
#[macro_export]
|
|
||||||
#[unstable(feature = "assert_matches", issue = "82775")]
|
|
||||||
#[allow_internal_unstable(core_panic)]
|
|
||||||
macro_rules! assert_matches {
|
|
||||||
($left:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => ({
|
|
||||||
match $left {
|
|
||||||
$( $pattern )|+ $( if $guard )? => {}
|
|
||||||
ref left_val => {
|
|
||||||
$crate::panicking::assert_matches_failed(
|
|
||||||
left_val,
|
|
||||||
$crate::stringify!($($pattern)|+ $(if $guard)?),
|
|
||||||
$crate::option::Option::None
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
($left:expr, $( $pattern:pat )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
|
|
||||||
match $left {
|
|
||||||
$( $pattern )|+ $( if $guard )? => {}
|
|
||||||
ref left_val => {
|
|
||||||
$crate::panicking::assert_matches_failed(
|
|
||||||
left_val,
|
|
||||||
$crate::stringify!($($pattern)|+ $(if $guard)?),
|
|
||||||
$crate::option::Option::Some($crate::format_args!($($arg)+))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Asserts that a boolean expression is `true` at runtime.
|
/// Asserts that a boolean expression is `true` at runtime.
|
||||||
///
|
///
|
||||||
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
||||||
|
@ -262,42 +208,6 @@ macro_rules! debug_assert_ne {
|
||||||
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
|
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Asserts that an expression matches any of the given patterns.
|
|
||||||
///
|
|
||||||
/// Like in a `match` expression, the pattern can be optionally followed by `if`
|
|
||||||
/// and a guard expression that has access to names bound by the pattern.
|
|
||||||
///
|
|
||||||
/// On panic, this macro will print the value of the expression with its
|
|
||||||
/// debug representation.
|
|
||||||
///
|
|
||||||
/// Unlike [`assert_matches!`], `debug_assert_matches!` statements are only
|
|
||||||
/// enabled in non optimized builds by default. An optimized build will not
|
|
||||||
/// execute `debug_assert_matches!` statements unless `-C debug-assertions` is
|
|
||||||
/// passed to the compiler. This makes `debug_assert_matches!` useful for
|
|
||||||
/// checks that are too expensive to be present in a release build but may be
|
|
||||||
/// helpful during development. The result of expanding `debug_assert_matches!`
|
|
||||||
/// is always type checked.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(assert_matches)]
|
|
||||||
///
|
|
||||||
/// let a = 1u32.checked_add(2);
|
|
||||||
/// let b = 1u32.checked_sub(2);
|
|
||||||
/// debug_assert_matches!(a, Some(_));
|
|
||||||
/// debug_assert_matches!(b, None);
|
|
||||||
///
|
|
||||||
/// let c = Ok("abc".to_string());
|
|
||||||
/// debug_assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
|
|
||||||
/// ```
|
|
||||||
#[macro_export]
|
|
||||||
#[unstable(feature = "assert_matches", issue = "82775")]
|
|
||||||
#[allow_internal_unstable(assert_matches)]
|
|
||||||
macro_rules! debug_assert_matches {
|
|
||||||
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_matches!($($arg)*); })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether the given expression matches any of the given patterns.
|
/// Returns whether the given expression matches any of the given patterns.
|
||||||
///
|
///
|
||||||
/// Like in a `match` expression, the pattern can be optionally followed by `if`
|
/// Like in a `match` expression, the pattern can be optionally followed by `if`
|
||||||
|
|
|
@ -682,8 +682,7 @@ pub unsafe fn uninitialized<T>() -> T {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||||
pub const fn swap<T>(x: &mut T, y: &mut T) {
|
|
||||||
// SAFETY: the raw pointers have been created from safe mutable references satisfying all the
|
// SAFETY: the raw pointers have been created from safe mutable references satisfying all the
|
||||||
// constraints on `ptr::swap_nonoverlapping_one`
|
// constraints on `ptr::swap_nonoverlapping_one`
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -813,8 +812,7 @@ pub fn take<T: Default>(dest: &mut T) -> T {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
pub fn replace<T>(dest: &mut T, src: T) -> T {
|
||||||
pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
|
||||||
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
|
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
|
||||||
// such that the old value is not duplicated. Nothing is dropped and
|
// such that the old value is not duplicated. Nothing is dropped and
|
||||||
// nothing here can panic.
|
// nothing here can panic.
|
||||||
|
|
|
@ -97,7 +97,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
|
||||||
pub enum AssertKind {
|
pub enum AssertKind {
|
||||||
Eq,
|
Eq,
|
||||||
Ne,
|
Ne,
|
||||||
Match,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal function for `assert_eq!` and `assert_ne!` macros
|
/// Internal function for `assert_eq!` and `assert_ne!` macros
|
||||||
|
@ -114,31 +113,8 @@ where
|
||||||
T: fmt::Debug + ?Sized,
|
T: fmt::Debug + ?Sized,
|
||||||
U: fmt::Debug + ?Sized,
|
U: fmt::Debug + ?Sized,
|
||||||
{
|
{
|
||||||
assert_failed_inner(kind, &left, &right, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Internal function for `assert_match!`
|
|
||||||
#[cold]
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[doc(hidden)]
|
fn inner(
|
||||||
pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
|
|
||||||
left: &T,
|
|
||||||
right: &str,
|
|
||||||
args: Option<fmt::Arguments<'_>>,
|
|
||||||
) -> ! {
|
|
||||||
// Use the Display implementation to display the pattern.
|
|
||||||
struct Pattern<'a>(&'a str);
|
|
||||||
impl fmt::Debug for Pattern<'_> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
fmt::Display::fmt(self.0, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert_failed_inner(AssertKind::Match, &left, &Pattern(right), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Non-generic version of the above functions, to avoid code bloat.
|
|
||||||
#[track_caller]
|
|
||||||
fn assert_failed_inner(
|
|
||||||
kind: AssertKind,
|
kind: AssertKind,
|
||||||
left: &dyn fmt::Debug,
|
left: &dyn fmt::Debug,
|
||||||
right: &dyn fmt::Debug,
|
right: &dyn fmt::Debug,
|
||||||
|
@ -147,7 +123,6 @@ fn assert_failed_inner(
|
||||||
let op = match kind {
|
let op = match kind {
|
||||||
AssertKind::Eq => "==",
|
AssertKind::Eq => "==",
|
||||||
AssertKind::Ne => "!=",
|
AssertKind::Ne => "!=",
|
||||||
AssertKind::Match => "matches",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match args {
|
match args {
|
||||||
|
@ -165,3 +140,5 @@ fn assert_failed_inner(
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inner(kind, &left, &right, args)
|
||||||
|
}
|
||||||
|
|
|
@ -463,8 +463,7 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
|
||||||
pub(crate) const unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
|
|
||||||
// For types smaller than the block optimization below,
|
// For types smaller than the block optimization below,
|
||||||
// just swap directly to avoid pessimizing codegen.
|
// just swap directly to avoid pessimizing codegen.
|
||||||
if mem::size_of::<T>() < 32 {
|
if mem::size_of::<T>() < 32 {
|
||||||
|
@ -584,8 +583,7 @@ const unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
|
||||||
pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
|
|
||||||
// SAFETY: the caller must guarantee that `dst` is valid to be
|
// SAFETY: the caller must guarantee that `dst` is valid to be
|
||||||
// cast to a mutable reference (valid for writes, aligned, initialized),
|
// cast to a mutable reference (valid for writes, aligned, initialized),
|
||||||
// and cannot overlap `src` since `dst` must point to a distinct
|
// and cannot overlap `src` since `dst` must point to a distinct
|
||||||
|
@ -898,14 +896,18 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
|
pub unsafe fn write<T>(dst: *mut T, src: T) {
|
||||||
pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
// We are calling the intrinsics directly to avoid function calls in the generated code
|
||||||
|
// as `intrinsics::copy_nonoverlapping` is a wrapper function.
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
|
}
|
||||||
|
|
||||||
// SAFETY: the caller must guarantee that `dst` is valid for writes.
|
// SAFETY: the caller must guarantee that `dst` is valid for writes.
|
||||||
// `dst` cannot overlap `src` because the caller has mutable access
|
// `dst` cannot overlap `src` because the caller has mutable access
|
||||||
// to `dst` while `src` is owned by this function.
|
// to `dst` while `src` is owned by this function.
|
||||||
unsafe {
|
unsafe {
|
||||||
copy_nonoverlapping(&src as *const T, dst, 1);
|
copy_nonoverlapping(&src as *const T, dst, 1);
|
||||||
// We are calling the intrinsic directly to avoid function calls in the generated code.
|
|
||||||
intrinsics::forget(src);
|
intrinsics::forget(src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1013,9 +1013,8 @@ impl<T: ?Sized> *mut T {
|
||||||
///
|
///
|
||||||
/// [`ptr::write`]: crate::ptr::write()
|
/// [`ptr::write`]: crate::ptr::write()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn write(self, val: T)
|
pub unsafe fn write(self, val: T)
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,52 +50,52 @@ fn mut_ptr_read() {
|
||||||
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
//#[test]
|
||||||
fn write() {
|
//fn write() {
|
||||||
use core::ptr;
|
// use core::ptr;
|
||||||
|
//
|
||||||
|
// const fn write_aligned() -> i32 {
|
||||||
|
// let mut res = 0;
|
||||||
|
// unsafe {
|
||||||
|
// ptr::write(&mut res as *mut _, 42);
|
||||||
|
// }
|
||||||
|
// res
|
||||||
|
// }
|
||||||
|
// const ALIGNED: i32 = write_aligned();
|
||||||
|
// assert_eq!(ALIGNED, 42);
|
||||||
|
//
|
||||||
|
// const fn write_unaligned() -> [u16; 2] {
|
||||||
|
// let mut two_aligned = [0u16; 2];
|
||||||
|
// unsafe {
|
||||||
|
// let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
|
||||||
|
// ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
|
||||||
|
// }
|
||||||
|
// two_aligned
|
||||||
|
// }
|
||||||
|
// const UNALIGNED: [u16; 2] = write_unaligned();
|
||||||
|
// assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
|
||||||
|
//}
|
||||||
|
|
||||||
const fn write_aligned() -> i32 {
|
//#[test]
|
||||||
let mut res = 0;
|
//fn mut_ptr_write() {
|
||||||
unsafe {
|
// const fn aligned() -> i32 {
|
||||||
ptr::write(&mut res as *mut _, 42);
|
// let mut res = 0;
|
||||||
}
|
// unsafe {
|
||||||
res
|
// (&mut res as *mut i32).write(42);
|
||||||
}
|
// }
|
||||||
const ALIGNED: i32 = write_aligned();
|
// res
|
||||||
assert_eq!(ALIGNED, 42);
|
// }
|
||||||
|
// const ALIGNED: i32 = aligned();
|
||||||
const fn write_unaligned() -> [u16; 2] {
|
// assert_eq!(ALIGNED, 42);
|
||||||
let mut two_aligned = [0u16; 2];
|
//
|
||||||
unsafe {
|
// const fn write_unaligned() -> [u16; 2] {
|
||||||
let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
|
// let mut two_aligned = [0u16; 2];
|
||||||
ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
|
// unsafe {
|
||||||
}
|
// let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
|
||||||
two_aligned
|
// unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
|
||||||
}
|
// }
|
||||||
const UNALIGNED: [u16; 2] = write_unaligned();
|
// two_aligned
|
||||||
assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
|
// }
|
||||||
}
|
// const UNALIGNED: [u16; 2] = write_unaligned();
|
||||||
|
// assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
|
||||||
#[test]
|
//}
|
||||||
fn mut_ptr_write() {
|
|
||||||
const fn aligned() -> i32 {
|
|
||||||
let mut res = 0;
|
|
||||||
unsafe {
|
|
||||||
(&mut res as *mut i32).write(42);
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
const ALIGNED: i32 = aligned();
|
|
||||||
assert_eq!(ALIGNED, 42);
|
|
||||||
|
|
||||||
const fn write_unaligned() -> [u16; 2] {
|
|
||||||
let mut two_aligned = [0u16; 2];
|
|
||||||
unsafe {
|
|
||||||
let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
|
|
||||||
unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
|
|
||||||
}
|
|
||||||
two_aligned
|
|
||||||
}
|
|
||||||
const UNALIGNED: [u16; 2] = write_unaligned();
|
|
||||||
assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
|
|
||||||
}
|
|
||||||
|
|
|
@ -228,7 +228,6 @@
|
||||||
#![feature(arbitrary_self_types)]
|
#![feature(arbitrary_self_types)]
|
||||||
#![feature(array_error_internals)]
|
#![feature(array_error_internals)]
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
#![feature(assert_matches)]
|
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(atomic_mut_ptr)]
|
#![feature(atomic_mut_ptr)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
@ -559,8 +558,8 @@ pub use std_detect::detect;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[allow(deprecated, deprecated_in_future)]
|
#[allow(deprecated, deprecated_in_future)]
|
||||||
pub use core::{
|
pub use core::{
|
||||||
assert_eq, assert_matches, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches,
|
assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, r#try, todo,
|
||||||
debug_assert_ne, matches, r#try, todo, unimplemented, unreachable, write, writeln,
|
unimplemented, unreachable, write, writeln,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Re-export built-in macros defined through libcore.
|
// Re-export built-in macros defined through libcore.
|
||||||
|
|
|
@ -68,7 +68,7 @@ fi
|
||||||
#
|
#
|
||||||
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
||||||
# either automatically or manually.
|
# either automatically or manually.
|
||||||
export RUST_RELEASE_CHANNEL=beta
|
export RUST_RELEASE_CHANNEL=stable
|
||||||
|
|
||||||
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
|
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
|
||||||
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
|
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
|
||||||
|
|
|
@ -5,8 +5,7 @@ use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_hir::def_id::{LOCAL_CRATE};
|
||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
|
@ -53,9 +52,6 @@ crate struct Context<'tcx> {
|
||||||
pub(super) render_redirect_pages: bool,
|
pub(super) render_redirect_pages: bool,
|
||||||
/// The map used to ensure all generated 'id=' attributes are unique.
|
/// The map used to ensure all generated 'id=' attributes are unique.
|
||||||
pub(super) id_map: RefCell<IdMap>,
|
pub(super) id_map: RefCell<IdMap>,
|
||||||
/// Tracks section IDs for `Deref` targets so they match in both the main
|
|
||||||
/// body and the sidebar.
|
|
||||||
pub(super) deref_id_map: RefCell<FxHashMap<DefId, String>>,
|
|
||||||
/// Shared mutable state.
|
/// Shared mutable state.
|
||||||
///
|
///
|
||||||
/// Issue for improving the situation: [#82381][]
|
/// Issue for improving the situation: [#82381][]
|
||||||
|
@ -76,7 +72,7 @@ crate struct Context<'tcx> {
|
||||||
|
|
||||||
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
|
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
rustc_data_structures::static_assert_size!(Context<'_>, 152);
|
rustc_data_structures::static_assert_size!(Context<'_>, 112);
|
||||||
|
|
||||||
impl<'tcx> Context<'tcx> {
|
impl<'tcx> Context<'tcx> {
|
||||||
pub(super) fn path(&self, filename: &str) -> PathBuf {
|
pub(super) fn path(&self, filename: &str) -> PathBuf {
|
||||||
|
@ -416,7 +412,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||||
dst,
|
dst,
|
||||||
render_redirect_pages: false,
|
render_redirect_pages: false,
|
||||||
id_map: RefCell::new(id_map),
|
id_map: RefCell::new(id_map),
|
||||||
deref_id_map: RefCell::new(FxHashMap::default()),
|
|
||||||
shared: Rc::new(scx),
|
shared: Rc::new(scx),
|
||||||
cache: Rc::new(cache),
|
cache: Rc::new(cache),
|
||||||
};
|
};
|
||||||
|
@ -439,7 +434,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||||
dst: self.dst.clone(),
|
dst: self.dst.clone(),
|
||||||
render_redirect_pages: self.render_redirect_pages,
|
render_redirect_pages: self.render_redirect_pages,
|
||||||
id_map: RefCell::new(id_map),
|
id_map: RefCell::new(id_map),
|
||||||
deref_id_map: RefCell::new(FxHashMap::default()),
|
|
||||||
shared: Rc::clone(&self.shared),
|
shared: Rc::clone(&self.shared),
|
||||||
cache: Rc::clone(&self.cache),
|
cache: Rc::clone(&self.cache),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1159,21 +1159,12 @@ fn render_assoc_items(
|
||||||
RenderMode::Normal
|
RenderMode::Normal
|
||||||
}
|
}
|
||||||
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
|
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
|
||||||
let id = cx.derive_id(small_url_encode(format!(
|
|
||||||
"deref-methods-{:#}",
|
|
||||||
type_.print(cx.cache())
|
|
||||||
)));
|
|
||||||
debug!("Adding {} to deref id map", type_.print(cx.cache()));
|
|
||||||
cx.deref_id_map
|
|
||||||
.borrow_mut()
|
|
||||||
.insert(type_.def_id_full(cx.cache()).unwrap(), id.clone());
|
|
||||||
write!(
|
write!(
|
||||||
w,
|
w,
|
||||||
"<h2 id=\"{id}\" class=\"small-section-header\">\
|
"<h2 id=\"deref-methods\" class=\"small-section-header\">\
|
||||||
Methods from {trait_}<Target = {type_}>\
|
Methods from {trait_}<Target = {type_}>\
|
||||||
<a href=\"#{id}\" class=\"anchor\"></a>\
|
<a href=\"#deref-methods\" class=\"anchor\"></a>\
|
||||||
</h2>",
|
</h2>",
|
||||||
id = id,
|
|
||||||
trait_ = trait_.print(cx.cache()),
|
trait_ = trait_.print(cx.cache()),
|
||||||
type_ = type_.print(cx.cache()),
|
type_ = type_.print(cx.cache()),
|
||||||
);
|
);
|
||||||
|
@ -1198,6 +1189,9 @@ fn render_assoc_items(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let AssocItemRender::DerefFor { .. } = what {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if !traits.is_empty() {
|
if !traits.is_empty() {
|
||||||
let deref_impl = traits
|
let deref_impl = traits
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1208,13 +1202,6 @@ fn render_assoc_items(
|
||||||
});
|
});
|
||||||
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
|
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we were already one level into rendering deref methods, we don't want to render
|
|
||||||
// anything after recursing into any further deref methods above.
|
|
||||||
if let AssocItemRender::DerefFor { .. } = what {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
|
let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
|
||||||
traits.iter().partition(|t| t.inner_impl().synthetic);
|
traits.iter().partition(|t| t.inner_impl().synthetic);
|
||||||
let (blanket_impl, concrete): (Vec<&&Impl>, _) =
|
let (blanket_impl, concrete): (Vec<&&Impl>, _) =
|
||||||
|
@ -2020,14 +2007,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
|
||||||
.flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c))
|
.flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if !ret.is_empty() {
|
if !ret.is_empty() {
|
||||||
let deref_id_map = cx.deref_id_map.borrow();
|
|
||||||
let id = deref_id_map
|
|
||||||
.get(&real_target.def_id_full(cx.cache()).unwrap())
|
|
||||||
.expect("Deref section without derived id");
|
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
"<a class=\"sidebar-title\" href=\"#{}\">Methods from {}<Target={}></a>",
|
"<a class=\"sidebar-title\" href=\"#deref-methods\">Methods from {}<Target={}></a>",
|
||||||
id,
|
|
||||||
Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(c))),
|
Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(c))),
|
||||||
Escape(&format!("{:#}", real_target.print(c))),
|
Escape(&format!("{:#}", real_target.print(c))),
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::clean::*;
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::fold::DocFolder;
|
use crate::fold::DocFolder;
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashSet};
|
||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc_middle::ty::DefIdTree;
|
use rustc_middle::ty::DefIdTree;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -53,6 +53,39 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut cleaner = BadImplStripper { prims, items: crate_items };
|
||||||
|
|
||||||
|
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
|
||||||
|
for it in &new_items {
|
||||||
|
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
|
||||||
|
if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
|
||||||
|
let target = items
|
||||||
|
.iter()
|
||||||
|
.find_map(|item| match *item.kind {
|
||||||
|
TypedefItem(ref t, true) => Some(&t.type_),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.expect("Deref impl without Target type");
|
||||||
|
|
||||||
|
if let Some(prim) = target.primitive_type() {
|
||||||
|
cleaner.prims.insert(prim);
|
||||||
|
} else if let Some(did) = target.def_id() {
|
||||||
|
cleaner.items.insert(did);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_items.retain(|it| {
|
||||||
|
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
|
||||||
|
cleaner.keep_impl(for_)
|
||||||
|
|| trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
|
||||||
|
|| blanket_impl.is_some()
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
|
// `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
|
||||||
// doesn't work with it anyway, so pull them from the HIR map instead
|
// doesn't work with it anyway, so pull them from the HIR map instead
|
||||||
let mut extra_attrs = Vec::new();
|
let mut extra_attrs = Vec::new();
|
||||||
|
@ -84,53 +117,6 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cleaner = BadImplStripper { prims, items: crate_items };
|
|
||||||
|
|
||||||
let mut type_did_to_deref_target: FxHashMap<DefId, &Type> = FxHashMap::default();
|
|
||||||
// Gather all type to `Deref` target edges.
|
|
||||||
for it in &new_items {
|
|
||||||
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
|
|
||||||
if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
|
|
||||||
let target = items.iter().find_map(|item| match *item.kind {
|
|
||||||
TypedefItem(ref t, true) => Some(&t.type_),
|
|
||||||
_ => None,
|
|
||||||
});
|
|
||||||
if let (Some(for_did), Some(target)) = (for_.def_id(), target) {
|
|
||||||
type_did_to_deref_target.insert(for_did, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Follow all `Deref` targets of included items and recursively add them as valid
|
|
||||||
fn add_deref_target(
|
|
||||||
map: &FxHashMap<DefId, &Type>,
|
|
||||||
cleaner: &mut BadImplStripper,
|
|
||||||
type_did: &DefId,
|
|
||||||
) {
|
|
||||||
if let Some(target) = map.get(type_did) {
|
|
||||||
debug!("add_deref_target: type {:?}, target {:?}", type_did, target);
|
|
||||||
if let Some(target_prim) = target.primitive_type() {
|
|
||||||
cleaner.prims.insert(target_prim);
|
|
||||||
} else if let Some(target_did) = target.def_id() {
|
|
||||||
// `impl Deref<Target = S> for S`
|
|
||||||
if target_did == *type_did {
|
|
||||||
// Avoid infinite cycles
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cleaner.items.insert(target_did);
|
|
||||||
add_deref_target(map, cleaner, &target_did);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for type_did in type_did_to_deref_target.keys() {
|
|
||||||
// Since only the `DefId` portion of the `Type` instances is known to be same for both the
|
|
||||||
// `Deref` target type and the impl for type positions, this map of types is keyed by
|
|
||||||
// `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
|
|
||||||
if cleaner.keep_impl_with_def_id(type_did) {
|
|
||||||
add_deref_target(&type_did_to_deref_target, &mut cleaner, type_did);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let items = if let Some(ref mut it) = krate.module {
|
let items = if let Some(ref mut it) = krate.module {
|
||||||
if let ModuleItem(Module { ref mut items, .. }) = *it.kind {
|
if let ModuleItem(Module { ref mut items, .. }) = *it.kind {
|
||||||
items
|
items
|
||||||
|
@ -142,18 +128,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||||
};
|
};
|
||||||
|
|
||||||
items.extend(synth_impls);
|
items.extend(synth_impls);
|
||||||
for it in new_items.drain(..) {
|
items.extend(new_items);
|
||||||
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
|
|
||||||
if !(cleaner.keep_impl(for_)
|
|
||||||
|| trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
|
|
||||||
|| blanket_impl.is_some())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
items.push(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
krate
|
krate
|
||||||
}
|
}
|
||||||
|
@ -208,13 +183,9 @@ impl BadImplStripper {
|
||||||
} else if let Some(prim) = ty.primitive_type() {
|
} else if let Some(prim) = ty.primitive_type() {
|
||||||
self.prims.contains(&prim)
|
self.prims.contains(&prim)
|
||||||
} else if let Some(did) = ty.def_id() {
|
} else if let Some(did) = ty.def_id() {
|
||||||
self.keep_impl_with_def_id(&did)
|
self.items.contains(&did)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keep_impl_with_def_id(&self, did: &DefId) -> bool {
|
|
||||||
self.items.contains(did)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
// min-llvm-version: 11.0.1
|
|
||||||
// revisions: x86_64 i686
|
|
||||||
// assembly-output: emit-asm
|
|
||||||
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
|
|
||||||
//[i686] compile-flags: --target i686-unknown-linux-gnu
|
|
||||||
// compile-flags: -C llvm-args=--x86-asm-syntax=intel
|
|
||||||
|
|
||||||
#![feature(no_core, lang_items)]
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#![no_core]
|
|
||||||
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
|
|
||||||
impl Copy for u8 {}
|
|
||||||
|
|
||||||
// Check that inline-asm stack probes are generated correctly.
|
|
||||||
// To avoid making this test fragile to slight asm changes,
|
|
||||||
// we only check that the stack pointer is decremented by a page at a time,
|
|
||||||
// instead of matching the whole probe sequence.
|
|
||||||
|
|
||||||
// CHECK-LABEL: small_stack_probe:
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn small_stack_probe(x: u8, f: fn([u8; 8192])) {
|
|
||||||
// CHECK-NOT: __rust_probestack
|
|
||||||
// x86_64: sub rsp, 4096
|
|
||||||
// i686: sub esp, 4096
|
|
||||||
let a = [x; 8192];
|
|
||||||
f(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK-LABEL: big_stack_probe:
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn big_stack_probe(x: u8, f: fn([u8; 65536])) {
|
|
||||||
// CHECK-NOT: __rust_probestack
|
|
||||||
// x86_64: sub rsp, 4096
|
|
||||||
// i686: sub esp, 4096
|
|
||||||
let a = [x; 65536];
|
|
||||||
f(a);
|
|
||||||
}
|
|
|
@ -13,12 +13,10 @@
|
||||||
// ignore-emscripten
|
// ignore-emscripten
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// compile-flags: -C no-prepopulate-passes
|
// compile-flags: -C no-prepopulate-passes
|
||||||
// min-llvm-version: 11.0.1
|
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn foo() {
|
pub fn foo() {
|
||||||
// CHECK: @foo() unnamed_addr #0
|
// CHECK: @foo() unnamed_addr #0
|
||||||
// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
// check-pass
|
|
||||||
// #26207: Ensure `Deref` cycles are properly handled without errors.
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
struct S;
|
|
||||||
|
|
||||||
impl std::ops::Deref for S {
|
|
||||||
type Target = S;
|
|
||||||
|
|
||||||
fn deref(&self) -> &S {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let s: S = *******S;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
// ignore-tidy-linelength
|
|
||||||
|
|
||||||
// #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing
|
|
||||||
// levels and across multiple crates.
|
|
||||||
|
|
||||||
// @has 'foo/struct.Foo.html'
|
|
||||||
// @has '-' '//*[@id="deref-methods-PathBuf"]' 'Methods from Deref<Target = PathBuf>'
|
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.as_path"]' 'pub fn as_path(&self)'
|
|
||||||
// @has '-' '//*[@id="deref-methods-Path"]' 'Methods from Deref<Target = Path>'
|
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.exists"]' 'pub fn exists(&self)'
|
|
||||||
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-PathBuf"]' 'Methods from Deref<Target=PathBuf>'
|
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.as_path"]' 'as_path'
|
|
||||||
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Path"]' 'Methods from Deref<Target=Path>'
|
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.exists"]' 'exists'
|
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
|
||||||
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub struct Foo(PathBuf);
|
|
||||||
|
|
||||||
impl Deref for Foo {
|
|
||||||
type Target = PathBuf;
|
|
||||||
fn deref(&self) -> &PathBuf { &self.0 }
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
// ignore-tidy-linelength
|
|
||||||
|
|
||||||
// #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing
|
|
||||||
// levels if needed.
|
|
||||||
|
|
||||||
// @has 'foo/struct.Foo.html'
|
|
||||||
// @has '-' '//*[@id="deref-methods-Bar"]' 'Methods from Deref<Target = Bar>'
|
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.bar"]' 'pub fn bar(&self)'
|
|
||||||
// @has '-' '//*[@id="deref-methods-Baz"]' 'Methods from Deref<Target = Baz>'
|
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.baz"]' 'pub fn baz(&self)'
|
|
||||||
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Bar"]' 'Methods from Deref<Target=Bar>'
|
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.bar"]' 'bar'
|
|
||||||
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Baz"]' 'Methods from Deref<Target=Baz>'
|
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.baz"]' 'baz'
|
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
|
||||||
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
pub struct Foo(Bar);
|
|
||||||
pub struct Bar(Baz);
|
|
||||||
pub struct Baz;
|
|
||||||
|
|
||||||
impl Deref for Foo {
|
|
||||||
type Target = Bar;
|
|
||||||
fn deref(&self) -> &Bar { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Bar {
|
|
||||||
type Target = Baz;
|
|
||||||
fn deref(&self) -> &Baz { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Bar {
|
|
||||||
/// This appears under `Foo` methods
|
|
||||||
pub fn bar(&self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Baz {
|
|
||||||
/// This should also appear in `Foo` methods when recursing
|
|
||||||
pub fn baz(&self) {}
|
|
||||||
}
|
|
|
@ -1,14 +1,12 @@
|
||||||
// ignore-tidy-linelength
|
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
// @has 'foo/struct.Bar.html'
|
// @has 'foo/struct.Bar.html'
|
||||||
// @has '-' '//*[@id="deref-methods-FooJ"]' 'Methods from Deref<Target = FooJ>'
|
// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooJ>'
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)'
|
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)'
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
|
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
|
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
|
||||||
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
|
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
|
||||||
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-FooJ"]' 'Methods from Deref<Target=FooJ>'
|
// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods"]' 'Methods from Deref<Target=FooJ>'
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
|
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
|
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
|
||||||
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'
|
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
use std::convert::AsRef;
|
||||||
|
pub struct Local;
|
||||||
|
|
||||||
|
// @has issue_82465_asref_for_and_of_local/struct.Local.html '//code' 'impl AsRef<str> for Local'
|
||||||
|
impl AsRef<str> for Local {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has - '//code' 'impl AsRef<Local> for str'
|
||||||
|
impl AsRef<Local> for str {
|
||||||
|
fn as_ref(&self) -> &Local {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
struct A {
|
struct A {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// rust-lang/rust#83309: The compiler tries to suggest potential
|
||||||
|
// methods that return `&mut` items. However, when it doesn't
|
||||||
|
// find such methods, it still tries to add suggestions
|
||||||
|
// which then fails an assertion later because there was
|
||||||
|
// no suggestions to make.
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for v in Query.iter_mut() {
|
||||||
|
//~^ NOTE this iterator yields `&` references
|
||||||
|
*v -= 1;
|
||||||
|
//~^ ERROR cannot assign to `*v` which is behind a `&` reference
|
||||||
|
//~| NOTE `v` is a `&` reference, so the data it refers to cannot be written
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Query;
|
||||||
|
pub struct QueryIter<'a>(&'a i32);
|
||||||
|
|
||||||
|
impl Query {
|
||||||
|
pub fn iter_mut<'a>(&'a mut self) -> QueryIter<'a> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for QueryIter<'a> {
|
||||||
|
type Item = &'a i32;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0594]: cannot assign to `*v` which is behind a `&` reference
|
||||||
|
--> $DIR/issue-83309-ice-immut-in-for-loop.rs:11:9
|
||||||
|
|
|
||||||
|
LL | for v in Query.iter_mut() {
|
||||||
|
| ---------------- this iterator yields `&` references
|
||||||
|
LL |
|
||||||
|
LL | *v -= 1;
|
||||||
|
| ^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0594`.
|
|
@ -1,10 +1,11 @@
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
LL | unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
||||||
|
| inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||||
| inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
|
| inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
|
||||||
|
|
|
|
||||||
|
@ -18,12 +19,13 @@ LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
LL | unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
||||||
|
| inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||||
| inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
| inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
| inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
|
| inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
|
||||||
|
@ -37,12 +39,13 @@ LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
LL | unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
||||||
|
| inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||||
| inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
| inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
||||||
| inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
|
| inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
// ignore-tidy-linelength
|
|
||||||
#![feature(const_mut_refs, const_intrinsic_copy, const_ptr_offset)]
|
|
||||||
use std::{ptr, mem};
|
|
||||||
|
|
||||||
const COPY_ZERO: () = unsafe {
|
|
||||||
// Since we are not copying anything, this should be allowed.
|
|
||||||
let src = ();
|
|
||||||
let mut dst = ();
|
|
||||||
ptr::copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const COPY_OOB_1: () = unsafe {
|
|
||||||
let mut x = 0i32;
|
|
||||||
let dangle = (&mut x as *mut i32).wrapping_add(10);
|
|
||||||
// Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
|
|
||||||
ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| memory access failed: pointer must be in-bounds
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
const COPY_OOB_2: () = unsafe {
|
|
||||||
let x = 0i32;
|
|
||||||
let dangle = (&x as *const i32).wrapping_add(10);
|
|
||||||
// Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
|
|
||||||
ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| memory access failed: pointer must be in-bounds
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
|
|
||||||
const COPY_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
let x = 0;
|
|
||||||
let mut y = 0;
|
|
||||||
ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| overflow computing total size of `copy`
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
let x = 0;
|
|
||||||
let mut y = 0;
|
|
||||||
ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| overflow computing total size of `copy_nonoverlapping`
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:16:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_OOB_1: () = unsafe {
|
|
||||||
LL | | let mut x = 0i32;
|
|
||||||
LL | | let dangle = (&mut x as *mut i32).wrapping_add(10);
|
|
||||||
LL | | // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
|
|
||||||
LL | | ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0);
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc4 which has size 4
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= note: `#[deny(const_err)]` on by default
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:24:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_OOB_2: () = unsafe {
|
|
||||||
LL | | let x = 0i32;
|
|
||||||
LL | | let dangle = (&x as *const i32).wrapping_add(10);
|
|
||||||
LL | | // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
|
|
||||||
LL | | ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0);
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc6 which has size 4
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:32:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
LL | | let x = 0;
|
|
||||||
LL | | let mut y = 0;
|
|
||||||
LL | | ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:39:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
LL | | let x = 0;
|
|
||||||
LL | | let mut y = 0;
|
|
||||||
LL | | ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
#![deny(dead_code)]
|
|
||||||
|
|
||||||
struct S {
|
|
||||||
f: i32, //~ ERROR: field is never read
|
|
||||||
sub: Sub, //~ ERROR: field is never read
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Sub {
|
|
||||||
f: i32, //~ ERROR: field is never read
|
|
||||||
}
|
|
||||||
|
|
||||||
fn field_write(s: &mut S) {
|
|
||||||
s.f = 1;
|
|
||||||
s.sub.f = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut s = S { f: 0, sub: Sub { f: 0 } };
|
|
||||||
field_write(&mut s);
|
|
||||||
|
|
||||||
auto_deref();
|
|
||||||
nested_boxes();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn auto_deref() {
|
|
||||||
struct E {
|
|
||||||
x: bool,
|
|
||||||
y: bool, //~ ERROR: field is never read
|
|
||||||
}
|
|
||||||
|
|
||||||
struct P<'a> {
|
|
||||||
e: &'a mut E
|
|
||||||
}
|
|
||||||
|
|
||||||
impl P<'_> {
|
|
||||||
fn f(&mut self) {
|
|
||||||
self.e.x = true;
|
|
||||||
self.e.y = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut e = E { x: false, y: false };
|
|
||||||
let mut p = P { e: &mut e };
|
|
||||||
p.f();
|
|
||||||
assert!(e.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nested_boxes() {
|
|
||||||
struct A {
|
|
||||||
b: Box<B>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct B {
|
|
||||||
c: Box<C>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct C {
|
|
||||||
u: u32, //~ ERROR: field is never read
|
|
||||||
v: u32, //~ ERROR: field is never read
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut a = A {
|
|
||||||
b: Box::new(B {
|
|
||||||
c: Box::new(C { u: 0, v: 0 }),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
a.b.c.v = 10;
|
|
||||||
a.b.c = Box::new(C { u: 1, v: 2 });
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
error: field is never read: `f`
|
|
||||||
--> $DIR/write-only-field.rs:4:5
|
|
||||||
|
|
|
||||||
LL | f: i32,
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/write-only-field.rs:1:9
|
|
||||||
|
|
|
||||||
LL | #![deny(dead_code)]
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: field is never read: `sub`
|
|
||||||
--> $DIR/write-only-field.rs:5:5
|
|
||||||
|
|
|
||||||
LL | sub: Sub,
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: field is never read: `f`
|
|
||||||
--> $DIR/write-only-field.rs:9:5
|
|
||||||
|
|
|
||||||
LL | f: i32,
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
||||||
error: field is never read: `y`
|
|
||||||
--> $DIR/write-only-field.rs:28:9
|
|
||||||
|
|
|
||||||
LL | y: bool,
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
error: field is never read: `u`
|
|
||||||
--> $DIR/write-only-field.rs:58:9
|
|
||||||
|
|
|
||||||
LL | u: u32,
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
||||||
error: field is never read: `v`
|
|
||||||
--> $DIR/write-only-field.rs:59:9
|
|
||||||
|
|
|
||||||
LL | v: u32,
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
// run-fail
|
|
||||||
// error-pattern:panicked at 'assertion failed: `(left matches right)`
|
|
||||||
// error-pattern: left: `2`
|
|
||||||
// error-pattern:right: `3`: 1 + 1 definitely should be 3'
|
|
||||||
// ignore-emscripten no processes
|
|
||||||
|
|
||||||
#![feature(assert_matches)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
assert_matches!(1 + 1, 3, "1 + 1 definitely should be 3");
|
|
||||||
}
|
|
|
@ -18,8 +18,8 @@ pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeS
|
||||||
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
|
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
|
||||||
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
|
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
|
||||||
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
|
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
|
||||||
pub const COPY: [&str; 4] = ["core", "intrinsics", "", "copy_nonoverlapping"];
|
pub const COPY: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"];
|
||||||
pub const COPY_NONOVERLAPPING: [&str; 4] = ["core", "intrinsics", "", "copy"];
|
pub const COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy"];
|
||||||
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
|
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
|
||||||
pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
|
pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
|
||||||
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
|
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
|
||||||
|
|
Loading…
Reference in New Issue