mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #59226 - kennytm:rollup, r=kennytm
Rollup of 37 pull requests Successful merges: - #58854 (appveyor: Use VS2017 for all our images) - #58855 (std: Spin for a global malloc lock on wasm32) - #58873 (Fix "Auto-hide item methods documentation" setting) - #58901 (Change `std::fs::copy` to use `copyfile` on MacOS and iOS) - #58933 (Move alloc::prelude::* to alloc::prelude::v1, make alloc a subset of std) - #58938 (core: ensure VaList passes improper_ctypes lint) - #58941 (MIPS: add r6 support) - #58949 (SGX target: Expose thread id function in os module) - #58959 (Add release notes for PR #56243) - #58976 (Default to integrated `rust-lld` linker for UEFI targets) - #59009 (Fix SGX implementations of read/write_vectored.) - #59025 (Fix generic argument lookup for Self) - #59036 (Fix ICE in MIR pretty printing) - #59037 (Avoid some common false positives in intra doc link checking) - #59072 (we can now skip should_panic tests with the libtest harness) - #59079 (add suggestions to invalid macro item error) - #59082 (A few improvements to comments in user-facing crates) - #59102 (Consistent naming for duration_float methods and additional f32 methods) - #59118 (rustc: fix ICE when trait alias has bare Self) - #59139 (Unregress using scalar unions in constants.) - #59146 (Suggest return lifetime when there's only one named lifetime) - #59147 (Make std time tests more robust for platform differences) - #59152 (Stabilize Range*::contains.) - #59156 ([wg-async-await] Add regression test for #55809.) - #59158 (Revert "Don't generate minification variable if minification disabled") - #59169 (Add `-Z allow_features=...` flag) - #59173 (bootstrap: Default to a sensible llvm-suffix.) - #59175 (Don't run test launching `echo` since that doesn't exist on Windows) - #59180 (Use try blocks in rustc_codegen_ssa) - #59185 (No old chestnuts in iter::repeat docs) - #59201 (Remove restriction on isize/usize in repr(simd)) - #59204 (Output diagnostic information for rustdoc) - #59206 (Improved test output) - #59208 (Reduce a Code Repetition Related to Bit Operation) - #59212 (Add x86_64 musl host to the manifest) - #59221 (Option and Result: Add references to documentation of as_ref and as_mut) - #59231 (Stabilize Option::copied)
This commit is contained in:
commit
2c8bbf50db
@ -110,8 +110,11 @@ Compatibility Notes
|
||||
methods instead.
|
||||
- The `Error::cause` method has been deprecated in favor of `Error::source` which supports
|
||||
downcasting.
|
||||
- [Libtest no longer creates a new thread for each test when
|
||||
`--test-threads=1`. It also runs the tests in deterministic order][56243]
|
||||
|
||||
[55982]: https://github.com/rust-lang/rust/pull/55982/
|
||||
[56243]: https://github.com/rust-lang/rust/pull/56243
|
||||
[56303]: https://github.com/rust-lang/rust/pull/56303/
|
||||
[56351]: https://github.com/rust-lang/rust/pull/56351/
|
||||
[56362]: https://github.com/rust-lang/rust/pull/56362
|
||||
|
@ -1,4 +1,7 @@
|
||||
environment:
|
||||
# This is required for at least an AArch64 compiler in one image, and is also
|
||||
# going to soon be required for compiling LLVM.
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
|
||||
|
||||
# By default schannel checks revocation of certificates unlike some other SSL
|
||||
# backends, but we've historically had problems on CI where a revocation
|
||||
@ -81,7 +84,6 @@ environment:
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
DEPLOY: 1
|
||||
CI_JOB_NAME: dist-x86_64-msvc
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
|
||||
- RUST_CONFIGURE_ARGS: >
|
||||
--build=i686-pc-windows-msvc
|
||||
--target=i586-pc-windows-msvc
|
||||
|
@ -35,7 +35,7 @@ fn main() {
|
||||
.arg("--cfg")
|
||||
.arg("dox")
|
||||
.arg("--sysroot")
|
||||
.arg(sysroot)
|
||||
.arg(&sysroot)
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
|
||||
@ -72,7 +72,13 @@ fn main() {
|
||||
}
|
||||
|
||||
if verbose > 1 {
|
||||
eprintln!("rustdoc command: {:?}", cmd);
|
||||
eprintln!(
|
||||
"rustdoc command: {:?}={:?} {:?}",
|
||||
bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap(),
|
||||
cmd,
|
||||
);
|
||||
eprintln!("sysroot: {:?}", sysroot);
|
||||
eprintln!("libdir: {:?}", libdir);
|
||||
}
|
||||
|
||||
|
@ -408,11 +408,11 @@ impl<'a> Builder<'a> {
|
||||
test::RustdocJSStd,
|
||||
test::RustdocJSNotStd,
|
||||
test::RustdocTheme,
|
||||
test::RustdocUi,
|
||||
// Run bootstrap close to the end as it's unlikely to fail
|
||||
test::Bootstrap,
|
||||
// Run run-make last, since these won't pass without make on Windows
|
||||
test::RunMake,
|
||||
test::RustdocUi
|
||||
),
|
||||
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
|
||||
Kind::Doc => describe!(
|
||||
|
@ -241,6 +241,8 @@ pub struct Build {
|
||||
clippy_info: channel::GitInfo,
|
||||
miri_info: channel::GitInfo,
|
||||
rustfmt_info: channel::GitInfo,
|
||||
in_tree_llvm_info: channel::GitInfo,
|
||||
emscripten_llvm_info: channel::GitInfo,
|
||||
local_rebuild: bool,
|
||||
fail_fast: bool,
|
||||
doc_tests: DocTests,
|
||||
@ -363,6 +365,8 @@ impl Build {
|
||||
let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy"));
|
||||
let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri"));
|
||||
let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt"));
|
||||
let in_tree_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-project"));
|
||||
let emscripten_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-emscripten"));
|
||||
|
||||
let mut build = Build {
|
||||
initial_rustc: config.initial_rustc.clone(),
|
||||
@ -386,6 +390,8 @@ impl Build {
|
||||
clippy_info,
|
||||
miri_info,
|
||||
rustfmt_info,
|
||||
in_tree_llvm_info,
|
||||
emscripten_llvm_info,
|
||||
cc: HashMap::new(),
|
||||
cxx: HashMap::new(),
|
||||
ar: HashMap::new(),
|
||||
|
@ -18,6 +18,7 @@ use build_helper::output;
|
||||
use cmake;
|
||||
use cc;
|
||||
|
||||
use crate::channel;
|
||||
use crate::util::{self, exe};
|
||||
use build_helper::up_to_date;
|
||||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
@ -231,7 +232,26 @@ impl Step for Llvm {
|
||||
}
|
||||
|
||||
if let Some(ref suffix) = builder.config.llvm_version_suffix {
|
||||
cfg.define("LLVM_VERSION_SUFFIX", suffix);
|
||||
// Allow version-suffix="" to not define a version suffix at all.
|
||||
if !suffix.is_empty() {
|
||||
cfg.define("LLVM_VERSION_SUFFIX", suffix);
|
||||
}
|
||||
} else {
|
||||
let mut default_suffix = format!(
|
||||
"-rust-{}-{}",
|
||||
channel::CFG_RELEASE_NUM,
|
||||
builder.config.channel,
|
||||
);
|
||||
let llvm_info = if self.emscripten {
|
||||
&builder.emscripten_llvm_info
|
||||
} else {
|
||||
&builder.in_tree_llvm_info
|
||||
};
|
||||
if let Some(sha) = llvm_info.sha_short() {
|
||||
default_suffix.push_str("-");
|
||||
default_suffix.push_str(sha);
|
||||
}
|
||||
cfg.define("LLVM_VERSION_SUFFIX", default_suffix);
|
||||
}
|
||||
|
||||
if let Some(ref linker) = builder.config.llvm_use_linker {
|
||||
|
@ -1,19 +0,0 @@
|
||||
//! The alloc Prelude
|
||||
//!
|
||||
//! The purpose of this module is to alleviate imports of commonly-used
|
||||
//! items of the `alloc` crate by adding a glob import to the top of modules:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![allow(unused_imports)]
|
||||
//! # #![feature(alloc)]
|
||||
//! extern crate alloc;
|
||||
//! use alloc::prelude::*;
|
||||
//! ```
|
||||
|
||||
#![unstable(feature = "alloc", issue = "27783")]
|
||||
|
||||
#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned;
|
||||
#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box;
|
||||
#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt;
|
||||
#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString};
|
||||
#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec;
|
16
src/liballoc/prelude/mod.rs
Normal file
16
src/liballoc/prelude/mod.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//! The alloc Prelude
|
||||
//!
|
||||
//! The purpose of this module is to alleviate imports of commonly-used
|
||||
//! items of the `alloc` crate by adding a glob import to the top of modules:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![allow(unused_imports)]
|
||||
//! # #![feature(alloc)]
|
||||
//! #![feature(alloc_prelude)]
|
||||
//! extern crate alloc;
|
||||
//! use alloc::prelude::v1::*;
|
||||
//! ```
|
||||
|
||||
#![unstable(feature = "alloc_prelude", issue = "58935")]
|
||||
|
||||
pub mod v1;
|
11
src/liballoc/prelude/v1.rs
Normal file
11
src/liballoc/prelude/v1.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//! The first version of the prelude of `alloc` crate.
|
||||
//!
|
||||
//! See the [module-level documentation](../index.html) for more.
|
||||
|
||||
#![unstable(feature = "alloc_prelude", issue = "58935")]
|
||||
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt;
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;
|
@ -282,7 +282,7 @@ fn assert_covariance() {
|
||||
//
|
||||
// Destructors must be called exactly once per element.
|
||||
#[test]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
#[cfg(not(miri))] // Miri does not support panics nor entropy
|
||||
fn panic_safe() {
|
||||
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
|
@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_range_equal_excluded() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
map.range((Excluded(2), Excluded(2)));
|
||||
@ -234,7 +233,6 @@ fn test_range_equal_excluded() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_range_backwards_1() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
map.range((Included(3), Included(2)));
|
||||
@ -242,7 +240,6 @@ fn test_range_backwards_1() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_range_backwards_2() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
map.range((Included(3), Excluded(2)));
|
||||
@ -250,7 +247,6 @@ fn test_range_backwards_2() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_range_backwards_3() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
map.range((Excluded(3), Included(2)));
|
||||
@ -258,7 +254,6 @@ fn test_range_backwards_3() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_range_backwards_4() {
|
||||
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
|
||||
map.range((Excluded(3), Excluded(2)));
|
||||
|
@ -258,7 +258,6 @@ fn test_swap_remove() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_swap_remove_fail() {
|
||||
let mut v = vec![1];
|
||||
let _ = v.swap_remove(0);
|
||||
@ -632,7 +631,6 @@ fn test_insert() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_insert_oob() {
|
||||
let mut a = vec![1, 2, 3];
|
||||
a.insert(4, 5);
|
||||
@ -657,7 +655,6 @@ fn test_remove() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_remove_fail() {
|
||||
let mut a = vec![1];
|
||||
let _ = a.remove(0);
|
||||
@ -939,7 +936,6 @@ fn test_windowsator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_windowsator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.windows(0);
|
||||
@ -964,7 +960,6 @@ fn test_chunksator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_chunksator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.chunks(0);
|
||||
@ -989,7 +984,6 @@ fn test_chunks_exactator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_chunks_exactator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.chunks_exact(0);
|
||||
@ -1014,7 +1008,6 @@ fn test_rchunksator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_rchunksator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.rchunks(0);
|
||||
@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_rchunks_exactator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.rchunks_exact(0);
|
||||
@ -1092,7 +1084,6 @@ fn test_vec_default() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_overflow_does_not_cause_segfault() {
|
||||
let mut v = vec![];
|
||||
v.reserve_exact(!0);
|
||||
@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_overflow_does_not_cause_segfault_managed() {
|
||||
let mut v = vec![Rc::new(1)];
|
||||
v.reserve_exact(!0);
|
||||
@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mut_chunks_0() {
|
||||
let mut v = [1, 2, 3, 4];
|
||||
let _it = v.chunks_mut(0);
|
||||
@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mut_chunks_exact_0() {
|
||||
let mut v = [1, 2, 3, 4];
|
||||
let _it = v.chunks_exact_mut(0);
|
||||
@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mut_rchunks_0() {
|
||||
let mut v = [1, 2, 3, 4];
|
||||
let _it = v.rchunks_mut(0);
|
||||
@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mut_rchunks_exact_0() {
|
||||
let mut v = [1, 2, 3, 4];
|
||||
let _it = v.rchunks_exact_mut(0);
|
||||
@ -1411,7 +1397,7 @@ fn test_box_slice_clone() {
|
||||
#[test]
|
||||
#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
|
||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
#[cfg(not(miri))] // Miri does not support threads nor entropy
|
||||
fn test_box_slice_clone_panics() {
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
@ -1476,7 +1462,6 @@ fn test_copy_from_slice() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "destination and source slices have different lengths")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_copy_from_slice_dst_longer() {
|
||||
let src = [0, 1, 2, 3];
|
||||
let mut dst = [0; 5];
|
||||
@ -1485,7 +1470,6 @@ fn test_copy_from_slice_dst_longer() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "destination and source slices have different lengths")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_copy_from_slice_dst_shorter() {
|
||||
let src = [0, 1, 2, 3];
|
||||
let mut dst = [0; 3];
|
||||
@ -1605,7 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
#[cfg(not(miri))] // Miri does not support threads nor entropy
|
||||
fn panic_safe() {
|
||||
let prev = panic::take_hook();
|
||||
panic::set_hook(Box::new(move |info| {
|
||||
|
@ -7,7 +7,7 @@ fn test_le() {
|
||||
assert!("" <= "");
|
||||
assert!("" <= "foo");
|
||||
assert!("foo" <= "foo");
|
||||
assert!("foo" != "bar");
|
||||
assert_ne!("foo", "bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -351,7 +351,6 @@ mod slice_index {
|
||||
// to be used in `should_panic`)
|
||||
#[test]
|
||||
#[should_panic(expected = "out of bounds")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn assert_range_eq_can_fail_by_panic() {
|
||||
assert_range_eq!("abc", 0..5, "abc");
|
||||
}
|
||||
@ -361,7 +360,6 @@ mod slice_index {
|
||||
// to be used in `should_panic`)
|
||||
#[test]
|
||||
#[should_panic(expected = "==")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn assert_range_eq_can_fail_by_inequality() {
|
||||
assert_range_eq!("abc", 0..2, "abc");
|
||||
}
|
||||
@ -409,7 +407,6 @@ mod slice_index {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = $expect_msg)]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn index_fail() {
|
||||
let v: String = $data.into();
|
||||
let v: &str = &v;
|
||||
@ -418,7 +415,6 @@ mod slice_index {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = $expect_msg)]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn index_mut_fail() {
|
||||
let mut v: String = $data.into();
|
||||
let v: &mut str = &mut v;
|
||||
@ -514,7 +510,6 @@ mod slice_index {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_fail() {
|
||||
&"中华Việt Nam"[0..2];
|
||||
}
|
||||
@ -666,14 +661,12 @@ mod slice_index {
|
||||
// check the panic includes the prefix of the sliced string
|
||||
#[test]
|
||||
#[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_fail_truncated_1() {
|
||||
&LOREM_PARAGRAPH[..1024];
|
||||
}
|
||||
// check the truncation in the panic message
|
||||
#[test]
|
||||
#[should_panic(expected="luctus, im`[...]")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_fail_truncated_2() {
|
||||
&LOREM_PARAGRAPH[..1024];
|
||||
}
|
||||
@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_str_slice_rangetoinclusive_notok() {
|
||||
let s = "abcαβγ";
|
||||
&s[..=3];
|
||||
@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_str_slicemut_rangetoinclusive_notok() {
|
||||
let mut s = "abcαβγ".to_owned();
|
||||
let s: &mut str = &mut s;
|
||||
@ -894,7 +885,6 @@ fn test_as_bytes() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_as_bytes_fail() {
|
||||
// Don't double free. (I'm not sure if this exercises the
|
||||
// original problem code path anymore.)
|
||||
@ -984,7 +974,6 @@ fn test_split_at_mut() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_split_at_boundscheck() {
|
||||
let s = "ศไทย中华Việt Nam";
|
||||
s.split_at(1);
|
||||
|
@ -231,7 +231,6 @@ fn test_split_off_empty() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_split_off_past_end() {
|
||||
let orig = "Hello, world!";
|
||||
let mut split = String::from(orig);
|
||||
@ -240,7 +239,6 @@ fn test_split_off_past_end() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_split_off_mid_char() {
|
||||
let mut orig = String::from("山");
|
||||
orig.split_off(1);
|
||||
@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_str_truncate_split_codepoint() {
|
||||
let mut s = String::from("\u{FC}"); // ü
|
||||
s.truncate(1);
|
||||
@ -324,7 +321,6 @@ fn remove() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn remove_bad() {
|
||||
"ศ".to_string().remove(1);
|
||||
}
|
||||
@ -360,13 +356,11 @@ fn insert() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn insert_bad1() {
|
||||
"".to_string().insert(1, 't');
|
||||
}
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn insert_bad2() {
|
||||
"ệ".to_string().insert(1, 't');
|
||||
}
|
||||
@ -447,7 +441,6 @@ fn test_replace_range() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_replace_range_char_boundary() {
|
||||
let mut s = "Hello, 世界!".to_owned();
|
||||
s.replace_range(..8, "");
|
||||
@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_replace_range_out_of_bounds() {
|
||||
let mut s = String::from("12345");
|
||||
s.replace_range(5..6, "789");
|
||||
@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_replace_range_inclusive_out_of_bounds() {
|
||||
let mut s = String::from("12345");
|
||||
s.replace_range(5..=5, "789");
|
||||
|
@ -368,7 +368,6 @@ fn test_vec_truncate_drop() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_vec_truncate_fail() {
|
||||
struct BadElem(i32);
|
||||
impl Drop for BadElem {
|
||||
@ -392,7 +391,6 @@ fn test_index() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_index_out_of_bounds() {
|
||||
let vec = vec![1, 2, 3];
|
||||
let _ = vec[3];
|
||||
@ -400,7 +398,6 @@ fn test_index_out_of_bounds() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_out_of_bounds_1() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[!0..];
|
||||
@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_out_of_bounds_2() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[..6];
|
||||
@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_out_of_bounds_3() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[!0..4];
|
||||
@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_out_of_bounds_4() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[1..6];
|
||||
@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_slice_out_of_bounds_5() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[3..2];
|
||||
@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_swap_remove_empty() {
|
||||
let mut vec = Vec::<i32>::new();
|
||||
vec.swap_remove(0);
|
||||
@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_drain_out_of_bounds() {
|
||||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
v.drain(5..6);
|
||||
@ -585,7 +576,6 @@ fn test_drain_max_vec_size() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_drain_inclusive_out_of_bounds() {
|
||||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
v.drain(5..=5);
|
||||
@ -615,7 +605,6 @@ fn test_splice_inclusive_range() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_splice_out_of_bounds() {
|
||||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
let a = [10, 11, 12];
|
||||
@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_splice_inclusive_out_of_bounds() {
|
||||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
let a = [10, 11, 12];
|
||||
|
@ -108,7 +108,6 @@ fn test_index() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_index_out_of_bounds() {
|
||||
let mut deq = VecDeque::new();
|
||||
for i in 1..4 {
|
||||
|
@ -79,9 +79,9 @@ impl fmt::Debug for VaListImpl {
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
struct VaListImpl {
|
||||
stack: *mut (),
|
||||
gr_top: *mut (),
|
||||
vr_top: *mut (),
|
||||
stack: *mut c_void,
|
||||
gr_top: *mut c_void,
|
||||
vr_top: *mut c_void,
|
||||
gr_offs: i32,
|
||||
vr_offs: i32,
|
||||
}
|
||||
@ -98,8 +98,8 @@ struct VaListImpl {
|
||||
gpr: u8,
|
||||
fpr: u8,
|
||||
reserved: u16,
|
||||
overflow_arg_area: *mut (),
|
||||
reg_save_area: *mut (),
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
}
|
||||
|
||||
/// x86_64 ABI implementation of a `va_list`.
|
||||
@ -113,8 +113,8 @@ struct VaListImpl {
|
||||
struct VaListImpl {
|
||||
gp_offset: i32,
|
||||
fp_offset: i32,
|
||||
overflow_arg_area: *mut (),
|
||||
reg_save_area: *mut (),
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
}
|
||||
|
||||
/// A wrapper for a `va_list`
|
||||
|
@ -1198,7 +1198,7 @@ impl<I: Iterator> Peekable<I> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that rejects elements while `predicate` is true.
|
||||
/// An iterator that rejects elements while `predicate` returns `true`.
|
||||
///
|
||||
/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
|
||||
/// documentation for more.
|
||||
@ -1286,7 +1286,7 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
|
||||
impl<I, P> FusedIterator for SkipWhile<I, P>
|
||||
where I: FusedIterator, P: FnMut(&I::Item) -> bool {}
|
||||
|
||||
/// An iterator that only accepts elements while `predicate` is true.
|
||||
/// An iterator that only accepts elements while `predicate` returns `true`.
|
||||
///
|
||||
/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
|
||||
/// documentation for more.
|
||||
|
@ -39,8 +39,7 @@ unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
|
||||
|
||||
/// Creates a new iterator that endlessly repeats a single element.
|
||||
///
|
||||
/// The `repeat()` function repeats a single value over and over and over and
|
||||
/// over and over and 🔁.
|
||||
/// The `repeat()` function repeats a single value over and over again.
|
||||
///
|
||||
/// Infinite iterators like `repeat()` are often used with adapters like
|
||||
/// [`take`], in order to make them finite.
|
||||
@ -128,8 +127,7 @@ unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}
|
||||
/// Creates a new iterator that repeats elements of type `A` endlessly by
|
||||
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
|
||||
///
|
||||
/// The `repeat_with()` function calls the repeater over and over and over and
|
||||
/// over and over and 🔁.
|
||||
/// The `repeat_with()` function calls the repeater over and over again.
|
||||
///
|
||||
/// Infinite iterators like `repeat_with()` are often used with adapters like
|
||||
/// [`take`], in order to make them finite.
|
||||
|
@ -1111,11 +1111,12 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
|
||||
/// ```
|
||||
///
|
||||
/// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
|
||||
//
|
||||
// FIXME before stabilizing, explain how to initialize a struct field-by-field.
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
#[derive(Copy)]
|
||||
// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`.
|
||||
// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`.
|
||||
pub union MaybeUninit<T> {
|
||||
uninit: (),
|
||||
value: ManuallyDrop<T>,
|
||||
@ -1125,13 +1126,13 @@ pub union MaybeUninit<T> {
|
||||
impl<T: Copy> Clone for MaybeUninit<T> {
|
||||
#[inline(always)]
|
||||
fn clone(&self) -> Self {
|
||||
// Not calling T::clone(), we cannot know if we are initialized enough for that.
|
||||
// Not calling `T::clone()`, we cannot know if we are initialized enough for that.
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MaybeUninit<T> {
|
||||
/// Create a new `MaybeUninit<T>` initialized with the given value.
|
||||
/// Creates a new `MaybeUninit<T>` initialized with the given value.
|
||||
///
|
||||
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
|
||||
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
|
||||
@ -1239,6 +1240,7 @@ impl<T> MaybeUninit<T> {
|
||||
/// let x_vec = unsafe { &*x.as_ptr() };
|
||||
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
|
||||
/// ```
|
||||
///
|
||||
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
||||
/// until they are, it is advisable to avoid them.)
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
@ -1277,6 +1279,7 @@ impl<T> MaybeUninit<T> {
|
||||
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
|
||||
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
|
||||
/// ```
|
||||
///
|
||||
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
||||
/// until they are, it is advisable to avoid them.)
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
|
@ -326,7 +326,7 @@ pub fn algorithm_m<T: RawFloat>(f: &Big, e: i16) -> T {
|
||||
round_by_remainder(v, rem, q, z)
|
||||
}
|
||||
|
||||
/// Skip over most Algorithm M iterations by checking the bit length.
|
||||
/// Skips over most Algorithm M iterations by checking the bit length.
|
||||
fn quick_start<T: RawFloat>(u: &mut Big, v: &mut Big, k: &mut i16) {
|
||||
// The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v).
|
||||
// The estimate is off by at most 1, but always an under-estimate, so the error on log(u)
|
||||
|
@ -304,8 +304,8 @@ fn simplify(decimal: &mut Decimal) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and
|
||||
/// Algorithm M will compute while working on the given decimal.
|
||||
/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R
|
||||
/// and Algorithm M will compute while working on the given decimal.
|
||||
fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
|
||||
// We don't need to worry too much about overflow here thanks to trivial_cases() and the
|
||||
// parser, which filter out the most extreme inputs for us.
|
||||
@ -324,7 +324,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Detect obvious overflows and underflows without even looking at the decimal digits.
|
||||
/// Detects obvious overflows and underflows without even looking at the decimal digits.
|
||||
fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
|
||||
// There were zeros but they were stripped by simplify()
|
||||
if decimal.integral.is_empty() && decimal.fractional.is_empty() {
|
||||
|
@ -78,7 +78,7 @@ pub fn parse_decimal(s: &str) -> ParseResult {
|
||||
}
|
||||
}
|
||||
|
||||
/// Carve off decimal digits up to the first non-digit character.
|
||||
/// Carves off decimal digits up to the first non-digit character.
|
||||
fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) {
|
||||
let mut i = 0;
|
||||
while i < s.len() && b'0' <= s[i] && s[i] <= b'9' {
|
||||
|
@ -10,7 +10,7 @@ use num::dec2flt::rawfp::RawFloat;
|
||||
///
|
||||
/// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will
|
||||
/// round to the original value. The range is inclusive only when
|
||||
/// `inclusive` is true.
|
||||
/// `inclusive` is `true`.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Decoded {
|
||||
/// The scaled mantissa.
|
||||
|
@ -315,15 +315,15 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize,
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form
|
||||
/// with at least given number of significant digits. When `upper` is true,
|
||||
/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential
|
||||
/// form with at least the given number of significant digits. When `upper` is `true`,
|
||||
/// the exponent will be prefixed by `E`; otherwise that's `e`. The result is
|
||||
/// stored to the supplied parts array and a slice of written parts is returned.
|
||||
///
|
||||
/// `min_digits` can be less than the number of actual significant digits in `buf`;
|
||||
/// it will be ignored and full digits will be printed. It is only used to print
|
||||
/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that
|
||||
/// it will only print given digits and nothing else.
|
||||
/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that
|
||||
/// it will only print the given digits and nothing else.
|
||||
fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool,
|
||||
parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
|
||||
assert!(!buf.is_empty());
|
||||
@ -384,7 +384,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats given floating point number into the decimal form with at least
|
||||
/// Formats the given floating point number into the decimal form with at least
|
||||
/// given number of fractional digits. The result is stored to the supplied parts
|
||||
/// array while utilizing given byte buffer as a scratch. `upper` is currently
|
||||
/// unused but left for the future decision to change the case of non-finite values,
|
||||
@ -438,7 +438,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats given floating point number into the decimal form or
|
||||
/// Formats the given floating point number into the decimal form or
|
||||
/// the exponential form, depending on the resulting exponent. The result is
|
||||
/// stored to the supplied parts array while utilizing given byte buffer
|
||||
/// as a scratch. `upper` is used to determine the case of non-finite values
|
||||
@ -497,7 +497,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns rather crude approximation (upper bound) for the maximum buffer size
|
||||
/// Returns a rather crude approximation (upper bound) for the maximum buffer size
|
||||
/// calculated from the given decoded exponent.
|
||||
///
|
||||
/// The exact limit is:
|
||||
|
@ -71,7 +71,7 @@ impl fmt::Debug for RangeFull {
|
||||
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
|
||||
/// ```
|
||||
#[doc(alias = "..")]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
|
||||
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Range<Idx> {
|
||||
/// The lower bound of the range (inclusive).
|
||||
@ -95,8 +95,6 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// use std::f32;
|
||||
///
|
||||
/// assert!(!(3..5).contains(&2));
|
||||
@ -112,7 +110,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
|
||||
/// assert!(!(0.0..f32::NAN).contains(&0.5));
|
||||
/// assert!(!(f32::NAN..1.0).contains(&0.5));
|
||||
/// ```
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
#[stable(feature = "range_contains", since = "1.35.0")]
|
||||
pub fn contains<U>(&self, item: &U) -> bool
|
||||
where
|
||||
Idx: PartialOrd<U>,
|
||||
@ -175,7 +173,7 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
|
||||
///
|
||||
/// [`Iterator`]: ../iter/trait.IntoIterator.html
|
||||
#[doc(alias = "..")]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
|
||||
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct RangeFrom<Idx> {
|
||||
/// The lower bound of the range (inclusive).
|
||||
@ -196,8 +194,6 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// use std::f32;
|
||||
///
|
||||
/// assert!(!(3..).contains(&2));
|
||||
@ -208,7 +204,7 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
|
||||
/// assert!(!(0.0..).contains(&f32::NAN));
|
||||
/// assert!(!(f32::NAN..).contains(&0.5));
|
||||
/// ```
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
#[stable(feature = "range_contains", since = "1.35.0")]
|
||||
pub fn contains<U>(&self, item: &U) -> bool
|
||||
where
|
||||
Idx: PartialOrd<U>,
|
||||
@ -280,8 +276,6 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// use std::f32;
|
||||
///
|
||||
/// assert!( (..5).contains(&-1_000_000_000));
|
||||
@ -292,7 +286,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
||||
/// assert!(!(..1.0).contains(&f32::NAN));
|
||||
/// assert!(!(..f32::NAN).contains(&0.5));
|
||||
/// ```
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
#[stable(feature = "range_contains", since = "1.35.0")]
|
||||
pub fn contains<U>(&self, item: &U) -> bool
|
||||
where
|
||||
Idx: PartialOrd<U>,
|
||||
@ -329,7 +323,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
||||
/// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive
|
||||
/// ```
|
||||
#[doc(alias = "..=")]
|
||||
#[derive(Clone)] // not Copy -- see #27186
|
||||
#[derive(Clone)] // not Copy -- see #27186
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
pub struct RangeInclusive<Idx> {
|
||||
pub(crate) start: Idx,
|
||||
@ -365,7 +359,8 @@ impl<T: PartialOrd> RangeInclusiveEquality for T {
|
||||
impl<Idx: PartialEq> PartialEq for RangeInclusive<Idx> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.start == other.start && self.end == other.end
|
||||
self.start == other.start
|
||||
&& self.end == other.end
|
||||
&& RangeInclusiveEquality::canonicalized_is_empty(self)
|
||||
== RangeInclusiveEquality::canonicalized_is_empty(other)
|
||||
}
|
||||
@ -397,7 +392,11 @@ impl<Idx> RangeInclusive<Idx> {
|
||||
#[inline]
|
||||
#[rustc_promotable]
|
||||
pub const fn new(start: Idx, end: Idx) -> Self {
|
||||
Self { start, end, is_empty: None }
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
is_empty: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the lower bound of the range (inclusive).
|
||||
@ -478,8 +477,6 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// use std::f32;
|
||||
///
|
||||
/// assert!(!(3..=5).contains(&2));
|
||||
@ -496,7 +493,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
||||
/// assert!(!(0.0..=f32::NAN).contains(&0.0));
|
||||
/// assert!(!(f32::NAN..=1.0).contains(&1.0));
|
||||
/// ```
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
#[stable(feature = "range_contains", since = "1.35.0")]
|
||||
pub fn contains<U>(&self, item: &U) -> bool
|
||||
where
|
||||
Idx: PartialOrd<U>,
|
||||
@ -609,15 +606,12 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
||||
/// Returns `true` if `item` is contained in the range.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// use std::f32;
|
||||
///
|
||||
/// assert!( (..=5).contains(&-1_000_000_000));
|
||||
@ -628,7 +622,7 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
||||
/// assert!(!(..=1.0).contains(&f32::NAN));
|
||||
/// assert!(!(..=f32::NAN).contains(&0.5));
|
||||
/// ```
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
#[stable(feature = "range_contains", since = "1.35.0")]
|
||||
pub fn contains<U>(&self, item: &U) -> bool
|
||||
where
|
||||
Idx: PartialOrd<U>,
|
||||
@ -730,14 +724,11 @@ pub trait RangeBounds<T: ?Sized> {
|
||||
#[stable(feature = "collections_range", since = "1.28.0")]
|
||||
fn end_bound(&self) -> Bound<&T>;
|
||||
|
||||
|
||||
/// Returns `true` if `item` is contained in the range.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
///
|
||||
/// use std::f32;
|
||||
///
|
||||
/// assert!( (3..5).contains(&4));
|
||||
@ -747,7 +738,7 @@ pub trait RangeBounds<T: ?Sized> {
|
||||
/// assert!(!(0.0..1.0).contains(&f32::NAN));
|
||||
/// assert!(!(0.0..f32::NAN).contains(&0.5));
|
||||
/// assert!(!(f32::NAN..1.0).contains(&0.5));
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
#[stable(feature = "range_contains", since = "1.35.0")]
|
||||
fn contains<U>(&self, item: &U) -> bool
|
||||
where
|
||||
T: PartialOrd<U>,
|
||||
@ -757,9 +748,7 @@ pub trait RangeBounds<T: ?Sized> {
|
||||
Included(ref start) => *start <= item,
|
||||
Excluded(ref start) => *start < item,
|
||||
Unbounded => true,
|
||||
})
|
||||
&&
|
||||
(match self.end_bound() {
|
||||
}) && (match self.end_bound() {
|
||||
Included(ref end) => item <= *end,
|
||||
Excluded(ref end) => item < *end,
|
||||
Unbounded => true,
|
||||
@ -835,7 +824,7 @@ impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
|
||||
match *self {
|
||||
(Included(ref start), _) => Included(start),
|
||||
(Excluded(ref start), _) => Excluded(start),
|
||||
(Unbounded, _) => Unbounded,
|
||||
(Unbounded, _) => Unbounded,
|
||||
}
|
||||
}
|
||||
|
||||
@ -843,7 +832,7 @@ impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
|
||||
match *self {
|
||||
(_, Included(ref end)) => Included(end),
|
||||
(_, Excluded(ref end)) => Excluded(end),
|
||||
(_, Unbounded) => Unbounded,
|
||||
(_, Unbounded) => Unbounded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ impl<T> Option<T> {
|
||||
// Adapter for working with references
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Converts from `Option<T>` to `Option<&T>`.
|
||||
/// Converts from `&Option<T>` to `Option<&T>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -239,7 +239,7 @@ impl<T> Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts from `Option<T>` to `Option<&mut T>`.
|
||||
/// Converts from `&mut Option<T>` to `Option<&mut T>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -881,15 +881,13 @@ impl<T: Copy> Option<&T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(copied)]
|
||||
///
|
||||
/// let x = 12;
|
||||
/// let opt_x = Some(&x);
|
||||
/// assert_eq!(opt_x, Some(&12));
|
||||
/// let copied = opt_x.copied();
|
||||
/// assert_eq!(copied, Some(12));
|
||||
/// ```
|
||||
#[unstable(feature = "copied", issue = "57126")]
|
||||
#[stable(feature = "copied", since = "1.35.0")]
|
||||
pub fn copied(self) -> Option<T> {
|
||||
self.map(|&t| t)
|
||||
}
|
||||
@ -902,15 +900,13 @@ impl<T: Copy> Option<&mut T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(copied)]
|
||||
///
|
||||
/// let mut x = 12;
|
||||
/// let opt_x = Some(&mut x);
|
||||
/// assert_eq!(opt_x, Some(&mut 12));
|
||||
/// let copied = opt_x.copied();
|
||||
/// assert_eq!(copied, Some(12));
|
||||
/// ```
|
||||
#[unstable(feature = "copied", issue = "57126")]
|
||||
#[stable(feature = "copied", since = "1.35.0")]
|
||||
pub fn copied(self) -> Option<T> {
|
||||
self.map(|&mut t| t)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Types which pin data to its location in memory
|
||||
//! Types that pin data to its location in memory.
|
||||
//!
|
||||
//! It is sometimes useful to have objects that are guaranteed to not move,
|
||||
//! in the sense that their placement in memory does not change, and can thus be relied upon.
|
||||
|
@ -369,7 +369,7 @@ impl<T, E> Result<T, E> {
|
||||
// Adapter for working with references
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Converts from `Result<T, E>` to `Result<&T, &E>`.
|
||||
/// Converts from `&Result<T, E>` to `Result<&T, &E>`.
|
||||
///
|
||||
/// Produces a new `Result`, containing a reference
|
||||
/// into the original, leaving the original in place.
|
||||
@ -394,7 +394,7 @@ impl<T, E> Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts from `Result<T, E>` to `Result<&mut T, &mut E>`.
|
||||
/// Converts from `&mut Result<T, E>` to `Result<&mut T, &mut E>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -2968,7 +2968,7 @@ impl str {
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
/// elements. This is true for, e.g., [`char`], but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
@ -3143,7 +3143,7 @@ impl str {
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
/// elements. This is true for, e.g., [`char`], but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
@ -3326,7 +3326,7 @@ impl str {
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
/// elements. This is true for, e.g., [`char`], but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
@ -3402,7 +3402,7 @@ impl str {
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
/// elements. This is true for, e.g., [`char`], but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
|
@ -108,7 +108,7 @@ impl Waker {
|
||||
unsafe { (self.waker.vtable.wake)(self.waker.data) }
|
||||
}
|
||||
|
||||
/// Returns whether or not this `Waker` and other `Waker` have awaken the same task.
|
||||
/// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
|
||||
///
|
||||
/// This function works on a best-effort basis, and may return false even
|
||||
/// when the `Waker`s would awaken the same task. However, if this function
|
||||
|
@ -5,15 +5,15 @@ use std::mem::drop;
|
||||
#[test]
|
||||
fn smoketest_cell() {
|
||||
let x = Cell::new(10);
|
||||
assert!(x == Cell::new(10));
|
||||
assert!(x.get() == 10);
|
||||
assert_eq!(x, Cell::new(10));
|
||||
assert_eq!(x.get(), 10);
|
||||
x.set(20);
|
||||
assert!(x == Cell::new(20));
|
||||
assert!(x.get() == 20);
|
||||
assert_eq!(x, Cell::new(20));
|
||||
assert_eq!(x.get(), 20);
|
||||
|
||||
let y = Cell::new((30, 40));
|
||||
assert!(y == Cell::new((30, 40)));
|
||||
assert!(y.get() == (30, 40));
|
||||
assert_eq!(y, Cell::new((30, 40)));
|
||||
assert_eq!(y.get(), (30, 40));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn discard_doesnt_unborrow() {
|
||||
let x = RefCell::new(0);
|
||||
let _b = x.borrow();
|
||||
@ -350,7 +349,6 @@ fn refcell_ref_coercion() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn refcell_swap_borrows() {
|
||||
let x = RefCell::new(0);
|
||||
let _b = x.borrow();
|
||||
@ -360,7 +358,6 @@ fn refcell_swap_borrows() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn refcell_replace_borrows() {
|
||||
let x = RefCell::new(0);
|
||||
let _b = x.borrow();
|
||||
|
@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_iterator_step_by_zero() {
|
||||
let mut it = (0..).step_by(0);
|
||||
it.next();
|
||||
@ -1442,7 +1441,6 @@ fn test_rposition() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_rposition_panic() {
|
||||
let v: [(Box<_>, Box<_>); 4] =
|
||||
[(box 0, box 0), (box 0, box 0),
|
||||
|
@ -1,6 +1,5 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_update)]
|
||||
#![feature(copied)]
|
||||
#![feature(core_private_bignum)]
|
||||
#![feature(core_private_diy_float)]
|
||||
#![feature(dec2flt)]
|
||||
|
@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_from_u64_overflow() {
|
||||
Big::from_u64(0x1000000);
|
||||
}
|
||||
@ -20,14 +19,12 @@ fn test_add() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_add_overflow_1() {
|
||||
Big::from_small(1).add(&Big::from_u64(0xffffff));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_add_overflow_2() {
|
||||
Big::from_u64(0xffffff).add(&Big::from_small(1));
|
||||
}
|
||||
@ -45,7 +42,6 @@ fn test_add_small() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_add_small_overflow() {
|
||||
Big::from_u64(0xffffff).add_small(1);
|
||||
}
|
||||
@ -61,14 +57,12 @@ fn test_sub() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_sub_underflow_1() {
|
||||
Big::from_u64(0x10665).sub(&Big::from_u64(0x10666));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_sub_underflow_2() {
|
||||
Big::from_small(0).sub(&Big::from_u64(0x123456));
|
||||
}
|
||||
@ -82,7 +76,6 @@ fn test_mul_small() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_small_overflow() {
|
||||
Big::from_u64(0x800000).mul_small(2);
|
||||
}
|
||||
@ -101,14 +94,12 @@ fn test_mul_pow2() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_pow2_overflow_1() {
|
||||
Big::from_u64(0x1).mul_pow2(24);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_pow2_overflow_2() {
|
||||
Big::from_u64(0x123).mul_pow2(16);
|
||||
}
|
||||
@ -127,14 +118,12 @@ fn test_mul_pow5() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_pow5_overflow_1() {
|
||||
Big::from_small(1).mul_pow5(12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_pow5_overflow_2() {
|
||||
Big::from_small(230).mul_pow5(8);
|
||||
}
|
||||
@ -152,14 +141,12 @@ fn test_mul_digits() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_digits_overflow_1() {
|
||||
Big::from_u64(0x800000).mul_digits(&[2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_mul_digits_overflow_2() {
|
||||
Big::from_u64(0x1000).mul_digits(&[0, 0x10]);
|
||||
}
|
||||
@ -219,7 +206,6 @@ fn test_get_bit() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_get_bit_out_of_range() {
|
||||
Big::from_small(42).get_bit(24);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ mod tests {
|
||||
fn test_overflows() {
|
||||
assert!(MAX > 0);
|
||||
assert!(MIN <= 0);
|
||||
assert!(MIN + MAX + 1 == 0);
|
||||
assert_eq!(MIN + MAX + 1, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -22,22 +22,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_rem_euclid() {
|
||||
assert!((-1 as $T).rem_euclid(MIN) == MAX);
|
||||
assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_abs() {
|
||||
assert!((1 as $T).abs() == 1 as $T);
|
||||
assert!((0 as $T).abs() == 0 as $T);
|
||||
assert!((-1 as $T).abs() == 1 as $T);
|
||||
assert_eq!((1 as $T).abs(), 1 as $T);
|
||||
assert_eq!((0 as $T).abs(), 0 as $T);
|
||||
assert_eq!((-1 as $T).abs(), 1 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signum() {
|
||||
assert!((1 as $T).signum() == 1 as $T);
|
||||
assert!((0 as $T).signum() == 0 as $T);
|
||||
assert!((-0 as $T).signum() == 0 as $T);
|
||||
assert!((-1 as $T).signum() == -1 as $T);
|
||||
assert_eq!((1 as $T).signum(), 1 as $T);
|
||||
assert_eq!((0 as $T).signum(), 0 as $T);
|
||||
assert_eq!((-0 as $T).signum(), 0 as $T);
|
||||
assert_eq!((-1 as $T).signum(), -1 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -58,12 +58,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_bitwise_operators() {
|
||||
assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
|
||||
assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
|
||||
assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
|
||||
assert!(0b1110 as $T == (0b0111 as $T).shl(1));
|
||||
assert!(0b0111 as $T == (0b1110 as $T).shr(1));
|
||||
assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
|
||||
assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
|
||||
assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
|
||||
assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
|
||||
assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
|
||||
assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
|
||||
assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
|
||||
}
|
||||
|
||||
const A: $T = 0b0101100;
|
||||
@ -75,17 +75,17 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_count_ones() {
|
||||
assert!(A.count_ones() == 3);
|
||||
assert!(B.count_ones() == 2);
|
||||
assert!(C.count_ones() == 5);
|
||||
assert_eq!(A.count_ones(), 3);
|
||||
assert_eq!(B.count_ones(), 2);
|
||||
assert_eq!(C.count_ones(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_zeros() {
|
||||
let bits = mem::size_of::<$T>() * 8;
|
||||
assert!(A.count_zeros() == bits as u32 - 3);
|
||||
assert!(B.count_zeros() == bits as u32 - 2);
|
||||
assert!(C.count_zeros() == bits as u32 - 5);
|
||||
assert_eq!(A.count_zeros(), bits as u32 - 3);
|
||||
assert_eq!(B.count_zeros(), bits as u32 - 2);
|
||||
assert_eq!(C.count_zeros(), bits as u32 - 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -148,9 +148,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_signed_checked_div() {
|
||||
assert!((10 as $T).checked_div(2) == Some(5));
|
||||
assert!((5 as $T).checked_div(0) == None);
|
||||
assert!(isize::MIN.checked_div(-1) == None);
|
||||
assert_eq!((10 as $T).checked_div(2), Some(5));
|
||||
assert_eq!((5 as $T).checked_div(0), None);
|
||||
assert_eq!(isize::MIN.checked_div(-1), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -7,11 +7,11 @@ fn test_range() {
|
||||
let r = Range { start: 2, end: 10 };
|
||||
let mut count = 0;
|
||||
for (i, ri) in r.enumerate() {
|
||||
assert!(ri == i + 2);
|
||||
assert_eq!(ri, i + 2);
|
||||
assert!(ri >= 2 && ri < 10);
|
||||
count += 1;
|
||||
}
|
||||
assert!(count == 8);
|
||||
assert_eq!(count, 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -19,11 +19,11 @@ fn test_range_from() {
|
||||
let r = RangeFrom { start: 2 };
|
||||
let mut count = 0;
|
||||
for (i, ri) in r.take(10).enumerate() {
|
||||
assert!(ri == i + 2);
|
||||
assert_eq!(ri, i + 2);
|
||||
assert!(ri >= 2 && ri < 12);
|
||||
count += 1;
|
||||
}
|
||||
assert!(count == 10);
|
||||
assert_eq!(count, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -69,7 +69,6 @@ fn test_option_dance() {
|
||||
}
|
||||
|
||||
#[test] #[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_option_too_much_dance() {
|
||||
struct A;
|
||||
let mut y = Some(A);
|
||||
@ -130,7 +129,6 @@ fn test_unwrap() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_unwrap_panic1() {
|
||||
let x: Option<isize> = None;
|
||||
x.unwrap();
|
||||
@ -138,7 +136,6 @@ fn test_unwrap_panic1() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_unwrap_panic2() {
|
||||
let x: Option<String> = None;
|
||||
x.unwrap();
|
||||
|
@ -117,7 +117,6 @@ fn test_unwrap_or_else() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
pub fn test_unwrap_or_else_panic() {
|
||||
fn handler(msg: &'static str) -> isize {
|
||||
if msg == "I got this." {
|
||||
@ -139,7 +138,6 @@ pub fn test_expect_ok() {
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected="Got expected error: \"All good\"")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
pub fn test_expect_err() {
|
||||
let err: Result<isize, &'static str> = Err("All good");
|
||||
err.expect("Got expected error");
|
||||
@ -153,7 +151,6 @@ pub fn test_expect_err_err() {
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected="Got expected ok: \"All good\"")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
pub fn test_expect_err_ok() {
|
||||
let err: Result<&'static str, isize> = Ok("All good");
|
||||
err.expect_err("Got expected ok");
|
||||
|
@ -782,7 +782,6 @@ mod slice_index {
|
||||
// to be used in `should_panic`)
|
||||
#[test]
|
||||
#[should_panic(expected = "out of range")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn assert_range_eq_can_fail_by_panic() {
|
||||
assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]);
|
||||
}
|
||||
@ -792,7 +791,6 @@ mod slice_index {
|
||||
// to be used in `should_panic`)
|
||||
#[test]
|
||||
#[should_panic(expected = "==")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn assert_range_eq_can_fail_by_inequality() {
|
||||
assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]);
|
||||
}
|
||||
@ -842,7 +840,6 @@ mod slice_index {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = $expect_msg)]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn index_fail() {
|
||||
let v = $data;
|
||||
let v: &[_] = &v;
|
||||
@ -851,7 +848,6 @@ mod slice_index {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = $expect_msg)]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn index_mut_fail() {
|
||||
let mut v = $data;
|
||||
let v: &mut [_] = &mut v;
|
||||
@ -1304,7 +1300,6 @@ fn test_copy_within() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "src is out of bounds")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_copy_within_panics_src_too_long() {
|
||||
let mut bytes = *b"Hello, World!";
|
||||
// The length is only 13, so 14 is out of bounds.
|
||||
@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "dest is out of bounds")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_copy_within_panics_dest_too_long() {
|
||||
let mut bytes = *b"Hello, World!";
|
||||
// The length is only 13, so a slice of length 4 starting at index 10 is out of bounds.
|
||||
@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() {
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = "src end is before src start")]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn test_copy_within_panics_src_inverted() {
|
||||
let mut bytes = *b"Hello, World!";
|
||||
// 2 is greater than 1, so this range is invalid.
|
||||
|
@ -107,14 +107,12 @@ fn checked_sub() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn sub_bad1() {
|
||||
let _ = Duration::new(0, 0) - Duration::new(0, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[cfg(not(miri))] // Miri does not support panics
|
||||
fn sub_bad2() {
|
||||
let _ = Duration::new(0, 0) - Duration::new(1, 0);
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ const NANOS_PER_MILLI: u32 = 1_000_000;
|
||||
const NANOS_PER_MICRO: u32 = 1_000;
|
||||
const MILLIS_PER_SEC: u64 = 1_000;
|
||||
const MICROS_PER_SEC: u64 = 1_000_000;
|
||||
const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
|
||||
|
||||
/// A `Duration` type to represent a span of time, typically used for system
|
||||
/// timeouts.
|
||||
@ -510,15 +509,34 @@ impl Duration {
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// assert_eq!(dur.as_float_secs(), 2.7);
|
||||
/// assert_eq!(dur.as_secs_f64(), 2.7);
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub const fn as_float_secs(&self) -> f64 {
|
||||
pub const fn as_secs_f64(&self) -> f64 {
|
||||
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
|
||||
}
|
||||
|
||||
/// Creates a new `Duration` from the specified number of seconds.
|
||||
/// Returns the number of seconds contained by this `Duration` as `f32`.
|
||||
///
|
||||
/// The returned value does include the fractional (nanosecond) part of the duration.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(duration_float)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// assert_eq!(dur.as_secs_f32(), 2.7);
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub const fn as_secs_f32(&self) -> f32 {
|
||||
(self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
|
||||
}
|
||||
|
||||
/// Creates a new `Duration` from the specified number of seconds represented
|
||||
/// as `f64`.
|
||||
///
|
||||
/// # Panics
|
||||
/// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
|
||||
@ -528,12 +546,14 @@ impl Duration {
|
||||
/// #![feature(duration_float)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::from_float_secs(2.7);
|
||||
/// let dur = Duration::from_secs_f64(2.7);
|
||||
/// assert_eq!(dur, Duration::new(2, 700_000_000));
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn from_float_secs(secs: f64) -> Duration {
|
||||
pub fn from_secs_f64(secs: f64) -> Duration {
|
||||
const MAX_NANOS_F64: f64 =
|
||||
((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
|
||||
let nanos = secs * (NANOS_PER_SEC as f64);
|
||||
if !nanos.is_finite() {
|
||||
panic!("got non-finite value when converting float to duration");
|
||||
@ -551,6 +571,42 @@ impl Duration {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `Duration` from the specified number of seconds represented
|
||||
/// as `f32`.
|
||||
///
|
||||
/// # Panics
|
||||
/// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(duration_float)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::from_secs_f32(2.7);
|
||||
/// assert_eq!(dur, Duration::new(2, 700_000_000));
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn from_secs_f32(secs: f32) -> Duration {
|
||||
const MAX_NANOS_F32: f32 =
|
||||
((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32;
|
||||
let nanos = secs * (NANOS_PER_SEC as f32);
|
||||
if !nanos.is_finite() {
|
||||
panic!("got non-finite value when converting float to duration");
|
||||
}
|
||||
if nanos >= MAX_NANOS_F32 {
|
||||
panic!("overflow when converting float to duration");
|
||||
}
|
||||
if nanos < 0.0 {
|
||||
panic!("underflow when converting float to duration");
|
||||
}
|
||||
let nanos = nanos as u128;
|
||||
Duration {
|
||||
secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
|
||||
nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
|
||||
}
|
||||
}
|
||||
|
||||
/// Multiplies `Duration` by `f64`.
|
||||
///
|
||||
/// # Panics
|
||||
@ -568,7 +624,29 @@ impl Duration {
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn mul_f64(self, rhs: f64) -> Duration {
|
||||
Duration::from_float_secs(rhs * self.as_float_secs())
|
||||
Duration::from_secs_f64(rhs * self.as_secs_f64())
|
||||
}
|
||||
|
||||
/// Multiplies `Duration` by `f32`.
|
||||
///
|
||||
/// # Panics
|
||||
/// This method will panic if result is not finite, negative or overflows `Duration`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(duration_float)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// // note that due to rounding errors result is slightly different
|
||||
/// // from 8.478 and 847800.0
|
||||
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
|
||||
/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn mul_f32(self, rhs: f32) -> Duration {
|
||||
Duration::from_secs_f32(rhs * self.as_secs_f32())
|
||||
}
|
||||
|
||||
/// Divide `Duration` by `f64`.
|
||||
@ -589,7 +667,30 @@ impl Duration {
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn div_f64(self, rhs: f64) -> Duration {
|
||||
Duration::from_float_secs(self.as_float_secs() / rhs)
|
||||
Duration::from_secs_f64(self.as_secs_f64() / rhs)
|
||||
}
|
||||
|
||||
/// Divide `Duration` by `f32`.
|
||||
///
|
||||
/// # Panics
|
||||
/// This method will panic if result is not finite, negative or overflows `Duration`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(duration_float)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// // note that due to rounding errors result is slightly
|
||||
/// // different from 0.859_872_611
|
||||
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576));
|
||||
/// // note that truncation is used, not rounding
|
||||
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn div_f32(self, rhs: f32) -> Duration {
|
||||
Duration::from_secs_f32(self.as_secs_f32() / rhs)
|
||||
}
|
||||
|
||||
/// Divide `Duration` by `Duration` and return `f64`.
|
||||
@ -601,12 +702,29 @@ impl Duration {
|
||||
///
|
||||
/// let dur1 = Duration::new(2, 700_000_000);
|
||||
/// let dur2 = Duration::new(5, 400_000_000);
|
||||
/// assert_eq!(dur1.div_duration(dur2), 0.5);
|
||||
/// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn div_duration(self, rhs: Duration) -> f64 {
|
||||
self.as_float_secs() / rhs.as_float_secs()
|
||||
pub fn div_duration_f64(self, rhs: Duration) -> f64 {
|
||||
self.as_secs_f64() / rhs.as_secs_f64()
|
||||
}
|
||||
|
||||
/// Divide `Duration` by `Duration` and return `f32`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(duration_float)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur1 = Duration::new(2, 700_000_000);
|
||||
/// let dur2 = Duration::new(5, 400_000_000);
|
||||
/// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
|
||||
/// ```
|
||||
#[unstable(feature = "duration_float", issue = "54361")]
|
||||
#[inline]
|
||||
pub fn div_duration_f32(self, rhs: Duration) -> f32 {
|
||||
self.as_secs_f32() / rhs.as_secs_f32()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -541,7 +541,8 @@ impl<'hir> Map<'hir> {
|
||||
|
||||
pub fn ty_param_owner(&self, id: HirId) -> HirId {
|
||||
match self.get_by_hir_id(id) {
|
||||
Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id,
|
||||
Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
|
||||
Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id,
|
||||
Node::GenericParam(_) => self.get_parent_node_by_hir_id(id),
|
||||
_ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id))
|
||||
}
|
||||
@ -549,7 +550,8 @@ impl<'hir> Map<'hir> {
|
||||
|
||||
pub fn ty_param_name(&self, id: HirId) -> Name {
|
||||
match self.get_by_hir_id(id) {
|
||||
Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(),
|
||||
Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
|
||||
Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(),
|
||||
Node::GenericParam(param) => param.name.ident().name,
|
||||
_ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)),
|
||||
}
|
||||
|
@ -2299,6 +2299,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
let span = lifetime_refs[0].span;
|
||||
let mut late_depth = 0;
|
||||
let mut scope = self.scope;
|
||||
let mut lifetime_names = FxHashSet::default();
|
||||
let error = loop {
|
||||
match *scope {
|
||||
// Do not assign any resolution, it will be inferred.
|
||||
@ -2306,12 +2307,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
Scope::Root => break None,
|
||||
|
||||
Scope::Binder { s, .. } => {
|
||||
Scope::Binder { s, ref lifetimes, .. } => {
|
||||
// collect named lifetimes for suggestions
|
||||
for name in lifetimes.keys() {
|
||||
if let hir::ParamName::Plain(name) = name {
|
||||
lifetime_names.insert(*name);
|
||||
}
|
||||
}
|
||||
late_depth += 1;
|
||||
scope = s;
|
||||
}
|
||||
|
||||
Scope::Elision { ref elide, .. } => {
|
||||
Scope::Elision { ref elide, ref s, .. } => {
|
||||
let lifetime = match *elide {
|
||||
Elide::FreshLateAnon(ref counter) => {
|
||||
for lifetime_ref in lifetime_refs {
|
||||
@ -2321,7 +2328,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
Elide::Exact(l) => l.shifted(late_depth),
|
||||
Elide::Error(ref e) => break Some(e),
|
||||
Elide::Error(ref e) => {
|
||||
if let Scope::Binder { ref lifetimes, .. } = s {
|
||||
// collect named lifetimes for suggestions
|
||||
for name in lifetimes.keys() {
|
||||
if let hir::ParamName::Plain(name) = name {
|
||||
lifetime_names.insert(*name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break Some(e);
|
||||
}
|
||||
};
|
||||
for lifetime_ref in lifetime_refs {
|
||||
self.insert_lifetime(lifetime_ref, lifetime);
|
||||
@ -2344,7 +2361,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
if add_label {
|
||||
add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len());
|
||||
add_missing_lifetime_specifiers_label(
|
||||
&mut err,
|
||||
span,
|
||||
lifetime_refs.len(),
|
||||
&lifetime_names,
|
||||
self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()),
|
||||
);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
@ -2885,10 +2908,23 @@ fn add_missing_lifetime_specifiers_label(
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
count: usize,
|
||||
lifetime_names: &FxHashSet<ast::Ident>,
|
||||
snippet: Option<&str>,
|
||||
) {
|
||||
if count > 1 {
|
||||
err.span_label(span, format!("expected {} lifetime parameters", count));
|
||||
} else if let (1, Some(name), Some("&")) = (
|
||||
lifetime_names.len(),
|
||||
lifetime_names.iter().next(),
|
||||
snippet,
|
||||
) {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider using the named lifetime",
|
||||
format!("&{} ", name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_label(span, "expected lifetime parameter");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -800,6 +800,7 @@ macro_rules! options {
|
||||
pub const parse_opt_pathbuf: Option<&str> = Some("a path");
|
||||
pub const parse_list: Option<&str> = Some("a space-separated list of strings");
|
||||
pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings");
|
||||
pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings");
|
||||
pub const parse_uint: Option<&str> = Some("a number");
|
||||
pub const parse_passes: Option<&str> =
|
||||
Some("a space-separated list of passes, or `all`");
|
||||
@ -926,6 +927,18 @@ macro_rules! options {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
|
||||
-> bool {
|
||||
match v {
|
||||
Some(s) => {
|
||||
let v = s.split(',').map(|s| s.to_string()).collect();
|
||||
*slot = Some(v);
|
||||
true
|
||||
},
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool {
|
||||
match v.and_then(|s| s.parse().ok()) {
|
||||
Some(i) => { *slot = i; true },
|
||||
@ -1427,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
|
||||
"control the operation of the MergeFunctions LLVM pass, taking
|
||||
the same values as the target option of the same name"),
|
||||
allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
|
||||
"only allow the listed language features to be enabled in code (space separated)"),
|
||||
}
|
||||
|
||||
pub fn default_lib_output() -> CrateType {
|
||||
@ -3273,6 +3288,10 @@ mod tests {
|
||||
opts = reference.clone();
|
||||
opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
|
||||
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
|
||||
|
||||
opts = reference.clone();
|
||||
opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]);
|
||||
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1911,7 +1911,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
|
||||
pub fn is_machine(&self) -> bool {
|
||||
match self.sty {
|
||||
Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false,
|
||||
Int(..) | Uint(..) | Float(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#![allow(unused_attributes)]
|
||||
#![feature(libc)]
|
||||
#![feature(nll)]
|
||||
#![feature(range_contains)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(concat_idents)]
|
||||
|
@ -382,20 +382,19 @@ impl<'a> Linker for GccLinker<'a> {
|
||||
|
||||
if self.sess.target.target.options.is_like_osx {
|
||||
// Write a plain, newline-separated list of symbols
|
||||
let res = (|| -> io::Result<()> {
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = BufWriter::new(File::create(&path)?);
|
||||
for sym in self.info.exports[&crate_type].iter() {
|
||||
debug!(" _{}", sym);
|
||||
writeln!(f, "_{}", sym)?;
|
||||
}
|
||||
Ok(())
|
||||
})();
|
||||
};
|
||||
if let Err(e) = res {
|
||||
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
|
||||
}
|
||||
} else {
|
||||
// Write an LD version script
|
||||
let res = (|| -> io::Result<()> {
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = BufWriter::new(File::create(&path)?);
|
||||
writeln!(f, "{{\n global:")?;
|
||||
for sym in self.info.exports[&crate_type].iter() {
|
||||
@ -403,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||
writeln!(f, " {};", sym)?;
|
||||
}
|
||||
writeln!(f, "\n local:\n *;\n}};")?;
|
||||
Ok(())
|
||||
})();
|
||||
};
|
||||
if let Err(e) = res {
|
||||
self.sess.fatal(&format!("failed to write version script: {}", e));
|
||||
}
|
||||
@ -644,7 +642,7 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType) {
|
||||
let path = tmpdir.join("lib.def");
|
||||
let res = (|| -> io::Result<()> {
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = BufWriter::new(File::create(&path)?);
|
||||
|
||||
// Start off with the standard module name header and then go
|
||||
@ -655,8 +653,7 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||
debug!(" _{}", symbol);
|
||||
writeln!(f, " {}", symbol)?;
|
||||
}
|
||||
Ok(())
|
||||
})();
|
||||
};
|
||||
if let Err(e) = res {
|
||||
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#![feature(libc)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![allow(unused_attributes)]
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(unused_attributes)]
|
||||
#![feature(range_contains)]
|
||||
#![cfg_attr(unix, feature(libc))]
|
||||
#![feature(nll)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
@ -243,6 +243,7 @@ pub fn register_plugins<'a>(
|
||||
krate,
|
||||
&sess.parse_sess,
|
||||
sess.edition(),
|
||||
&sess.opts.debugging_opts.allow_features,
|
||||
);
|
||||
// these need to be set "early" so that expansion sees `quote` if enabled.
|
||||
sess.init_features(features);
|
||||
|
@ -114,14 +114,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
|
||||
}
|
||||
ty::Int(ity) => {
|
||||
// FIXME(49937): refactor these bit manipulations into interpret.
|
||||
let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
|
||||
let max = truncate(u128::max_value(), size);
|
||||
let bias = 1u128 << (size.bits() - 1);
|
||||
(Some((0, max, size)), bias)
|
||||
}
|
||||
ty::Uint(uty) => {
|
||||
// FIXME(49937): refactor these bit manipulations into interpret.
|
||||
let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
|
||||
let max = truncate(u128::max_value(), size);
|
||||
(Some((0, max, size)), 0)
|
||||
|
@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
|
||||
fn mplace_to_const<'tcx>(
|
||||
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
|
||||
mplace: MPlaceTy<'tcx>,
|
||||
) -> EvalResult<'tcx, ty::Const<'tcx>> {
|
||||
) -> ty::Const<'tcx> {
|
||||
let MemPlace { ptr, align, meta } = *mplace;
|
||||
// extract alloc-offset pair
|
||||
assert!(meta.is_none());
|
||||
let ptr = ptr.to_ptr()?;
|
||||
let alloc = ecx.memory.get(ptr.alloc_id)?;
|
||||
let ptr = ptr.to_ptr().unwrap();
|
||||
let alloc = ecx.memory.get(ptr.alloc_id).unwrap();
|
||||
assert!(alloc.align >= align);
|
||||
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes());
|
||||
let mut alloc = alloc.clone();
|
||||
@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>(
|
||||
// interned this? I thought that is the entire point of that `FinishStatic` stuff?
|
||||
let alloc = ecx.tcx.intern_const_alloc(alloc);
|
||||
let val = ConstValue::ByRef(ptr, alloc);
|
||||
Ok(ty::Const { val, ty: mplace.layout.ty })
|
||||
ty::Const { val, ty: mplace.layout.ty }
|
||||
}
|
||||
|
||||
fn op_to_const<'tcx>(
|
||||
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
|
||||
op: OpTy<'tcx>,
|
||||
) -> EvalResult<'tcx, ty::Const<'tcx>> {
|
||||
// We do not normalize just any data. Only scalar layout and slices.
|
||||
) -> ty::Const<'tcx> {
|
||||
// We do not normalize just any data. Only non-union scalars and slices.
|
||||
let normalize = match op.layout.abi {
|
||||
layout::Abi::Scalar(..) => true,
|
||||
layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()),
|
||||
layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
|
||||
_ => false,
|
||||
};
|
||||
@ -100,11 +100,11 @@ fn op_to_const<'tcx>(
|
||||
let val = match normalized_op {
|
||||
Ok(mplace) => return mplace_to_const(ecx, mplace),
|
||||
Err(Immediate::Scalar(x)) =>
|
||||
ConstValue::Scalar(x.not_undef()?),
|
||||
ConstValue::Scalar(x.not_undef().unwrap()),
|
||||
Err(Immediate::ScalarPair(a, b)) =>
|
||||
ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?),
|
||||
ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()),
|
||||
};
|
||||
Ok(ty::Const { val, ty: op.layout.ty })
|
||||
ty::Const { val, ty: op.layout.ty }
|
||||
}
|
||||
|
||||
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>(
|
||||
let field = ecx.operand_field(down, field.index() as u64).unwrap();
|
||||
// and finally move back to the const world, always normalizing because
|
||||
// this is not called for statics.
|
||||
op_to_const(&ecx, field).unwrap()
|
||||
op_to_const(&ecx, field)
|
||||
}
|
||||
|
||||
// this function uses `unwrap` copiously, because an already validated constant must have valid
|
||||
@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>(
|
||||
// Now that we validated, turn this into a proper constant.
|
||||
let def_id = cid.instance.def.def_id();
|
||||
if tcx.is_static(def_id).is_some() || cid.promoted.is_some() {
|
||||
mplace_to_const(&ecx, mplace)
|
||||
Ok(mplace_to_const(&ecx, mplace))
|
||||
} else {
|
||||
op_to_const(&ecx, mplace.into())
|
||||
Ok(op_to_const(&ecx, mplace.into()))
|
||||
}
|
||||
})();
|
||||
|
||||
|
@ -172,7 +172,7 @@ use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt, TypeFoldable, Const};
|
||||
use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size};
|
||||
|
||||
use rustc::mir::Field;
|
||||
use rustc::mir::interpret::{ConstValue, Scalar};
|
||||
use rustc::mir::interpret::{ConstValue, Scalar, truncate};
|
||||
use rustc::util::common::ErrorReported;
|
||||
|
||||
use syntax::attr::{SignedInt, UnsignedInt};
|
||||
@ -678,16 +678,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
]
|
||||
}
|
||||
ty::Int(ity) => {
|
||||
// FIXME(49937): refactor these bit manipulations into interpret.
|
||||
let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
|
||||
let min = 1u128 << (bits - 1);
|
||||
let max = (1u128 << (bits - 1)) - 1;
|
||||
let max = min - 1;
|
||||
vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
|
||||
}
|
||||
ty::Uint(uty) => {
|
||||
// FIXME(49937): refactor these bit manipulations into interpret.
|
||||
let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
|
||||
let max = !0u128 >> (128 - bits);
|
||||
let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size();
|
||||
let max = truncate(u128::max_value(), size);
|
||||
vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)]
|
||||
}
|
||||
_ => {
|
||||
|
@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
|
||||
#![feature(const_fn)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(range_contains)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(never_type)]
|
||||
|
@ -1,4 +1,5 @@
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::hir::def::CtorKind;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::Visitor;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
@ -596,7 +597,8 @@ fn write_mir_sig(
|
||||
trace!("write_mir_sig: {:?}", src.instance);
|
||||
let descr = tcx.describe_def(src.def_id());
|
||||
let is_function = match descr {
|
||||
Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true,
|
||||
Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) |
|
||||
Some(Def::StructCtor(_, CtorKind::Fn)) => true,
|
||||
_ => tcx.is_closure(src.def_id()),
|
||||
};
|
||||
match (descr, src.promoted) {
|
||||
|
23
src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
Normal file
23
src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
Ok(Target {
|
||||
llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
target_pointer_width: "32".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(),
|
||||
arch: "mips".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
target_env: "gnu".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
options: TargetOptions {
|
||||
cpu: "mips32r6".to_string(),
|
||||
features: "+mips32r6".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
}
|
24
src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
Normal file
24
src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
Ok(Target {
|
||||
llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "32".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(),
|
||||
arch: "mips".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
target_env: "gnu".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
|
||||
options: TargetOptions {
|
||||
cpu: "mips32r6".to_string(),
|
||||
features: "+mips32r6".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
Ok(Target {
|
||||
llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
target_pointer_width: "64".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
|
||||
arch: "mips64".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
target_env: "gnu".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
options: TargetOptions {
|
||||
// NOTE(mips64r6) matches C toolchain
|
||||
cpu: "mips64r6".to_string(),
|
||||
features: "+mips64r6".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
Ok(Target {
|
||||
llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "64".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
|
||||
arch: "mips64".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
target_env: "gnu".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
options: TargetOptions {
|
||||
// NOTE(mips64r6) matches C toolchain
|
||||
cpu: "mips64r6".to_string(),
|
||||
features: "+mips64r6".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
}
|
@ -335,6 +335,10 @@ supported_targets! {
|
||||
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
|
||||
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
|
||||
("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
|
||||
("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu),
|
||||
("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu),
|
||||
("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64),
|
||||
("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64),
|
||||
("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu),
|
||||
("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu),
|
||||
("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe),
|
||||
|
@ -59,7 +59,7 @@ pub fn opts() -> TargetOptions {
|
||||
singlethread: true,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
||||
linker: Some("lld-link".to_string()),
|
||||
linker: Some("rust-lld".to_string()),
|
||||
lld_flavor: LldFlavor::Link,
|
||||
pre_link_args,
|
||||
|
||||
|
@ -5288,6 +5288,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Some(original_span.with_lo(original_span.hi() - BytePos(1)))
|
||||
}
|
||||
|
||||
// Rewrite `SelfCtor` to `StructCtor`
|
||||
pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) {
|
||||
let tcx = self.tcx;
|
||||
if let Def::SelfCtor(impl_def_id) = def {
|
||||
let ty = self.impl_self_ty(span, impl_def_id).ty;
|
||||
let adt_def = ty.ty_adt_def();
|
||||
|
||||
match adt_def {
|
||||
Some(adt_def) if adt_def.has_ctor() => {
|
||||
let variant = adt_def.non_enum_variant();
|
||||
let def = Def::StructCtor(variant.did, variant.ctor_kind);
|
||||
(def, variant.did, tcx.type_of(variant.did))
|
||||
}
|
||||
_ => {
|
||||
let mut err = tcx.sess.struct_span_err(span,
|
||||
"the `Self` constructor can only be used with tuple or unit structs");
|
||||
if let Some(adt_def) = adt_def {
|
||||
match adt_def.adt_kind() {
|
||||
AdtKind::Enum => {
|
||||
err.help("did you mean to use one of the enum's variants?");
|
||||
},
|
||||
AdtKind::Struct |
|
||||
AdtKind::Union => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"use curly brackets",
|
||||
String::from("Self { /* fields */ }"),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
||||
(def, impl_def_id, tcx.types.err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let def_id = def.def_id();
|
||||
|
||||
// The things we are substituting into the type should not contain
|
||||
// escaping late-bound regions, and nor should the base type scheme.
|
||||
let ty = tcx.type_of(def_id);
|
||||
(def, def_id, ty)
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiates the given path, which must refer to an item with the given
|
||||
// number of type parameters and type.
|
||||
pub fn instantiate_value_path(&self,
|
||||
@ -5307,6 +5354,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let tcx = self.tcx;
|
||||
|
||||
match def {
|
||||
Def::Local(nid) | Def::Upvar(nid, ..) => {
|
||||
let hid = self.tcx.hir().node_to_hir_id(nid);
|
||||
let ty = self.local_ty(span, hid).decl_ty;
|
||||
let ty = self.normalize_associated_types_in(span, &ty);
|
||||
self.write_ty(hir_id, ty);
|
||||
return (ty, def);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let (def, def_id, ty) = self.rewrite_self_ctor(def, span);
|
||||
let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def);
|
||||
|
||||
let mut user_self_ty = None;
|
||||
@ -5368,17 +5427,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
user_self_ty = None;
|
||||
}
|
||||
|
||||
match def {
|
||||
Def::Local(nid) | Def::Upvar(nid, ..) => {
|
||||
let hid = self.tcx.hir().node_to_hir_id(nid);
|
||||
let ty = self.local_ty(span, hid).decl_ty;
|
||||
let ty = self.normalize_associated_types_in(span, &ty);
|
||||
self.write_ty(hir_id, ty);
|
||||
return (ty, def);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Now we have to compare the types that the user *actually*
|
||||
// provided against the types that were *expected*. If the user
|
||||
// did not provide any types, then we want to substitute inference
|
||||
@ -5411,53 +5459,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
tcx.generics_of(*def_id).has_self
|
||||
}).unwrap_or(false);
|
||||
|
||||
let mut new_def = def;
|
||||
let (def_id, ty) = match def {
|
||||
Def::SelfCtor(impl_def_id) => {
|
||||
let ty = self.impl_self_ty(span, impl_def_id).ty;
|
||||
let adt_def = ty.ty_adt_def();
|
||||
|
||||
match adt_def {
|
||||
Some(adt_def) if adt_def.has_ctor() => {
|
||||
let variant = adt_def.non_enum_variant();
|
||||
new_def = Def::StructCtor(variant.did, variant.ctor_kind);
|
||||
(variant.did, tcx.type_of(variant.did))
|
||||
}
|
||||
_ => {
|
||||
let mut err = tcx.sess.struct_span_err(span,
|
||||
"the `Self` constructor can only be used with tuple or unit structs");
|
||||
if let Some(adt_def) = adt_def {
|
||||
match adt_def.adt_kind() {
|
||||
AdtKind::Enum => {
|
||||
err.help("did you mean to use one of the enum's variants?");
|
||||
},
|
||||
AdtKind::Struct |
|
||||
AdtKind::Union => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"use curly brackets",
|
||||
String::from("Self { /* fields */ }"),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
||||
(impl_def_id, tcx.types.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let def_id = def.def_id();
|
||||
|
||||
// The things we are substituting into the type should not contain
|
||||
// escaping late-bound regions, and nor should the base type scheme.
|
||||
let ty = tcx.type_of(def_id);
|
||||
(def_id, ty)
|
||||
}
|
||||
};
|
||||
|
||||
let substs = AstConv::create_substs_for_generic_args(
|
||||
tcx,
|
||||
def_id,
|
||||
@ -5573,7 +5574,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
ty_substituted);
|
||||
self.write_substs(hir_id, substs);
|
||||
|
||||
(ty_substituted, new_def)
|
||||
(ty_substituted, def)
|
||||
}
|
||||
|
||||
fn check_rustc_args_require_const(&self,
|
||||
|
@ -1117,11 +1117,7 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
// with rustdoc running in parallel.
|
||||
all_indexes.sort();
|
||||
let mut w = try_err!(File::create(&dst), &dst);
|
||||
if options.enable_minification {
|
||||
try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
|
||||
} else {
|
||||
try_err!(writeln!(&mut w, "var searchIndex={{}};"), &dst);
|
||||
}
|
||||
try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
|
||||
try_err!(write_minify_replacer(&mut w,
|
||||
&format!("{}\n{}", variables.join(""), all_indexes.join("\n")),
|
||||
options.enable_minification),
|
||||
|
@ -2077,16 +2077,22 @@ if (!DOMTokenList.prototype.remove) {
|
||||
}
|
||||
|
||||
var toggle = createSimpleToggle(false);
|
||||
var hideMethodDocs = getCurrentValue("rustdoc-method-docs") !== "false";
|
||||
var pageId = getPageId();
|
||||
|
||||
var func = function(e) {
|
||||
var next = e.nextElementSibling;
|
||||
if (!next) {
|
||||
return;
|
||||
}
|
||||
if (hasClass(next, "docblock") ||
|
||||
(hasClass(next, "stability") &&
|
||||
hasClass(next.nextElementSibling, "docblock"))) {
|
||||
insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
|
||||
if (hasClass(next, "docblock") === true ||
|
||||
(hasClass(next, "stability") === true &&
|
||||
hasClass(next.nextElementSibling, "docblock") === true)) {
|
||||
var newToggle = toggle.cloneNode(true);
|
||||
insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
|
||||
if (hideMethodDocs === true && hasClass(e, "method") === true) {
|
||||
collapseDocs(newToggle, "hide", pageId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -2107,17 +2113,16 @@ if (!DOMTokenList.prototype.remove) {
|
||||
onEachLazy(document.getElementsByClassName("associatedconstant"), func);
|
||||
onEachLazy(document.getElementsByClassName("impl"), funcImpl);
|
||||
var impl_call = function() {};
|
||||
if (getCurrentValue("rustdoc-method-docs") !== "false") {
|
||||
if (hideMethodDocs === true) {
|
||||
impl_call = function(e, newToggle, pageId) {
|
||||
if (e.id.match(/^impl(?:-\d+)?$/) === null) {
|
||||
// Automatically minimize all non-inherent impls
|
||||
if (hasClass(e, "impl")) {
|
||||
if (hasClass(e, "impl") === true) {
|
||||
collapseDocs(newToggle, "hide", pageId);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
var pageId = getPageId();
|
||||
var newToggle = document.createElement("a");
|
||||
newToggle.href = "javascript:void(0)";
|
||||
newToggle.className = "collapse-toggle hidden-default collapsed";
|
||||
@ -2163,7 +2168,7 @@ if (!DOMTokenList.prototype.remove) {
|
||||
var inner_toggle = newToggle.cloneNode(true);
|
||||
inner_toggle.onclick = toggleClicked;
|
||||
e.insertBefore(inner_toggle, e.firstChild);
|
||||
impl_call(e, inner_toggle, pageId);
|
||||
impl_call(e.previousSibling, inner_toggle, pageId);
|
||||
}
|
||||
});
|
||||
|
||||
@ -2265,30 +2270,6 @@ if (!DOMTokenList.prototype.remove) {
|
||||
onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
|
||||
onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
|
||||
|
||||
// In the search display, allows to switch between tabs.
|
||||
function printTab(nb) {
|
||||
if (nb === 0 || nb === 1 || nb === 2) {
|
||||
currentTab = nb;
|
||||
}
|
||||
var nb_copy = nb;
|
||||
onEachLazy(document.getElementById("titles").childNodes, function(elem) {
|
||||
if (nb_copy === 0) {
|
||||
addClass(elem, "selected");
|
||||
} else {
|
||||
removeClass(elem, "selected");
|
||||
}
|
||||
nb_copy -= 1;
|
||||
});
|
||||
onEachLazy(document.getElementById("results").childNodes, function(elem) {
|
||||
if (nb === 0) {
|
||||
elem.style.display = "";
|
||||
} else {
|
||||
elem.style.display = "none";
|
||||
}
|
||||
nb -= 1;
|
||||
});
|
||||
}
|
||||
|
||||
function createToggleWrapper(tog) {
|
||||
var span = document.createElement("span");
|
||||
span.className = "toggle-label";
|
||||
@ -2374,6 +2355,30 @@ if (!DOMTokenList.prototype.remove) {
|
||||
};
|
||||
});
|
||||
|
||||
// In the search display, allows to switch between tabs.
|
||||
function printTab(nb) {
|
||||
if (nb === 0 || nb === 1 || nb === 2) {
|
||||
currentTab = nb;
|
||||
}
|
||||
var nb_copy = nb;
|
||||
onEachLazy(document.getElementById("titles").childNodes, function(elem) {
|
||||
if (nb_copy === 0) {
|
||||
addClass(elem, "selected");
|
||||
} else {
|
||||
removeClass(elem, "selected");
|
||||
}
|
||||
nb_copy -= 1;
|
||||
});
|
||||
onEachLazy(document.getElementById("results").childNodes, function(elem) {
|
||||
if (nb === 0) {
|
||||
elem.style.display = "";
|
||||
} else {
|
||||
elem.style.display = "none";
|
||||
}
|
||||
nb -= 1;
|
||||
});
|
||||
}
|
||||
|
||||
function putBackSearch(search_input) {
|
||||
if (search_input.value !== "") {
|
||||
addClass(main, "hidden");
|
||||
|
@ -288,6 +288,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
if ori_link.contains('/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// [] is mostly likely not supposed to be a link
|
||||
if ori_link.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let link = ori_link.replace("`", "");
|
||||
let (def, fragment) = {
|
||||
let mut kind = PathKind::Unknown;
|
||||
|
@ -19,7 +19,7 @@ use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucke
|
||||
use super::table::BucketState::{Empty, Full};
|
||||
use super::table::Fallibility::{Fallible, Infallible};
|
||||
|
||||
const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
|
||||
const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
|
||||
|
||||
/// The default behavior of HashMap implements a maximum load factor of 90.9%.
|
||||
#[derive(Clone)]
|
||||
|
@ -8,7 +8,7 @@ use super::Recover;
|
||||
use super::map::{self, HashMap, Keys, RandomState};
|
||||
|
||||
// Future Optimization (FIXME!)
|
||||
// =============================
|
||||
// ============================
|
||||
//
|
||||
// Iteration over zero sized values is a noop. There is no need
|
||||
// for `bucket.val` in the case of HashSet. I suppose we would need HKT
|
||||
|
@ -211,7 +211,7 @@ pub struct DirBuilder {
|
||||
recursive: bool,
|
||||
}
|
||||
|
||||
/// How large a buffer to pre-allocate before reading the entire file.
|
||||
/// Indicates how large a buffer to pre-allocate before reading the entire file.
|
||||
fn initial_buffer_size(file: &File) -> usize {
|
||||
// Allocate one extra byte so the buffer doesn't need to grow before the
|
||||
// final `read` call at the end of the file. Don't worry about `usize`
|
||||
@ -1581,7 +1581,8 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
|
||||
/// `O_CLOEXEC` is set for returned file descriptors.
|
||||
/// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
|
||||
/// NTFS streams are copied but only the size of the main stream is returned by
|
||||
/// this function.
|
||||
/// this function. On MacOS, this function corresponds to `copyfile` with
|
||||
/// `COPYFILE_ALL`.
|
||||
/// Note that, this [may change in the future][changes].
|
||||
///
|
||||
/// [changes]: ../io/index.html#platform-specific-behavior
|
||||
@ -2836,6 +2837,26 @@ mod tests {
|
||||
assert_eq!(check!(out_path.metadata()).len(), copied_len);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copy_file_follows_dst_symlink() {
|
||||
let tmp = tmpdir();
|
||||
if !got_symlink_permission(&tmp) { return };
|
||||
|
||||
let in_path = tmp.join("in.txt");
|
||||
let out_path = tmp.join("out.txt");
|
||||
let out_path_symlink = tmp.join("out_symlink.txt");
|
||||
|
||||
check!(fs::write(&in_path, "foo"));
|
||||
check!(fs::write(&out_path, "bar"));
|
||||
check!(symlink_file(&out_path, &out_path_symlink));
|
||||
|
||||
check!(fs::copy(&in_path, &out_path_symlink));
|
||||
|
||||
assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink());
|
||||
assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec());
|
||||
assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symlinks_work() {
|
||||
let tmpdir = tmpdir();
|
||||
|
@ -390,6 +390,28 @@ fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
|
||||
ret
|
||||
}
|
||||
|
||||
pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoVecMut<'_>]) -> Result<usize>
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> Result<usize>
|
||||
{
|
||||
let buf = bufs
|
||||
.iter_mut()
|
||||
.find(|b| !b.is_empty())
|
||||
.map_or(&mut [][..], |b| &mut **b);
|
||||
read(buf)
|
||||
}
|
||||
|
||||
pub(crate) fn default_write_vectored<F>(write: F, bufs: &[IoVec<'_>]) -> Result<usize>
|
||||
where
|
||||
F: FnOnce(&[u8]) -> Result<usize>
|
||||
{
|
||||
let buf = bufs
|
||||
.iter()
|
||||
.find(|b| !b.is_empty())
|
||||
.map_or(&[][..], |b| &**b);
|
||||
write(buf)
|
||||
}
|
||||
|
||||
/// The `Read` trait allows for reading bytes from a source.
|
||||
///
|
||||
/// Implementors of the `Read` trait are called 'readers'.
|
||||
@ -528,14 +550,11 @@ pub trait Read {
|
||||
/// written to possibly being only partially filled. This method must behave
|
||||
/// as a single call to `read` with the buffers concatenated would.
|
||||
///
|
||||
/// The default implementation simply passes the first nonempty buffer to
|
||||
/// `read`.
|
||||
/// The default implementation calls `read` with either the first nonempty
|
||||
/// buffer provided, or an empty one if none exists.
|
||||
#[unstable(feature = "iovec", issue = "58452")]
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result<usize> {
|
||||
match bufs.iter_mut().find(|b| !b.is_empty()) {
|
||||
Some(buf) => self.read(buf),
|
||||
None => Ok(0),
|
||||
}
|
||||
default_read_vectored(|b| self.read(b), bufs)
|
||||
}
|
||||
|
||||
/// Determines if this `Read`er can work with buffers of uninitialized
|
||||
@ -1107,14 +1126,11 @@ pub trait Write {
|
||||
/// read from possibly being only partially consumed. This method must
|
||||
/// behave as a call to `write` with the buffers concatenated would.
|
||||
///
|
||||
/// The default implementation simply passes the first nonempty buffer to
|
||||
/// `write`.
|
||||
/// The default implementation calls `write` with either the first nonempty
|
||||
/// buffer provided, or an empty one if none exists.
|
||||
#[unstable(feature = "iovec", issue = "58452")]
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result<usize> {
|
||||
match bufs.iter().find(|b| !b.is_empty()) {
|
||||
Some(buf) => self.write(buf),
|
||||
None => Ok(0),
|
||||
}
|
||||
default_write_vectored(|b| self.write(b), bufs)
|
||||
}
|
||||
|
||||
/// Flush this output stream, ensuring that all intermediately buffered
|
||||
|
@ -221,7 +221,7 @@
|
||||
|
||||
#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))]
|
||||
#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
feature(global_asm, range_contains, slice_index_methods,
|
||||
feature(global_asm, slice_index_methods,
|
||||
decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
|
||||
|
||||
// std is implemented with unstable features, many of which are internal
|
||||
|
@ -43,3 +43,8 @@ pub mod mem {
|
||||
}
|
||||
|
||||
pub use crate::sys::ext::{io, arch, ffi};
|
||||
|
||||
/// Functions for querying thread-related information.
|
||||
pub mod thread {
|
||||
pub use crate::sys::abi::thread::current;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
//!
|
||||
//! The [`Command`] struct is used to configure and spawn processes:
|
||||
//!
|
||||
//! ```
|
||||
//! ```no_run
|
||||
//! use std::process::Command;
|
||||
//!
|
||||
//! let output = Command::new("echo")
|
||||
|
@ -190,7 +190,7 @@ impl Condvar {
|
||||
/// // Wait for the thread to start up.
|
||||
/// let &(ref lock, ref cvar) = &*pair;
|
||||
/// let mut started = lock.lock().unwrap();
|
||||
/// // As long as the value inside the `Mutex` is false, we wait.
|
||||
/// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
|
||||
/// while !*started {
|
||||
/// started = cvar.wait(started).unwrap();
|
||||
/// }
|
||||
@ -254,7 +254,7 @@ impl Condvar {
|
||||
///
|
||||
/// // Wait for the thread to start up.
|
||||
/// let &(ref lock, ref cvar) = &*pair;
|
||||
/// // As long as the value inside the `Mutex` is false, we wait.
|
||||
/// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
|
||||
/// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap();
|
||||
/// ```
|
||||
#[unstable(feature = "wait_until", issue = "47960")]
|
||||
@ -311,7 +311,7 @@ impl Condvar {
|
||||
/// // Wait for the thread to start up.
|
||||
/// let &(ref lock, ref cvar) = &*pair;
|
||||
/// let mut started = lock.lock().unwrap();
|
||||
/// // As long as the value inside the `Mutex` is false, we wait.
|
||||
/// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
|
||||
/// loop {
|
||||
/// let result = cvar.wait_timeout_ms(started, 10).unwrap();
|
||||
/// // 10 milliseconds have passed, or maybe the value changed!
|
||||
@ -384,7 +384,7 @@ impl Condvar {
|
||||
/// // wait for the thread to start up
|
||||
/// let &(ref lock, ref cvar) = &*pair;
|
||||
/// let mut started = lock.lock().unwrap();
|
||||
/// // as long as the value inside the `Mutex` is false, we wait
|
||||
/// // as long as the value inside the `Mutex<bool>` is `false`, we wait
|
||||
/// loop {
|
||||
/// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap();
|
||||
/// // 10 milliseconds have passed, or maybe the value changed!
|
||||
@ -518,7 +518,7 @@ impl Condvar {
|
||||
/// // Wait for the thread to start up.
|
||||
/// let &(ref lock, ref cvar) = &*pair;
|
||||
/// let mut started = lock.lock().unwrap();
|
||||
/// // As long as the value inside the `Mutex` is false, we wait.
|
||||
/// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
|
||||
/// while !*started {
|
||||
/// started = cvar.wait(started).unwrap();
|
||||
/// }
|
||||
@ -558,7 +558,7 @@ impl Condvar {
|
||||
/// // Wait for the thread to start up.
|
||||
/// let &(ref lock, ref cvar) = &*pair;
|
||||
/// let mut started = lock.lock().unwrap();
|
||||
/// // As long as the value inside the `Mutex` is false, we wait.
|
||||
/// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
|
||||
/// while !*started {
|
||||
/// started = cvar.wait(started).unwrap();
|
||||
/// }
|
||||
|
@ -35,10 +35,7 @@ impl TcpStream {
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match bufs.iter_mut().find(|b| !b.is_empty()) {
|
||||
Some(buf) => self.read(buf),
|
||||
None => Ok(0),
|
||||
}
|
||||
io::default_read_vectored(|b| self.read(b), bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
@ -46,10 +43,7 @@ impl TcpStream {
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match bufs.iter().find(|b| !b.is_empty()) {
|
||||
Some(buf) => self.write(buf),
|
||||
None => Ok(0),
|
||||
}
|
||||
io::default_write_vectored(|b| self.write(b), bufs)
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> Result<Option<Error>> {
|
||||
|
@ -4,6 +4,7 @@ use fortanix_sgx_abi::Tcs;
|
||||
/// all currently running threads in the enclave, and it is guaranteed to be
|
||||
/// constant for the lifetime of the thread. More specifically for SGX, there
|
||||
/// is a one-to-one correspondence of the ID to the address of the TCS.
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub fn current() -> Tcs {
|
||||
extern "C" { fn get_tcs_addr() -> Tcs; }
|
||||
unsafe { get_tcs_addr() }
|
||||
|
@ -103,24 +103,16 @@ impl TcpStream {
|
||||
self.inner.inner.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
let buf = match buf.get_mut(0) {
|
||||
Some(buf) => buf,
|
||||
None => return Ok(0),
|
||||
};
|
||||
self.read(buf)
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
io::default_read_vectored(|b| self.read(b), bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.inner.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
let buf = match buf.get(0) {
|
||||
Some(buf) => buf,
|
||||
None => return Ok(0),
|
||||
};
|
||||
self.write(buf)
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
io::default_write_vectored(|b| self.write(b), bufs)
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
|
@ -827,7 +827,10 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
||||
Ok(PathBuf::from(OsString::from_vec(buf)))
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
#[cfg(not(any(target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "macos",
|
||||
target_os = "ios")))]
|
||||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
use crate::fs::File;
|
||||
if !from.is_file() {
|
||||
@ -937,3 +940,85 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
writer.set_permissions(perm)?;
|
||||
Ok(written)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
const COPYFILE_ACL: u32 = 1 << 0;
|
||||
const COPYFILE_STAT: u32 = 1 << 1;
|
||||
const COPYFILE_XATTR: u32 = 1 << 2;
|
||||
const COPYFILE_DATA: u32 = 1 << 3;
|
||||
|
||||
const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL;
|
||||
const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR;
|
||||
const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA;
|
||||
|
||||
const COPYFILE_STATE_COPIED: u32 = 8;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type copyfile_state_t = *mut libc::c_void;
|
||||
#[allow(non_camel_case_types)]
|
||||
type copyfile_flags_t = u32;
|
||||
|
||||
extern "C" {
|
||||
fn copyfile(
|
||||
from: *const libc::c_char,
|
||||
to: *const libc::c_char,
|
||||
state: copyfile_state_t,
|
||||
flags: copyfile_flags_t,
|
||||
) -> libc::c_int;
|
||||
fn copyfile_state_alloc() -> copyfile_state_t;
|
||||
fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int;
|
||||
fn copyfile_state_get(
|
||||
state: copyfile_state_t,
|
||||
flag: u32,
|
||||
dst: *mut libc::c_void,
|
||||
) -> libc::c_int;
|
||||
}
|
||||
|
||||
struct FreeOnDrop(copyfile_state_t);
|
||||
impl Drop for FreeOnDrop {
|
||||
fn drop(&mut self) {
|
||||
// The code below ensures that `FreeOnDrop` is never a null pointer
|
||||
unsafe {
|
||||
// `copyfile_state_free` returns -1 if the `to` or `from` files
|
||||
// cannot be closed. However, this is not considerd this an
|
||||
// error.
|
||||
copyfile_state_free(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !from.is_file() {
|
||||
return Err(Error::new(ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file"))
|
||||
}
|
||||
|
||||
// We ensure that `FreeOnDrop` never contains a null pointer so it is
|
||||
// always safe to call `copyfile_state_free`
|
||||
let state = unsafe {
|
||||
let state = copyfile_state_alloc();
|
||||
if state.is_null() {
|
||||
return Err(crate::io::Error::last_os_error());
|
||||
}
|
||||
FreeOnDrop(state)
|
||||
};
|
||||
|
||||
cvt(unsafe {
|
||||
copyfile(
|
||||
cstr(from)?.as_ptr(),
|
||||
cstr(to)?.as_ptr(),
|
||||
state.0,
|
||||
COPYFILE_ALL,
|
||||
)
|
||||
})?;
|
||||
|
||||
let mut bytes_copied: libc::off_t = 0;
|
||||
cvt(unsafe {
|
||||
copyfile_state_get(
|
||||
state.0,
|
||||
COPYFILE_STATE_COPIED,
|
||||
&mut bytes_copied as *mut libc::off_t as *mut libc::c_void,
|
||||
)
|
||||
})?;
|
||||
Ok(bytes_copied as u64)
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ unsafe impl GlobalAlloc for System {
|
||||
|
||||
#[cfg(target_feature = "atomics")]
|
||||
mod lock {
|
||||
use crate::arch::wasm32;
|
||||
use crate::sync::atomic::{AtomicI32, Ordering::SeqCst};
|
||||
|
||||
static LOCKED: AtomicI32 = AtomicI32::new(0);
|
||||
@ -61,14 +60,76 @@ mod lock {
|
||||
if LOCKED.swap(1, SeqCst) == 0 {
|
||||
return DropLock
|
||||
}
|
||||
unsafe {
|
||||
let r = wasm32::i32_atomic_wait(
|
||||
&LOCKED as *const AtomicI32 as *mut i32,
|
||||
1, // expected value
|
||||
-1, // timeout
|
||||
);
|
||||
debug_assert!(r == 0 || r == 1);
|
||||
}
|
||||
// Ok so here's where things get a little depressing. At this point
|
||||
// in time we need to synchronously acquire a lock, but we're
|
||||
// contending with some other thread. Typically we'd execute some
|
||||
// form of `i32.atomic.wait` like so:
|
||||
//
|
||||
// unsafe {
|
||||
// let r = core::arch::wasm32::i32_atomic_wait(
|
||||
// &LOCKED as *const AtomicI32 as *mut i32,
|
||||
// 1, // expected value
|
||||
// -1, // timeout
|
||||
// );
|
||||
// debug_assert!(r == 0 || r == 1);
|
||||
// }
|
||||
//
|
||||
// Unfortunately though in doing so we would cause issues for the
|
||||
// main thread. The main thread in a web browser *cannot ever
|
||||
// block*, no exceptions. This means that the main thread can't
|
||||
// actually execute the `i32.atomic.wait` instruction.
|
||||
//
|
||||
// As a result if we want to work within the context of browsers we
|
||||
// need to figure out some sort of allocation scheme for the main
|
||||
// thread where when there's contention on the global malloc lock we
|
||||
// do... something.
|
||||
//
|
||||
// Possible ideas include:
|
||||
//
|
||||
// 1. Attempt to acquire the global lock. If it fails, fall back to
|
||||
// memory allocation via `memory.grow`. Later just ... somehow
|
||||
// ... inject this raw page back into the main allocator as it
|
||||
// gets sliced up over time. This strategy has the downside of
|
||||
// forcing allocation of a page to happen whenever the main
|
||||
// thread contents with other threads, which is unfortunate.
|
||||
//
|
||||
// 2. Maintain a form of "two level" allocator scheme where the main
|
||||
// thread has its own allocator. Somehow this allocator would
|
||||
// also be balanced with a global allocator, not only to have
|
||||
// allocations cross between threads but also to ensure that the
|
||||
// two allocators stay "balanced" in terms of free'd memory and
|
||||
// such. This, however, seems significantly complicated.
|
||||
//
|
||||
// Out of a lack of other ideas, the current strategy implemented
|
||||
// here is to simply spin. Typical spin loop algorithms have some
|
||||
// form of "hint" here to the CPU that it's what we're doing to
|
||||
// ensure that the CPU doesn't get too hot, but wasm doesn't have
|
||||
// such an instruction.
|
||||
//
|
||||
// To be clear, spinning here is not a great solution.
|
||||
// Another thread with the lock may take quite a long time to wake
|
||||
// up. For example it could be in `memory.grow` or it could be
|
||||
// evicted from the CPU for a timeslice like 10ms. For these periods
|
||||
// of time our thread will "helpfully" sit here and eat CPU time
|
||||
// until it itself is evicted or the lock holder finishes. This
|
||||
// means we're just burning and wasting CPU time to no one's
|
||||
// benefit.
|
||||
//
|
||||
// Spinning does have the nice properties, though, of being
|
||||
// semantically correct, being fair to all threads for memory
|
||||
// allocation, and being simple enough to implement.
|
||||
//
|
||||
// This will surely (hopefully) be replaced in the future with a
|
||||
// real memory allocator that can handle the restriction of the main
|
||||
// thread.
|
||||
//
|
||||
//
|
||||
// FIXME: We can also possibly add an optimization here to detect
|
||||
// when a thread is the main thread or not and block on all
|
||||
// non-main-thread threads. Currently, however, we have no way
|
||||
// of knowing which wasm thread is on the browser main thread, but
|
||||
// if we could figure out we could at least somewhat mitigate the
|
||||
// cost of this spinning.
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,12 +137,16 @@ mod lock {
|
||||
fn drop(&mut self) {
|
||||
let r = LOCKED.swap(0, SeqCst);
|
||||
debug_assert_eq!(r, 1);
|
||||
unsafe {
|
||||
wasm32::atomic_notify(
|
||||
&LOCKED as *const AtomicI32 as *mut i32,
|
||||
1, // only one thread
|
||||
);
|
||||
}
|
||||
|
||||
// Note that due to the above logic we don't actually need to wake
|
||||
// anyone up, but if we did it'd likely look something like this:
|
||||
//
|
||||
// unsafe {
|
||||
// core::arch::wasm32::atomic_notify(
|
||||
// &LOCKED as *const AtomicI32 as *mut i32,
|
||||
// 1, // only one thread
|
||||
// );
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ pub struct Pipes {
|
||||
///
|
||||
/// The ours/theirs pipes are *not* specifically readable or writable. Each
|
||||
/// one only supports a read or a write, but which is which depends on the
|
||||
/// boolean flag given. If `ours_readable` is true then `ours` is readable where
|
||||
/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is
|
||||
/// writable where `theirs` is readable.
|
||||
/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and
|
||||
/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours`
|
||||
/// is writable and `theirs` is readable.
|
||||
///
|
||||
/// Also note that the `ours` pipe is always a handle opened up in overlapped
|
||||
/// mode. This means that technically speaking it should only ever be used
|
||||
|
@ -712,13 +712,6 @@ mod tests {
|
||||
assert_almost_eq!(a - second + second, a);
|
||||
assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
|
||||
|
||||
// A difference of 80 and 800 years cannot fit inside a 32-bit time_t
|
||||
if !(cfg!(unix) && crate::mem::size_of::<libc::time_t>() <= 4) {
|
||||
let eighty_years = second * 60 * 60 * 24 * 365 * 80;
|
||||
assert_almost_eq!(a - eighty_years + eighty_years, a);
|
||||
assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
|
||||
}
|
||||
|
||||
let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
|
||||
let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000)
|
||||
+ Duration::new(0, 500_000_000);
|
||||
@ -747,8 +740,8 @@ mod tests {
|
||||
#[test]
|
||||
fn since_epoch() {
|
||||
let ts = SystemTime::now();
|
||||
let a = ts.duration_since(UNIX_EPOCH).unwrap();
|
||||
let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
|
||||
let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap();
|
||||
let b = ts.duration_since(UNIX_EPOCH).unwrap();
|
||||
assert!(b > a);
|
||||
assert_eq!(b - a, Duration::new(1, 0));
|
||||
|
||||
|
@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> {
|
||||
}
|
||||
|
||||
// `cfg_attr`-process the crate's attributes and compute the crate's features.
|
||||
pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
|
||||
-> (ast::Crate, Features) {
|
||||
pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
|
||||
allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
|
||||
let features;
|
||||
{
|
||||
let mut strip_unconfigured = StripUnconfigured {
|
||||
@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
|
||||
return (krate, Features::new());
|
||||
}
|
||||
|
||||
features = get_features(&sess.span_diagnostic, &krate.attrs, edition);
|
||||
features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features);
|
||||
|
||||
// Avoid reconfiguring malformed `cfg_attr`s
|
||||
if err_count == sess.span_diagnostic.err_count() {
|
||||
|
@ -378,6 +378,21 @@ Erroneous code example:
|
||||
|
||||
"##,
|
||||
|
||||
E0725: r##"
|
||||
A feature attribute named a feature that was disallowed in the compiler
|
||||
command line flags.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```ignore (can't specify compiler flags from doctests)
|
||||
#![feature(never_type)] // error: the feature `never_type` is not in
|
||||
// the list of allowed features
|
||||
```
|
||||
|
||||
Delete the offending feature attribute, or add it to the list of allowed
|
||||
features in the `-Z allow_features` flag.
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
|
@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
crate_edition: Edition) -> Features {
|
||||
crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
|
||||
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
|
||||
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
|
||||
if let Some(reason) = reason {
|
||||
@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
}
|
||||
|
||||
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
|
||||
if let Some(allowed) = allow_features.as_ref() {
|
||||
if allowed.iter().find(|f| *f == name.as_str()).is_none() {
|
||||
span_err!(span_handler, mi.span, E0725,
|
||||
"the feature `{}` is not in the list of allowed features",
|
||||
name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
set(&mut features, mi.span);
|
||||
features.declared_lang_features.push((name, mi.span, None));
|
||||
continue
|
||||
|
@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let ident = self.parse_ident()?;
|
||||
let (delim, tokens) = self.expect_delimited_token_tree()?;
|
||||
if delim != MacDelimiter::Brace {
|
||||
if !self.eat(&token::Semi) {
|
||||
let msg = "macros that expand to items must either \
|
||||
be surrounded with braces or followed by a semicolon";
|
||||
self.span_err(self.prev_span, msg);
|
||||
}
|
||||
if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
|
||||
self.report_invalid_macro_expansion_item();
|
||||
}
|
||||
|
||||
(ident, ast::MacroDef { tokens: tokens, legacy: true })
|
||||
@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> {
|
||||
// if it has a special ident, it's definitely an item
|
||||
//
|
||||
// Require a semicolon or braces.
|
||||
if style != MacStmtStyle::Braces {
|
||||
if !self.eat(&token::Semi) {
|
||||
self.span_err(self.prev_span,
|
||||
"macros that expand to items must \
|
||||
either be surrounded with braces or \
|
||||
followed by a semicolon");
|
||||
}
|
||||
if style != MacStmtStyle::Braces && !self.eat(&token::Semi) {
|
||||
self.report_invalid_macro_expansion_item();
|
||||
}
|
||||
let span = lo.to(hi);
|
||||
Stmt {
|
||||
@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
// eat a matched-delimiter token tree:
|
||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||
if delim != MacDelimiter::Brace {
|
||||
if !self.eat(&token::Semi) {
|
||||
self.span_err(self.prev_span,
|
||||
"macros that expand to items must either \
|
||||
be surrounded with braces or followed by \
|
||||
a semicolon");
|
||||
}
|
||||
if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
|
||||
self.report_invalid_macro_expansion_item();
|
||||
}
|
||||
|
||||
let hi = self.prev_span;
|
||||
@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_invalid_macro_expansion_item(&self) {
|
||||
self.struct_span_err(
|
||||
self.prev_span,
|
||||
"macros that expand to items must be delimited with braces or followed by a semicolon",
|
||||
).multipart_suggestion(
|
||||
"change the delimiters to curly braces",
|
||||
vec![
|
||||
(self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
|
||||
(self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
).span_suggestion(
|
||||
self.sess.source_map.next_point(self.prev_span),
|
||||
"add a semicolon",
|
||||
';'.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
).emit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 38ad31bde8ff681d862dc0f96930a5dd9b7a472e
|
||||
Subproject commit 4fc9fb8245abe24680192535870c4522644a4212
|
@ -7,11 +7,18 @@ impl A {
|
||||
const ASSOCIATED_CONSTANT: i32 = 2;
|
||||
}
|
||||
|
||||
// See #59021
|
||||
enum Test {
|
||||
X(usize),
|
||||
Y { a: usize },
|
||||
}
|
||||
|
||||
enum E {
|
||||
V = 5,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f = Test::X as fn(usize) -> Test;
|
||||
let v = Vec::<i32>::new();
|
||||
}
|
||||
|
||||
@ -64,3 +71,14 @@ fn main() {
|
||||
// _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5];
|
||||
// }
|
||||
// END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
|
||||
|
||||
// START rustc.Test-X.mir_map.0.mir
|
||||
// fn Test::X(_1: usize) -> Test {
|
||||
// let mut _0: Test;
|
||||
//
|
||||
// bb0: {
|
||||
// _0 = Test::X(move _1,);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// END rustc.Test-X.mir_map.0.mir
|
||||
|
@ -14,7 +14,7 @@ pub fn main() {
|
||||
|
||||
let z : &str = "thing";
|
||||
assert_eq!(v, x);
|
||||
assert!(x != z);
|
||||
assert_ne!(x, z);
|
||||
|
||||
let a = "aaaa";
|
||||
let b = "bbbb";
|
||||
@ -26,7 +26,7 @@ pub fn main() {
|
||||
|
||||
assert!(a < b);
|
||||
assert!(a <= b);
|
||||
assert!(a != b);
|
||||
assert_ne!(a, b);
|
||||
assert!(b >= a);
|
||||
assert!(b > a);
|
||||
|
||||
@ -34,7 +34,7 @@ pub fn main() {
|
||||
|
||||
assert!(a < c);
|
||||
assert!(a <= c);
|
||||
assert!(a != c);
|
||||
assert_ne!(a, c);
|
||||
assert!(c >= a);
|
||||
assert!(c > a);
|
||||
|
||||
@ -42,7 +42,7 @@ pub fn main() {
|
||||
|
||||
assert!(c < cc);
|
||||
assert!(c <= cc);
|
||||
assert!(c != cc);
|
||||
assert_ne!(c, cc);
|
||||
assert!(cc >= c);
|
||||
assert!(cc > c);
|
||||
|
||||
|
30
src/test/run-pass/issue-55809.rs
Normal file
30
src/test/run-pass/issue-55809.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// edition:2018
|
||||
// run-pass
|
||||
|
||||
#![feature(async_await, await_macro, futures_api)]
|
||||
|
||||
trait Foo { }
|
||||
|
||||
impl Foo for () { }
|
||||
|
||||
impl<'a, T> Foo for &'a mut T where T: Foo { }
|
||||
|
||||
async fn foo_async<T>(_v: T) -> u8 where T: Foo {
|
||||
0
|
||||
}
|
||||
|
||||
async fn bad<T>(v: T) -> u8 where T: Foo {
|
||||
await!(foo_async(v))
|
||||
}
|
||||
|
||||
async fn async_main() {
|
||||
let mut v = ();
|
||||
|
||||
let _ = await!(bad(&mut v));
|
||||
let _ = await!(foo_async(&mut v));
|
||||
let _ = await!(bad(v));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = async_main();
|
||||
}
|
9
src/test/run-pass/issues/issue-57924.rs
Normal file
9
src/test/run-pass/issues/issue-57924.rs
Normal file
@ -0,0 +1,9 @@
|
||||
pub struct Gcm<E>(E);
|
||||
|
||||
impl<E> Gcm<E> {
|
||||
pub fn crash(e: E) -> Self {
|
||||
Self::<E>(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -37,6 +37,22 @@ fn main() {
|
||||
check::<f32x6>();
|
||||
check::<f32x7>();
|
||||
check::<f32x8>();
|
||||
|
||||
check::<usizex2>();
|
||||
check::<usizex3>();
|
||||
check::<usizex4>();
|
||||
check::<usizex5>();
|
||||
check::<usizex6>();
|
||||
check::<usizex7>();
|
||||
check::<usizex8>();
|
||||
|
||||
check::<isizex2>();
|
||||
check::<isizex3>();
|
||||
check::<isizex4>();
|
||||
check::<isizex5>();
|
||||
check::<isizex6>();
|
||||
check::<isizex7>();
|
||||
check::<isizex8>();
|
||||
}
|
||||
|
||||
#[repr(simd)] struct u8x2(u8, u8);
|
||||
@ -62,3 +78,19 @@ fn main() {
|
||||
#[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32);
|
||||
#[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32);
|
||||
#[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
|
||||
|
||||
#[repr(simd)] struct usizex2(usize, usize);
|
||||
#[repr(simd)] struct usizex3(usize, usize, usize);
|
||||
#[repr(simd)] struct usizex4(usize, usize, usize, usize);
|
||||
#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize);
|
||||
#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize);
|
||||
#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize);
|
||||
#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize);
|
||||
|
||||
#[repr(simd)] struct isizex2(isize, isize);
|
||||
#[repr(simd)] struct isizex3(isize, isize, isize);
|
||||
#[repr(simd)] struct isizex4(isize, isize, isize, isize);
|
||||
#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize);
|
||||
#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize);
|
||||
#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize);
|
||||
#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize);
|
||||
|
11
src/test/ui/consts/union_constant.rs
Normal file
11
src/test/ui/consts/union_constant.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// compile-pass
|
||||
|
||||
union Uninit {
|
||||
_never_use: *const u8,
|
||||
uninit: (),
|
||||
}
|
||||
|
||||
const UNINIT: Uninit = Uninit { uninit: () };
|
||||
|
||||
fn main() {}
|
||||
|
10
src/test/ui/feature-gate/allow-features-empty.rs
Normal file
10
src/test/ui/feature-gate/allow-features-empty.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// compile-flags: -Z allow_features=
|
||||
// Note: This test uses rustc internal flags because they will never stabilize.
|
||||
|
||||
#![feature(rustc_diagnostic_macros)] //~ ERROR
|
||||
|
||||
#![feature(rustc_const_unstable)] //~ ERROR
|
||||
|
||||
#![feature(lang_items)] //~ ERROR
|
||||
|
||||
fn main() {}
|
21
src/test/ui/feature-gate/allow-features-empty.stderr
Normal file
21
src/test/ui/feature-gate/allow-features-empty.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features
|
||||
--> $DIR/allow-features-empty.rs:4:12
|
||||
|
|
||||
LL | #![feature(rustc_diagnostic_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
|
||||
--> $DIR/allow-features-empty.rs:6:12
|
||||
|
|
||||
LL | #![feature(rustc_const_unstable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0725]: the feature `lang_items` is not in the list of allowed features
|
||||
--> $DIR/allow-features-empty.rs:8:12
|
||||
|
|
||||
LL | #![feature(lang_items)]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0725`.
|
10
src/test/ui/feature-gate/allow-features.rs
Normal file
10
src/test/ui/feature-gate/allow-features.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items
|
||||
// Note: This test uses rustc internal flags because they will never stabilize.
|
||||
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
|
||||
#![feature(rustc_const_unstable)] //~ ERROR
|
||||
|
||||
#![feature(lang_items)]
|
||||
|
||||
fn main() {}
|
9
src/test/ui/feature-gate/allow-features.stderr
Normal file
9
src/test/ui/feature-gate/allow-features.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
|
||||
--> $DIR/allow-features.rs:6:12
|
||||
|
|
||||
LL | #![feature(rustc_const_unstable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0725`.
|
@ -12,7 +12,7 @@ pub fn main() {
|
||||
foo!();
|
||||
|
||||
assert!({one! two()});
|
||||
//~^ ERROR macros that expand to items must either be surrounded with braces or followed by a
|
||||
//~^ ERROR macros that expand to items
|
||||
//~| ERROR cannot find macro `one!` in this scope
|
||||
//~| ERROR mismatched types
|
||||
|
||||
|
@ -1,8 +1,16 @@
|
||||
error: macros that expand to items must either be surrounded with braces or followed by a semicolon
|
||||
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
||||
--> $DIR/issue-10536.rs:14:22
|
||||
|
|
||||
LL | assert!({one! two()});
|
||||
| ^^
|
||||
help: change the delimiters to curly braces
|
||||
|
|
||||
LL | assert!({one! two {}});
|
||||
| ^^
|
||||
help: add a semicolon
|
||||
|
|
||||
LL | assert!({one! two();});
|
||||
| ^
|
||||
|
||||
error: expected `(` or `{`, found `}`
|
||||
--> $DIR/issue-10536.rs:21:22
|
||||
|
8
src/test/ui/issues/issue-59029-1.rs
Normal file
8
src/test/ui/issues/issue-59029-1.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Svc<Req> { type Res; }
|
||||
|
||||
trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
|
||||
//~^ ERROR associated type `Res` not found for `Self`
|
||||
|
||||
fn main() {}
|
9
src/test/ui/issues/issue-59029-1.stderr
Normal file
9
src/test/ui/issues/issue-59029-1.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0220]: associated type `Res` not found for `Self`
|
||||
--> $DIR/issue-59029-1.rs:5:46
|
||||
|
|
||||
LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
|
||||
| ^^^^^^^^^ associated type `Res` not found
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0220`.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user