Auto merge of #74313 - Manishearth:rollup-b55rn6t, r=Manishearth
Rollup of 8 pull requests Successful merges: - #73354 (Update RELEASES.md for 1.45.0) - #73852 (rustdoc: insert newlines between attributes) - #73867 (Document the union keyword) - #74046 (Fix caching issue when building tools.) - #74123 (clean up E0718 explanation) - #74147 (rustdoc: Allow linking from private items to private types) - #74285 (#71669: add ui, codegen tests for volatile + nearby int intrinsics) - #74286 (Added detailed error code explanation for issue E0688 in Rust compiler.) Failed merges: r? @ghost
This commit is contained in:
commit
4a689da944
18 changed files with 500 additions and 20 deletions
163
RELEASES.md
163
RELEASES.md
|
|
@ -1,3 +1,166 @@
|
|||
Version 1.45.0 (2020-07-16)
|
||||
==========================
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Out of range float to int conversions using `as` has been defined as a saturating
|
||||
conversion.][71269] This was previously undefined behaviour, but you can use the
|
||||
`{f64, f32}::to_int_unchecked` methods to continue using the current behaviour, which
|
||||
may be desirable in rare performance sensitive situations.
|
||||
- [`mem::Discriminant<T>` now uses `T`'s discriminant type instead of always
|
||||
using `u64`.][70705]
|
||||
- [Function like procedural macros can now be used in expression, pattern, and statement
|
||||
positions.][68717] This means you can now use a function-like procedural macro
|
||||
anywhere you can use a declarative (`macro_rules!`) macro.
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [You can now override individual target features through the `target-feature`
|
||||
flag.][72094] E.g. `-C target-feature=+avx2 -C target-feature=+fma` is now
|
||||
equivalent to `-C target-feature=+avx2,+fma`.
|
||||
- [Added the `force-unwind-tables` flag.][69984] This option allows
|
||||
rustc to always generate unwind tables regardless of panic strategy.
|
||||
- [Added the `embed-bitcode` flag.][71716] This codegen flag allows rustc
|
||||
to include LLVM bitcode into generated `rlib`s (this is on by default).
|
||||
- [Added the `tiny` value to the `code-model` codegen flag.][72397]
|
||||
- [Added tier 3 support\* for the `mipsel-sony-psp` target.][72062]
|
||||
- [Added tier 3 support for the `thumbv7a-uwp-windows-msvc` target.][72133]
|
||||
|
||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
||||
information on Rust's tiered platform support.
|
||||
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [`net::{SocketAddr, SocketAddrV4, SocketAddrV6}` now implements `PartialOrd`
|
||||
and `Ord`.][72239]
|
||||
- [`proc_macro::TokenStream` now implements `Default`.][72234]
|
||||
- [You can now use `char` with
|
||||
`ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo}` to iterate over
|
||||
a range of codepoints.][72413] E.g.
|
||||
you can now write the following;
|
||||
```rust
|
||||
for ch in 'a'..='z' {
|
||||
print!("{}", ch);
|
||||
}
|
||||
println!();
|
||||
// Prints "abcdefghijklmnopqrstuvwxyz"
|
||||
```
|
||||
- [`OsString` now implements `FromStr`.][71662]
|
||||
- [The `saturating_neg` method as been added to all signed integer primitive
|
||||
types, and the `saturating_abs` method has been added for all integer
|
||||
primitive types.][71886]
|
||||
- [`Arc<T>`, `Rc<T>` now implement `From<Cow<'_, T>>`, and `Box` now
|
||||
implements `From<Cow>` when `T` is `[T: Copy]`, `str`, `CStr`, `OsStr`,
|
||||
or `Path`.][71447]
|
||||
- [`Box<[T]>` now implements `From<[T; N]>`.][71095]
|
||||
- [`BitOr` and `BitOrAssign` are implemented for all `NonZero`
|
||||
integer types.][69813]
|
||||
- [The `fetch_min`, and `fetch_max` methods have been added to all atomic
|
||||
integer types.][72324]
|
||||
- [The `fetch_update` method has been added to all atomic integer types.][71843]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
- [`Arc::as_ptr`]
|
||||
- [`BTreeMap::remove_entry`]
|
||||
- [`Rc::as_ptr`]
|
||||
- [`rc::Weak::as_ptr`]
|
||||
- [`rc::Weak::from_raw`]
|
||||
- [`rc::Weak::into_raw`]
|
||||
- [`str::strip_prefix`]
|
||||
- [`str::strip_suffix`]
|
||||
- [`sync::Weak::as_ptr`]
|
||||
- [`sync::Weak::from_raw`]
|
||||
- [`sync::Weak::into_raw`]
|
||||
- [`char::UNICODE_VERSION`]
|
||||
- [`Span::resolved_at`]
|
||||
- [`Span::located_at`]
|
||||
- [`Span::mixed_site`]
|
||||
- [`unix::process::CommandExt::arg0`]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
Misc
|
||||
----
|
||||
- [Rustdoc now supports strikethrough text in Markdown.][71928] E.g.
|
||||
`~~outdated information~~` becomes "~~outdated information~~".
|
||||
- [Added an emoji to Rustdoc's deprecated API message.][72014]
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- [Trying to self initialize a static value (that is creating a value using
|
||||
itself) is unsound and now causes a compile error.][71140]
|
||||
- [`{f32, f64}::powi` now returns a slightly different value on Windows.][73420]
|
||||
This is due to changes in LLVM's intrinsics which `{f32, f64}::powi` uses.
|
||||
- [Rustdoc's CLI's extra error exit codes have been removed.][71900] These were
|
||||
previously undocumented and not intended for public use. Rustdoc still provides
|
||||
a non-zero exit code on errors.
|
||||
|
||||
Internals Only
|
||||
--------------
|
||||
- [Make clippy a git subtree instead of a git submodule][70655]
|
||||
- [Unify the undo log of all snapshot types][69464]
|
||||
|
||||
[73420]: https://github.com/rust-lang/rust/issues/73420/
|
||||
[72324]: https://github.com/rust-lang/rust/pull/72324/
|
||||
[71843]: https://github.com/rust-lang/rust/pull/71843/
|
||||
[71886]: https://github.com/rust-lang/rust/pull/71886/
|
||||
[72234]: https://github.com/rust-lang/rust/pull/72234/
|
||||
[72239]: https://github.com/rust-lang/rust/pull/72239/
|
||||
[72397]: https://github.com/rust-lang/rust/pull/72397/
|
||||
[72413]: https://github.com/rust-lang/rust/pull/72413/
|
||||
[72014]: https://github.com/rust-lang/rust/pull/72014/
|
||||
[72062]: https://github.com/rust-lang/rust/pull/72062/
|
||||
[72094]: https://github.com/rust-lang/rust/pull/72094/
|
||||
[72133]: https://github.com/rust-lang/rust/pull/72133/
|
||||
[71900]: https://github.com/rust-lang/rust/pull/71900/
|
||||
[71928]: https://github.com/rust-lang/rust/pull/71928/
|
||||
[71662]: https://github.com/rust-lang/rust/pull/71662/
|
||||
[71716]: https://github.com/rust-lang/rust/pull/71716/
|
||||
[71447]: https://github.com/rust-lang/rust/pull/71447/
|
||||
[71269]: https://github.com/rust-lang/rust/pull/71269/
|
||||
[71095]: https://github.com/rust-lang/rust/pull/71095/
|
||||
[71140]: https://github.com/rust-lang/rust/pull/71140/
|
||||
[70655]: https://github.com/rust-lang/rust/pull/70655/
|
||||
[70705]: https://github.com/rust-lang/rust/pull/70705/
|
||||
[69984]: https://github.com/rust-lang/rust/pull/69984/
|
||||
[69813]: https://github.com/rust-lang/rust/pull/69813/
|
||||
[69464]: https://github.com/rust-lang/rust/pull/69464/
|
||||
[68717]: https://github.com/rust-lang/rust/pull/68717/
|
||||
[`Arc::as_ptr`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.as_ptr
|
||||
[`BTreeMap::remove_entry`]: https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.remove_entry
|
||||
[`Rc::as_ptr`]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.as_ptr
|
||||
[`rc::Weak::as_ptr`]: https://doc.rust-lang.org/stable/std/rc/struct.Weak.html#method.as_ptr
|
||||
[`rc::Weak::from_raw`]: https://doc.rust-lang.org/stable/std/rc/struct.Weak.html#method.from_raw
|
||||
[`rc::Weak::into_raw`]: https://doc.rust-lang.org/stable/std/rc/struct.Weak.html#method.into_raw
|
||||
[`sync::Weak::as_ptr`]: https://doc.rust-lang.org/stable/std/sync/struct.Weak.html#method.as_ptr
|
||||
[`sync::Weak::from_raw`]: https://doc.rust-lang.org/stable/std/sync/struct.Weak.html#method.from_raw
|
||||
[`sync::Weak::into_raw`]: https://doc.rust-lang.org/stable/std/sync/struct.Weak.html#method.into_raw
|
||||
[`str::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.strip_prefix
|
||||
[`str::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.strip_suffix
|
||||
[`char::UNICODE_VERSION`]: https://doc.rust-lang.org/stable/std/char/constant.UNICODE_VERSION.html
|
||||
[`Span::resolved_at`]: https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.resolved_at
|
||||
[`Span::located_at`]: https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.located_at
|
||||
[`Span::mixed_site`]: https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.mixed_site
|
||||
[`unix::process::CommandExt::arg0`]: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.arg0
|
||||
|
||||
|
||||
Version 1.44.1 (2020-06-18)
|
||||
===========================
|
||||
|
||||
* [rustfmt accepts rustfmt_skip in cfg_attr again.][73078]
|
||||
* [Don't hash executable filenames on apple platforms, fixing backtraces.][cargo/8329]
|
||||
* [Fix crashes when finding backtrace on macOS.][71397]
|
||||
* [Clippy applies lint levels into different files.][clippy/5356]
|
||||
|
||||
[71397]: https://github.com/rust-lang/rust/issues/71397
|
||||
[73078]: https://github.com/rust-lang/rust/issues/73078
|
||||
[cargo/8329]: https://github.com/rust-lang/cargo/pull/8329
|
||||
[clippy/5356]: https://github.com/rust-lang/rust-clippy/issues/5356
|
||||
|
||||
|
||||
Version 1.44.0 (2020-06-04)
|
||||
==========================
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ fn main() {
|
|||
cmd.env("RUST_BACKTRACE", "1");
|
||||
}
|
||||
|
||||
if let Ok(lint_flags) = env::var("RUSTC_LINT_FLAGS") {
|
||||
cmd.args(lint_flags.split_whitespace());
|
||||
}
|
||||
|
||||
if target.is_some() {
|
||||
// The stage0 compiler has a special sysroot distinct from what we
|
||||
// actually downloaded, so we just always pass the `--sysroot` option,
|
||||
|
|
|
|||
|
|
@ -1130,22 +1130,32 @@ impl<'a> Builder<'a> {
|
|||
cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
|
||||
|
||||
if source_type == SourceType::InTree {
|
||||
let mut lint_flags = Vec::new();
|
||||
// When extending this list, add the new lints to the RUSTFLAGS of the
|
||||
// build_bootstrap function of src/bootstrap/bootstrap.py as well as
|
||||
// some code doesn't go through this `rustc` wrapper.
|
||||
rustflags.arg("-Wrust_2018_idioms");
|
||||
rustflags.arg("-Wunused_lifetimes");
|
||||
lint_flags.push("-Wrust_2018_idioms");
|
||||
lint_flags.push("-Wunused_lifetimes");
|
||||
|
||||
if self.config.deny_warnings {
|
||||
rustflags.arg("-Dwarnings");
|
||||
lint_flags.push("-Dwarnings");
|
||||
}
|
||||
|
||||
// FIXME(#58633) hide "unused attribute" errors in incremental
|
||||
// builds of the standard library, as the underlying checks are
|
||||
// not yet properly integrated with incremental recompilation.
|
||||
if mode == Mode::Std && compiler.stage == 0 && self.config.incremental {
|
||||
rustflags.arg("-Aunused-attributes");
|
||||
lint_flags.push("-Aunused-attributes");
|
||||
}
|
||||
// This does not use RUSTFLAGS due to caching issues with Cargo.
|
||||
// Clippy is treated as an "in tree" tool, but shares the same
|
||||
// cache as other "submodule" tools. With these options set in
|
||||
// RUSTFLAGS, that causes *every* shared dependency to be rebuilt.
|
||||
// By injecting this into the rustc wrapper, this circumvents
|
||||
// Cargo's fingerprint detection. This is fine because lint flags
|
||||
// are always ignored in dependencies. Eventually this should be
|
||||
// fixed via better support from Cargo.
|
||||
cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" "));
|
||||
}
|
||||
|
||||
if let Mode::Rustc | Mode::Codegen = mode {
|
||||
|
|
|
|||
|
|
@ -383,6 +383,7 @@ E0669: include_str!("./error_codes/E0669.md"),
|
|||
E0670: include_str!("./error_codes/E0670.md"),
|
||||
E0671: include_str!("./error_codes/E0671.md"),
|
||||
E0687: include_str!("./error_codes/E0687.md"),
|
||||
E0688: include_str!("./error_codes/E0688.md"),
|
||||
E0689: include_str!("./error_codes/E0689.md"),
|
||||
E0690: include_str!("./error_codes/E0690.md"),
|
||||
E0691: include_str!("./error_codes/E0691.md"),
|
||||
|
|
@ -616,7 +617,6 @@ E0768: include_str!("./error_codes/E0768.md"),
|
|||
E0640, // infer outlives requirements
|
||||
// E0645, // trait aliases not finished
|
||||
E0667, // `impl Trait` in projections
|
||||
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
|
||||
// E0694, // an unknown tool name found in scoped attributes
|
||||
// E0702, // replaced with a generic attribute input check
|
||||
// E0707, // multiple elided lifetimes used in arguments of `async fn`
|
||||
|
|
|
|||
36
src/librustc_error_codes/error_codes/E0688.md
Normal file
36
src/librustc_error_codes/error_codes/E0688.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
In-band lifetimes were mixed with explicit lifetime binders.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0688
|
||||
#![feature(in_band_lifetimes)]
|
||||
|
||||
fn foo<'a>(x: &'a u32, y: &'b u32) {} // error!
|
||||
|
||||
struct Foo<'a> { x: &'a u32 }
|
||||
|
||||
impl Foo<'a> {
|
||||
fn bar<'b>(x: &'a u32, y: &'b u32, z: &'c u32) {} // error!
|
||||
}
|
||||
|
||||
impl<'b> Foo<'a> { // error!
|
||||
fn baz() {}
|
||||
}
|
||||
```
|
||||
|
||||
In-band lifetimes cannot be mixed with explicit lifetime binders.
|
||||
For example:
|
||||
|
||||
```
|
||||
fn foo<'a, 'b>(x: &'a u32, y: &'b u32) {} // ok!
|
||||
|
||||
struct Foo<'a> { x: &'a u32 }
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn bar<'b,'c>(x: &'a u32, y: &'b u32, z: &'c u32) {} // ok!
|
||||
}
|
||||
|
||||
impl<'a> Foo<'a> { // ok!
|
||||
fn baz() {}
|
||||
}
|
||||
```
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
This error indicates that a `#[lang = ".."]` attribute was placed
|
||||
on the wrong type of item.
|
||||
A `#[lang = ".."]` attribute was placed on the wrong item type.
|
||||
|
||||
Examples of erroneous code:
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0718
|
||||
#![feature(lang_items)]
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ use std::str;
|
|||
use std::string::ToString;
|
||||
use std::sync::Arc;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::flock;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
|
|
@ -3170,15 +3171,19 @@ const ALLOWED_ATTRIBUTES: &[Symbol] = &[
|
|||
// bar: usize,
|
||||
// }
|
||||
fn render_attributes(w: &mut Buffer, it: &clean::Item, top: bool) {
|
||||
let mut attrs = String::new();
|
||||
let attrs = it
|
||||
.attrs
|
||||
.other_attrs
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
|
||||
Some(pprust::attribute_to_string(&attr))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
for attr in &it.attrs.other_attrs {
|
||||
if !ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
attrs.push_str(&pprust::attribute_to_string(&attr));
|
||||
}
|
||||
if !attrs.is_empty() {
|
||||
write!(
|
||||
w,
|
||||
|
|
|
|||
|
|
@ -799,6 +799,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
|
||||
let hir_id = self.cx.tcx.hir().as_local_hir_id(local);
|
||||
if !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_id)
|
||||
&& (item.visibility == Visibility::Public)
|
||||
&& !self.cx.render_options.document_private
|
||||
{
|
||||
let item_name = item.name.as_deref().unwrap_or("<unknown>");
|
||||
|
|
|
|||
|
|
@ -1732,8 +1732,72 @@ mod dyn_keyword {}
|
|||
//
|
||||
/// The [Rust equivalent of a C-style union][union].
|
||||
///
|
||||
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
|
||||
/// A `union` looks like a [`struct`] in terms of declaration, but all of its
|
||||
/// fields exist in the same memory, superimposed over one another. For instance,
|
||||
/// if we wanted some bits in memory that we sometimes interpret as a `u32` and
|
||||
/// sometimes as an `f32`, we could write:
|
||||
///
|
||||
/// ```rust
|
||||
/// union IntOrFloat {
|
||||
/// i: u32,
|
||||
/// f: f32,
|
||||
/// }
|
||||
///
|
||||
/// let mut u = IntOrFloat { f: 1.0 };
|
||||
/// // Reading the fields of an union is always unsafe
|
||||
/// assert_eq!(unsafe { u.i }, 1065353216);
|
||||
/// // Updating through any of the field will modify all of them
|
||||
/// u.i = 1073741824;
|
||||
/// assert_eq!(unsafe { u.f }, 2.0);
|
||||
/// ```
|
||||
///
|
||||
/// # Matching on unions
|
||||
///
|
||||
/// It is possible to use pattern matching on `union`s. A single field name must
|
||||
/// be used and it must match the name of one of the `union`'s field.
|
||||
/// Like reading from a `union`, pattern matching on a `union` requires `unsafe`.
|
||||
///
|
||||
/// ```rust
|
||||
/// union IntOrFloat {
|
||||
/// i: u32,
|
||||
/// f: f32,
|
||||
/// }
|
||||
///
|
||||
/// let u = IntOrFloat { f: 1.0 };
|
||||
///
|
||||
/// unsafe {
|
||||
/// match u {
|
||||
/// IntOrFloat { i: 10 } => println!("Found exactly ten!"),
|
||||
/// // Matching the field `f` provides an `f32`.
|
||||
/// IntOrFloat { f } => println!("Found f = {} !", f),
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # References to union fields
|
||||
///
|
||||
/// All fields in a `union` are all at the same place in memory which means
|
||||
/// borrowing one borrows the entire `union`, for the same lifetime:
|
||||
///
|
||||
/// ```rust,compile_fail,E0502
|
||||
/// union IntOrFloat {
|
||||
/// i: u32,
|
||||
/// f: f32,
|
||||
/// }
|
||||
///
|
||||
/// let mut u = IntOrFloat { f: 1.0 };
|
||||
///
|
||||
/// let f = unsafe { &u.f };
|
||||
/// // This will not compile because the field has already been borrowed, even
|
||||
/// // if only immutably
|
||||
/// let i = unsafe { &mut u.i };
|
||||
///
|
||||
/// *i = 10;
|
||||
/// println!("f = {} and i = {}", f, i);
|
||||
/// ```
|
||||
///
|
||||
/// See the [Reference][union] for more informations on `union`s.
|
||||
///
|
||||
/// [`struct`]: keyword.struct.html
|
||||
/// [union]: ../reference/items/unions.html
|
||||
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
|
||||
mod union_keyword {}
|
||||
|
|
|
|||
18
src/test/codegen/intrinsics/nearby.rs
Normal file
18
src/test/codegen/intrinsics/nearby.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics;
|
||||
|
||||
// CHECK-LABEL: @nearbyintf32
|
||||
#[no_mangle]
|
||||
pub unsafe fn nearbyintf32(a: f32) -> f32 {
|
||||
// CHECK: llvm.nearbyint.f32
|
||||
intrinsics::nearbyintf32(a)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @nearbyintf64
|
||||
#[no_mangle]
|
||||
pub unsafe fn nearbyintf64(a: f64) -> f64 {
|
||||
// CHECK: llvm.nearbyint.f64
|
||||
intrinsics::nearbyintf64(a)
|
||||
}
|
||||
55
src/test/codegen/intrinsics/volatile.rs
Normal file
55
src/test/codegen/intrinsics/volatile.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics;
|
||||
|
||||
// CHECK-LABEL: @volatile_copy_memory
|
||||
#[no_mangle]
|
||||
pub unsafe fn volatile_copy_memory(a: *mut u8, b: *const u8) {
|
||||
// CHECK: llvm.memmove.p0i8.p0i8.{{\w*(.*true)}}
|
||||
intrinsics::volatile_copy_memory(a, b, 1)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @volatile_copy_nonoverlapping_memory
|
||||
#[no_mangle]
|
||||
pub unsafe fn volatile_copy_nonoverlapping_memory(a: *mut u8, b: *const u8) {
|
||||
// CHECK: llvm.memcpy.p0i8.p0i8.{{\w*(.*true)}}
|
||||
intrinsics::volatile_copy_nonoverlapping_memory(a, b, 1)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @volatile_set_memory
|
||||
#[no_mangle]
|
||||
pub unsafe fn volatile_set_memory(a: *mut u8, b: u8) {
|
||||
// CHECK: llvm.memset.p0i8.{{\w*(.*true)}}
|
||||
intrinsics::volatile_set_memory(a, b, 1)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @volatile_load
|
||||
#[no_mangle]
|
||||
pub unsafe fn volatile_load(a: *const u8) -> u8 {
|
||||
// CHECK: load volatile
|
||||
intrinsics::volatile_load(a)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @volatile_store
|
||||
#[no_mangle]
|
||||
pub unsafe fn volatile_store(a: *mut u8, b: u8) {
|
||||
// CHECK: store volatile
|
||||
intrinsics::volatile_store(a, b)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @unaligned_volatile_load
|
||||
#[no_mangle]
|
||||
pub unsafe fn unaligned_volatile_load(a: *const u8) -> u8 {
|
||||
// CHECK: load volatile
|
||||
intrinsics::unaligned_volatile_load(a)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @unaligned_volatile_store
|
||||
#[no_mangle]
|
||||
pub unsafe fn unaligned_volatile_store(a: *mut u8, b: u8) {
|
||||
// CHECK: store volatile
|
||||
intrinsics::unaligned_volatile_store(a, b)
|
||||
}
|
||||
18
src/test/codegen/intrinsics/volatile_order.rs
Normal file
18
src/test/codegen/intrinsics/volatile_order.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::*;
|
||||
|
||||
pub unsafe fn test_volatile_order() {
|
||||
let mut a: Box<u8> = Box::new(0);
|
||||
// CHECK: load volatile
|
||||
let x = volatile_load(&*a);
|
||||
// CHECK: load volatile
|
||||
let x = volatile_load(&*a);
|
||||
// CHECK: store volatile
|
||||
volatile_store(&mut *a, 12);
|
||||
// CHECK: store volatile
|
||||
unaligned_volatile_store(&mut *a, 12);
|
||||
// CHECK: llvm.memset.p0i8
|
||||
volatile_set_memory(&mut *a, 12, 1)
|
||||
}
|
||||
10
src/test/rustdoc-ui/issue-74134.public.stderr
Normal file
10
src/test/rustdoc-ui/issue-74134.public.stderr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
warning: `[PrivateType]` public documentation for `public_item` links to a private item
|
||||
--> $DIR/issue-74134.rs:19:10
|
||||
|
|
||||
LL | /// [`PrivateType`]
|
||||
| ^^^^^^^^^^^^^ this item is private
|
||||
|
|
||||
= note: `#[warn(intra_doc_link_resolution_failure)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
41
src/test/rustdoc-ui/issue-74134.rs
Normal file
41
src/test/rustdoc-ui/issue-74134.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// revisions: public private
|
||||
// [private]compile-flags: --document-private-items
|
||||
// check-pass
|
||||
|
||||
// There are 4 cases here:
|
||||
// 1. public item -> public type: no warning
|
||||
// 2. public item -> private type: warning, if --document-private-items is not passed
|
||||
// 3. private item -> public type: no warning
|
||||
// 4. private item -> private type: no warning
|
||||
// All 4 cases are tested with and without --document-private-items.
|
||||
//
|
||||
// Case 4 without --document-private-items is the one described in issue #74134.
|
||||
|
||||
struct PrivateType;
|
||||
pub struct PublicType;
|
||||
|
||||
pub struct Public {
|
||||
/// [`PublicType`]
|
||||
/// [`PrivateType`]
|
||||
//[public]~^ WARNING public documentation for `public_item` links to a private
|
||||
pub public_item: u32,
|
||||
|
||||
/// [`PublicType`]
|
||||
/// [`PrivateType`]
|
||||
private_item: u32,
|
||||
}
|
||||
|
||||
// The following cases are identical to the ones above, except that they are in a private
|
||||
// module. Thus they all fall into cases 3 and 4 and should not produce a warning.
|
||||
|
||||
mod private {
|
||||
pub struct Public {
|
||||
/// [`super::PublicType`]
|
||||
/// [`super::PrivateType`]
|
||||
pub public_item: u32,
|
||||
|
||||
/// [`super::PublicType`]
|
||||
/// [`super::PrivateType`]
|
||||
private_item: u32,
|
||||
}
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@ pub extern "C" fn f() {}
|
|||
#[export_name = "bar"]
|
||||
pub extern "C" fn g() {}
|
||||
|
||||
// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[repr(i64)]'
|
||||
// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[must_use]'
|
||||
// @matches foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' \
|
||||
// '(?m)\A#\[repr\(i64\)\]\n#\[must_use\]\Z'
|
||||
#[repr(i64)]
|
||||
#[must_use]
|
||||
pub enum Foo {
|
||||
|
|
|
|||
|
|
@ -24,3 +24,4 @@ LL | impl<'b> Foo<'a> {
|
|||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0688`.
|
||||
|
|
|
|||
11
src/test/ui/intrinsics/intrinsic-nearby.rs
Normal file
11
src/test/ui/intrinsics/intrinsic-nearby.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// run-pass
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::*;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
assert_eq!(nearbyintf32(5.234f32), 5f32);
|
||||
assert_eq!(nearbyintf64(6.777f64), 7f64);
|
||||
}
|
||||
}
|
||||
44
src/test/ui/intrinsics/intrinsic-volatile.rs
Normal file
44
src/test/ui/intrinsics/intrinsic-volatile.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::*;
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let mut x: Box<u8> = Box::new(0);
|
||||
let mut y: Box<u8> = Box::new(0);
|
||||
|
||||
// test volatile load
|
||||
assert_eq!(volatile_load(&*x), 0);
|
||||
*x = 1;
|
||||
assert_eq!(volatile_load(&*x), 1);
|
||||
|
||||
// test volatile store
|
||||
volatile_store(&mut *x, 2);
|
||||
assert_eq!(*x, 2);
|
||||
|
||||
// test volatile copy memory
|
||||
volatile_copy_memory(&mut *y, &*x, 1);
|
||||
assert_eq!(*y, 2);
|
||||
|
||||
// test volatile copy non-overlapping memory
|
||||
*x = 3;
|
||||
volatile_copy_nonoverlapping_memory(&mut *y, &*x, 1);
|
||||
assert_eq!(*y, 3);
|
||||
|
||||
// test volatile set memory
|
||||
volatile_set_memory(&mut *x, 4, 1);
|
||||
assert_eq!(*x, 4);
|
||||
|
||||
// test unaligned volatile load
|
||||
let arr: [u8; 3] = [1, 2, 3];
|
||||
let ptr = arr[1..].as_ptr() as *const u16;
|
||||
assert_eq!(unaligned_volatile_load(ptr), u16::from_ne_bytes([arr[1], arr[2]]));
|
||||
|
||||
// test unaligned volatile store
|
||||
let ptr = arr[1..].as_ptr() as *mut u16;
|
||||
unaligned_volatile_store(ptr, 0);
|
||||
assert_eq!(arr, [1, 0, 0]);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue