mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Auto merge of #59949 - Centril:rollup-lsiqq1g, r=Centril
Rollup of 16 pull requests Successful merges: - #59675 (Stabilize the `alloc` crate.) - #59708 (Mark variables captured by reference as mutable correctly) - #59735 (remove lookup_char_pos_adj) - #59747 (Copy book.toml unstable book generator) - #59796 (Retire `IsNotConst` naming) - #59804 (Clean up jobserver integration) - #59818 (Eliminate `FnBox` usages from libstd.) - #59830 (Fix links on keyword docs.) - #59835 (Re-export NonZero signed variant in std) - #59852 (std: Add `{read,write}_vectored` for more types) - #59855 (Fix attributes position in type declaration) - #59858 (Make duplicate matcher bindings a hard error) - #59899 (In `-Zprint-type-size` output, sort enum variants by size.) - #59912 (MaybeUninit: remove deprecated functions) - #59925 (Fix paste error in split_ascii_whitespace docs.) - #59930 (Exclude some copies of old book editions from search engines) Failed merges: r? @ghost
This commit is contained in:
commit
00856722ba
@ -17,3 +17,11 @@ Disallow: /1.0.0-beta.2/
|
||||
Disallow: /1.0.0-beta.3/
|
||||
Disallow: /1.0.0-beta.4/
|
||||
Disallow: /1.0.0-beta.5/
|
||||
Disallow: /book/first-edition/
|
||||
Disallow: /book/second-edition/
|
||||
Disallow: /stable/book/first-edition/
|
||||
Disallow: /stable/book/second-edition/
|
||||
Disallow: /beta/book/first-edition/
|
||||
Disallow: /beta/book/second-edition/
|
||||
Disallow: /nightly/book/first-edition/
|
||||
Disallow: /nightly/book/second-edition/
|
||||
|
@ -1,2 +1,3 @@
|
||||
[book]
|
||||
title = "The Rust Unstable Book"
|
||||
author = "The Rust Community"
|
||||
|
@ -51,10 +51,7 @@
|
||||
//! default global allocator. It is not compatible with the libc allocator API.
|
||||
|
||||
#![allow(unused_attributes)]
|
||||
#![unstable(feature = "alloc",
|
||||
reason = "this library is unlikely to be stabilized in its current \
|
||||
form or name",
|
||||
issue = "27783")]
|
||||
#![stable(feature = "alloc", since = "1.36.0")]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
|
||||
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
|
||||
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
|
||||
|
@ -5,7 +5,6 @@
|
||||
//!
|
||||
//! ```
|
||||
//! # #![allow(unused_imports)]
|
||||
//! # #![feature(alloc)]
|
||||
//! #![feature(alloc_prelude)]
|
||||
//! extern crate alloc;
|
||||
//! use alloc::prelude::v1::*;
|
||||
|
@ -256,7 +256,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(alloc, raw_vec_internals)]
|
||||
/// # #![feature(raw_vec_internals)]
|
||||
/// # extern crate alloc;
|
||||
/// # use std::ptr;
|
||||
/// # use alloc::raw_vec::RawVec;
|
||||
@ -460,7 +460,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(alloc, raw_vec_internals)]
|
||||
/// # #![feature(raw_vec_internals)]
|
||||
/// # extern crate alloc;
|
||||
/// # use std::ptr;
|
||||
/// # use alloc::raw_vec::RawVec;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![cfg_attr(not(stage0), deny(internal))]
|
||||
|
||||
#![feature(alloc)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(raw_vec_internals)]
|
||||
|
@ -1152,15 +1152,6 @@ impl<T> MaybeUninit<T> {
|
||||
MaybeUninit { uninit: () }
|
||||
}
|
||||
|
||||
/// Deprecated before stabilization.
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
#[inline(always)]
|
||||
// FIXME: still used by stdsimd
|
||||
// #[rustc_deprecated(since = "1.35.0", reason = "use `uninit` instead")]
|
||||
pub const fn uninitialized() -> MaybeUninit<T> {
|
||||
Self::uninit()
|
||||
}
|
||||
|
||||
/// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
|
||||
/// filled with `0` bytes. It depends on `T` whether that already makes for
|
||||
/// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
|
||||
@ -1221,14 +1212,6 @@ impl<T> MaybeUninit<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated before stabilization.
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
#[inline(always)]
|
||||
#[rustc_deprecated(since = "1.35.0", reason = "use `write` instead")]
|
||||
pub fn set(&mut self, val: T) -> &mut T {
|
||||
self.write(val)
|
||||
}
|
||||
|
||||
/// Gets a pointer to the contained value. Reading from this pointer or turning it
|
||||
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
|
||||
///
|
||||
@ -1346,15 +1329,6 @@ impl<T> MaybeUninit<T> {
|
||||
ManuallyDrop::into_inner(self.value)
|
||||
}
|
||||
|
||||
/// Deprecated before stabilization.
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
#[inline(always)]
|
||||
// FIXME: still used by stdsimd
|
||||
// #[rustc_deprecated(since = "1.35.0", reason = "use `assume_init` instead")]
|
||||
pub unsafe fn into_initialized(self) -> T {
|
||||
self.assume_init()
|
||||
}
|
||||
|
||||
/// Reads the value from the `MaybeUninit<T>` container. The resulting `T` is subject
|
||||
/// to the usual drop handling.
|
||||
///
|
||||
@ -1417,14 +1391,6 @@ impl<T> MaybeUninit<T> {
|
||||
self.as_ptr().read()
|
||||
}
|
||||
|
||||
/// Deprecated before stabilization.
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")]
|
||||
#[inline(always)]
|
||||
#[rustc_deprecated(since = "1.35.0", reason = "use `read` instead")]
|
||||
pub unsafe fn read_initialized(&self) -> T {
|
||||
self.read()
|
||||
}
|
||||
|
||||
/// Gets a reference to the contained value.
|
||||
///
|
||||
/// # Safety
|
||||
|
@ -2712,7 +2712,7 @@ impl str {
|
||||
/// All kinds of ASCII whitespace are considered:
|
||||
///
|
||||
/// ```
|
||||
/// let mut iter = " Mary had\ta little \n\t lamb".split_whitespace();
|
||||
/// let mut iter = " Mary had\ta little \n\t lamb".split_ascii_whitespace();
|
||||
/// assert_eq!(Some("Mary"), iter.next());
|
||||
/// assert_eq!(Some("had"), iter.next());
|
||||
/// assert_eq!(Some("a"), iter.next());
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
#![deny(rust_2018_idioms)]
|
||||
|
||||
#![feature(allocator_api)]
|
||||
#![feature(alloc)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(libc)]
|
||||
|
@ -278,7 +278,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn explain_span(self, heading: &str, span: Span) -> (String, Option<Span>) {
|
||||
let lo = self.sess.source_map().lookup_char_pos_adj(span.lo());
|
||||
let lo = self.sess.source_map().lookup_char_pos(span.lo());
|
||||
(
|
||||
format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1),
|
||||
Some(span),
|
||||
|
@ -352,12 +352,6 @@ declare_lint! {
|
||||
"outlives requirements can be inferred"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub DUPLICATE_MATCHER_BINDING_NAME,
|
||||
Deny,
|
||||
"duplicate macro matcher binding name"
|
||||
}
|
||||
|
||||
/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
|
||||
pub mod parser {
|
||||
declare_lint! {
|
||||
@ -462,7 +456,6 @@ declare_lint_pass! {
|
||||
DEPRECATED_IN_FUTURE,
|
||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
NESTED_IMPL_TRAIT,
|
||||
DUPLICATE_MATCHER_BINDING_NAME,
|
||||
MUTABLE_BORROW_RESERVATION_CONFLICT,
|
||||
]
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ use rustc_data_structures::sync::{self, Lrc};
|
||||
use crate::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use crate::hir::intravisit;
|
||||
use crate::hir;
|
||||
use crate::lint::builtin::{BuiltinLintDiagnostics, DUPLICATE_MATCHER_BINDING_NAME};
|
||||
use crate::lint::builtin::BuiltinLintDiagnostics;
|
||||
use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT};
|
||||
use crate::session::{Session, DiagnosticMessageId};
|
||||
use crate::ty::TyCtxt;
|
||||
@ -82,7 +82,6 @@ impl Lint {
|
||||
match lint_id {
|
||||
BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP,
|
||||
BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
BufferedEarlyLintId::DuplicateMacroMatcherBindingName => DUPLICATE_MATCHER_BINDING_NAME,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,8 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
|
||||
write!(f, "inside call to `{}`", self.instance)?;
|
||||
}
|
||||
if !self.call_site.is_dummy() {
|
||||
let lo = tcx.sess.source_map().lookup_char_pos_adj(self.call_site.lo());
|
||||
write!(f, " at {}:{}:{}", lo.filename, lo.line, lo.col.to_usize() + 1)?;
|
||||
let lo = tcx.sess.source_map().lookup_char_pos(self.call_site.lo());
|
||||
write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -57,7 +57,13 @@ impl CodeStats {
|
||||
overall_size: Size,
|
||||
packed: bool,
|
||||
opt_discr_size: Option<Size>,
|
||||
variants: Vec<VariantInfo>) {
|
||||
mut variants: Vec<VariantInfo>) {
|
||||
// Sort variants so the largest ones are shown first. A stable sort is
|
||||
// used here so that source code order is preserved for all variants
|
||||
// that have the same size.
|
||||
variants.sort_by(|info1, info2| {
|
||||
info2.size.cmp(&info1.size)
|
||||
});
|
||||
let info = TypeSizeInfo {
|
||||
kind,
|
||||
type_description: type_desc.to_string(),
|
||||
|
@ -12,7 +12,7 @@ crate-type = ["dylib"]
|
||||
[dependencies]
|
||||
ena = "0.13"
|
||||
log = "0.4"
|
||||
jobserver_crate = { version = "0.1", package = "jobserver" }
|
||||
jobserver_crate = { version = "0.1.13", package = "jobserver" }
|
||||
lazy_static = "1"
|
||||
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
|
||||
serialize = { path = "../libserialize" }
|
||||
|
@ -1,89 +1,5 @@
|
||||
use jobserver_crate::{Client, HelperThread, Acquired};
|
||||
use jobserver_crate::Client;
|
||||
use lazy_static::lazy_static;
|
||||
use std::sync::{Condvar, Arc, Mutex};
|
||||
use std::mem;
|
||||
|
||||
#[derive(Default)]
|
||||
struct LockedProxyData {
|
||||
/// The number of free thread tokens, this may include the implicit token given to the process
|
||||
free: usize,
|
||||
|
||||
/// The number of threads waiting for a token
|
||||
waiters: usize,
|
||||
|
||||
/// The number of tokens we requested from the server
|
||||
requested: usize,
|
||||
|
||||
/// Stored tokens which will be dropped when we no longer need them
|
||||
tokens: Vec<Acquired>,
|
||||
}
|
||||
|
||||
impl LockedProxyData {
|
||||
fn request_token(&mut self, thread: &Mutex<HelperThread>) {
|
||||
self.requested += 1;
|
||||
thread.lock().unwrap().request_token();
|
||||
}
|
||||
|
||||
fn release_token(&mut self, cond_var: &Condvar) {
|
||||
if self.waiters > 0 {
|
||||
self.free += 1;
|
||||
cond_var.notify_one();
|
||||
} else {
|
||||
if self.tokens.is_empty() {
|
||||
// We are returning the implicit token
|
||||
self.free += 1;
|
||||
} else {
|
||||
// Return a real token to the server
|
||||
self.tokens.pop().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn take_token(&mut self, thread: &Mutex<HelperThread>) -> bool {
|
||||
if self.free > 0 {
|
||||
self.free -= 1;
|
||||
self.waiters -= 1;
|
||||
|
||||
// We stole some token reqested by someone else
|
||||
// Request another one
|
||||
if self.requested + self.free < self.waiters {
|
||||
self.request_token(thread);
|
||||
}
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn new_requested_token(&mut self, token: Acquired, cond_var: &Condvar) {
|
||||
self.requested -= 1;
|
||||
|
||||
// Does anything need this token?
|
||||
if self.waiters > 0 {
|
||||
self.free += 1;
|
||||
self.tokens.push(token);
|
||||
cond_var.notify_one();
|
||||
} else {
|
||||
// Otherwise we'll just drop it
|
||||
mem::drop(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ProxyData {
|
||||
lock: Mutex<LockedProxyData>,
|
||||
cond_var: Condvar,
|
||||
}
|
||||
|
||||
/// A helper type which makes managing jobserver tokens easier.
|
||||
/// It also allows you to treat the implicit token given to the process
|
||||
/// in the same manner as requested tokens.
|
||||
struct Proxy {
|
||||
thread: Mutex<HelperThread>,
|
||||
data: Arc<ProxyData>,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
// We can only call `from_env` once per process
|
||||
@ -105,20 +21,12 @@ lazy_static! {
|
||||
// per-process.
|
||||
static ref GLOBAL_CLIENT: Client = unsafe {
|
||||
Client::from_env().unwrap_or_else(|| {
|
||||
Client::new(32).expect("failed to create jobserver")
|
||||
let client = Client::new(32).expect("failed to create jobserver");
|
||||
// Acquire a token for the main thread which we can release later
|
||||
client.acquire_raw().ok();
|
||||
client
|
||||
})
|
||||
};
|
||||
|
||||
static ref GLOBAL_PROXY: Proxy = {
|
||||
let data = Arc::new(ProxyData::default());
|
||||
|
||||
Proxy {
|
||||
data: data.clone(),
|
||||
thread: Mutex::new(client().into_helper_thread(move |token| {
|
||||
data.lock.lock().unwrap().new_requested_token(token.unwrap(), &data.cond_var);
|
||||
}).unwrap()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn client() -> Client {
|
||||
@ -126,31 +34,9 @@ pub fn client() -> Client {
|
||||
}
|
||||
|
||||
pub fn acquire_thread() {
|
||||
GLOBAL_PROXY.acquire_token();
|
||||
GLOBAL_CLIENT.acquire_raw().ok();
|
||||
}
|
||||
|
||||
pub fn release_thread() {
|
||||
GLOBAL_PROXY.release_token();
|
||||
}
|
||||
|
||||
impl Proxy {
|
||||
fn release_token(&self) {
|
||||
self.data.lock.lock().unwrap().release_token(&self.data.cond_var);
|
||||
}
|
||||
|
||||
fn acquire_token(&self) {
|
||||
let mut data = self.data.lock.lock().unwrap();
|
||||
data.waiters += 1;
|
||||
if data.take_token(&self.thread) {
|
||||
return;
|
||||
}
|
||||
// Request a token for us
|
||||
data.request_token(&self.thread);
|
||||
loop {
|
||||
data = self.data.cond_var.wait(data).unwrap();
|
||||
if data.take_token(&self.thread) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
GLOBAL_CLIENT.release_raw().ok();
|
||||
}
|
||||
|
@ -428,11 +428,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
|
||||
edition: None,
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(DUPLICATE_MATCHER_BINDING_NAME),
|
||||
reference: "issue #57593 <https://github.com/rust-lang/rust/issues/57593>",
|
||||
edition: None,
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(NESTED_IMPL_TRAIT),
|
||||
reference: "issue #59014 <https://github.com/rust-lang/rust/issues/59014>",
|
||||
@ -494,6 +489,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
"no longer a warning, #[no_mangle] statics always exported");
|
||||
store.register_removed("bad_repr",
|
||||
"replaced with a generic attribute input check");
|
||||
store.register_removed("duplicate_matcher_binding_name",
|
||||
"converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
|
||||
}
|
||||
|
||||
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
|
@ -30,7 +30,7 @@ use std::rc::Rc;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex};
|
||||
use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError};
|
||||
use crate::dataflow::move_paths::{HasMoveData, InitLocation, LookupResult, MoveData, MoveError};
|
||||
use crate::dataflow::Borrows;
|
||||
use crate::dataflow::DataflowResultsConsumer;
|
||||
use crate::dataflow::FlowAtLocation;
|
||||
@ -1277,25 +1277,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
} = self.infcx.tcx.mir_borrowck(def_id);
|
||||
debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
|
||||
for field in used_mut_upvars {
|
||||
// This relies on the current way that by-value
|
||||
// captures of a closure are copied/moved directly
|
||||
// when generating MIR.
|
||||
match operands[field.index()] {
|
||||
Operand::Move(Place::Base(PlaceBase::Local(local)))
|
||||
| Operand::Copy(Place::Base(PlaceBase::Local(local))) => {
|
||||
self.used_mut.insert(local);
|
||||
}
|
||||
Operand::Move(ref place @ Place::Projection(_))
|
||||
| Operand::Copy(ref place @ Place::Projection(_)) => {
|
||||
if let Some(field) = place.is_upvar_field_projection(
|
||||
self.mir, &self.infcx.tcx) {
|
||||
self.used_mut_upvars.push(field);
|
||||
}
|
||||
}
|
||||
Operand::Move(Place::Base(PlaceBase::Static(..)))
|
||||
| Operand::Copy(Place::Base(PlaceBase::Static(..)))
|
||||
| Operand::Constant(..) => {}
|
||||
}
|
||||
self.propagate_closure_used_mut_upvar(&operands[field.index()]);
|
||||
}
|
||||
}
|
||||
AggregateKind::Adt(..)
|
||||
@ -1310,6 +1292,80 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
|
||||
let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| {
|
||||
match *place {
|
||||
Place::Projection { .. } => {
|
||||
if let Some(field) = place.is_upvar_field_projection(
|
||||
this.mir, &this.infcx.tcx) {
|
||||
this.used_mut_upvars.push(field);
|
||||
}
|
||||
}
|
||||
Place::Base(PlaceBase::Local(local)) => {
|
||||
this.used_mut.insert(local);
|
||||
}
|
||||
Place::Base(PlaceBase::Static(_)) => {}
|
||||
}
|
||||
};
|
||||
|
||||
// This relies on the current way that by-value
|
||||
// captures of a closure are copied/moved directly
|
||||
// when generating MIR.
|
||||
match *operand {
|
||||
Operand::Move(Place::Base(PlaceBase::Local(local)))
|
||||
| Operand::Copy(Place::Base(PlaceBase::Local(local)))
|
||||
if self.mir.local_decls[local].is_user_variable.is_none() =>
|
||||
{
|
||||
if self.mir.local_decls[local].ty.is_mutable_pointer() {
|
||||
// The variable will be marked as mutable by the borrow.
|
||||
return;
|
||||
}
|
||||
// This is an edge case where we have a `move` closure
|
||||
// inside a non-move closure, and the inner closure
|
||||
// contains a mutation:
|
||||
//
|
||||
// let mut i = 0;
|
||||
// || { move || { i += 1; }; };
|
||||
//
|
||||
// In this case our usual strategy of assuming that the
|
||||
// variable will be captured by mutable reference is
|
||||
// wrong, since `i` can be copied into the inner
|
||||
// closure from a shared reference.
|
||||
//
|
||||
// As such we have to search for the local that this
|
||||
// capture comes from and mark it as being used as mut.
|
||||
|
||||
let temp_mpi = self.move_data.rev_lookup.find_local(local);
|
||||
let init = if let [init_index] = *self.move_data.init_path_map[temp_mpi] {
|
||||
&self.move_data.inits[init_index]
|
||||
} else {
|
||||
bug!("temporary should be initialized exactly once")
|
||||
};
|
||||
|
||||
let loc = match init.location {
|
||||
InitLocation::Statement(stmt) => stmt,
|
||||
_ => bug!("temporary initialized in arguments"),
|
||||
};
|
||||
|
||||
let bbd = &self.mir[loc.block];
|
||||
let stmt = &bbd.statements[loc.statement_index];
|
||||
debug!("temporary assigned in: stmt={:?}", stmt);
|
||||
|
||||
if let StatementKind::Assign(_, box Rvalue::Ref(_, _, ref source)) = stmt.kind {
|
||||
propagate_closure_used_mut_place(self, source);
|
||||
} else {
|
||||
bug!("closures should only capture user variables \
|
||||
or references to user variables");
|
||||
}
|
||||
}
|
||||
Operand::Move(ref place)
|
||||
| Operand::Copy(ref place) => {
|
||||
propagate_closure_used_mut_place(self, place);
|
||||
}
|
||||
Operand::Constant(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn consume_operand(
|
||||
&mut self,
|
||||
context: Context,
|
||||
|
@ -44,8 +44,8 @@ pub enum TempState {
|
||||
impl TempState {
|
||||
pub fn is_promotable(&self) -> bool {
|
||||
debug!("is_promotable: self={:?}", self);
|
||||
if let TempState::Defined { uses, .. } = *self {
|
||||
uses > 0
|
||||
if let TempState::Defined { .. } = *self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -80,9 +80,14 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
||||
context: PlaceContext<'tcx>,
|
||||
location: Location) {
|
||||
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
|
||||
// We're only interested in temporaries
|
||||
if self.mir.local_kind(index) != LocalKind::Temp {
|
||||
return;
|
||||
// We're only interested in temporaries and the return place
|
||||
match self.mir.local_kind(index) {
|
||||
| LocalKind::Temp
|
||||
| LocalKind::ReturnPointer
|
||||
=> {},
|
||||
| LocalKind::Arg
|
||||
| LocalKind::Var
|
||||
=> return,
|
||||
}
|
||||
|
||||
// Ignore drops, if the temp gets promoted,
|
||||
@ -101,7 +106,6 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
||||
if *temp == TempState::Undefined {
|
||||
match context {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store) |
|
||||
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Call) => {
|
||||
*temp = TempState::Defined {
|
||||
location,
|
||||
|
@ -365,11 +365,11 @@ impl Qualif for NeedsDrop {
|
||||
}
|
||||
}
|
||||
|
||||
// Not constant at all - non-`const fn` calls, asm!,
|
||||
// Not promotable at all - non-`const fn` calls, asm!,
|
||||
// pointer comparisons, ptr-to-int casts, etc.
|
||||
struct IsNotConst;
|
||||
struct IsNotPromotable;
|
||||
|
||||
impl Qualif for IsNotConst {
|
||||
impl Qualif for IsNotPromotable {
|
||||
const IDX: usize = 2;
|
||||
|
||||
fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
|
||||
@ -508,13 +508,17 @@ impl Qualif for IsNotConst {
|
||||
}
|
||||
}
|
||||
|
||||
// Refers to temporaries which cannot be promoted as
|
||||
// promote_consts decided they weren't simple enough.
|
||||
// FIXME(oli-obk,eddyb): Remove this flag entirely and
|
||||
// solely process this information via `IsNotConst`.
|
||||
struct IsNotPromotable;
|
||||
/// Refers to temporaries which cannot be promoted *implicitly*.
|
||||
/// Explicit promotion happens e.g. for constant arguments declared via `rustc_args_required_const`.
|
||||
/// Inside a const context all constness rules
|
||||
/// apply, so implicit promotion simply has to follow the regular constant rules (modulo interior
|
||||
/// mutability or `Drop` rules which are handled `HasMutInterior` and `NeedsDrop` respectively).
|
||||
/// Implicit promotion inside regular functions does not happen if `const fn` calls are involved,
|
||||
/// as the call may be perfectly alright at runtime, but fail at compile time e.g. due to addresses
|
||||
/// being compared inside the function.
|
||||
struct IsNotImplicitlyPromotable;
|
||||
|
||||
impl Qualif for IsNotPromotable {
|
||||
impl Qualif for IsNotImplicitlyPromotable {
|
||||
const IDX: usize = 3;
|
||||
|
||||
fn in_call(
|
||||
@ -550,15 +554,18 @@ macro_rules! static_assert_seq_qualifs {
|
||||
static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i);
|
||||
};
|
||||
}
|
||||
static_assert_seq_qualifs!(0 => HasMutInterior, NeedsDrop, IsNotConst, IsNotPromotable);
|
||||
static_assert_seq_qualifs!(
|
||||
0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable
|
||||
);
|
||||
|
||||
impl ConstCx<'_, 'tcx> {
|
||||
fn qualifs_in_any_value_of_ty(&self, ty: Ty<'tcx>) -> PerQualif<bool> {
|
||||
let mut qualifs = PerQualif::default();
|
||||
qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false);
|
||||
qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false);
|
||||
qualifs[IsNotConst] = IsNotConst::in_any_value_of_ty(self, ty).unwrap_or(false);
|
||||
qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
|
||||
qualifs[IsNotImplicitlyPromotable] =
|
||||
IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
|
||||
qualifs
|
||||
}
|
||||
|
||||
@ -566,8 +573,8 @@ impl ConstCx<'_, 'tcx> {
|
||||
let mut qualifs = PerQualif::default();
|
||||
qualifs[HasMutInterior] = HasMutInterior::in_local(self, local);
|
||||
qualifs[NeedsDrop] = NeedsDrop::in_local(self, local);
|
||||
qualifs[IsNotConst] = IsNotConst::in_local(self, local);
|
||||
qualifs[IsNotPromotable] = IsNotPromotable::in_local(self, local);
|
||||
qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_local(self, local);
|
||||
qualifs
|
||||
}
|
||||
|
||||
@ -575,8 +582,8 @@ impl ConstCx<'_, 'tcx> {
|
||||
let mut qualifs = PerQualif::default();
|
||||
qualifs[HasMutInterior] = HasMutInterior::in_value(self, source);
|
||||
qualifs[NeedsDrop] = NeedsDrop::in_value(self, source);
|
||||
qualifs[IsNotConst] = IsNotConst::in_value(self, source);
|
||||
qualifs[IsNotPromotable] = IsNotPromotable::in_value(self, source);
|
||||
qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_value(self, source);
|
||||
qualifs
|
||||
}
|
||||
}
|
||||
@ -631,26 +638,21 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
};
|
||||
|
||||
for (local, decl) in mir.local_decls.iter_enumerated() {
|
||||
match mir.local_kind(local) {
|
||||
LocalKind::Arg => {
|
||||
let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty);
|
||||
for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 {
|
||||
if *qualif {
|
||||
per_local.insert(local);
|
||||
}
|
||||
if let LocalKind::Arg = mir.local_kind(local) {
|
||||
let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty);
|
||||
for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 {
|
||||
if *qualif {
|
||||
per_local.insert(local);
|
||||
}
|
||||
cx.per_local[IsNotConst].insert(local);
|
||||
}
|
||||
|
||||
LocalKind::Var if mode == Mode::Fn => {
|
||||
cx.per_local[IsNotConst].insert(local);
|
||||
}
|
||||
|
||||
LocalKind::Temp if !temps[local].is_promotable() => {
|
||||
cx.per_local[IsNotConst].insert(local);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
if !temps[local].is_promotable() {
|
||||
cx.per_local[IsNotPromotable].insert(local);
|
||||
}
|
||||
if let LocalKind::Var = mir.local_kind(local) {
|
||||
// Sanity check to prevent implicit and explicit promotion of
|
||||
// named locals
|
||||
assert!(cx.per_local[IsNotPromotable].contains(local));
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,11 +700,11 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
// the borrowed place is disallowed from being borrowed,
|
||||
// due to either a mutable borrow (with some exceptions),
|
||||
// or an shared borrow of a value with interior mutability.
|
||||
// Then `HasMutInterior` is replaced with `IsNotConst`,
|
||||
// Then `HasMutInterior` is replaced with `IsNotPromotable`,
|
||||
// to avoid duplicate errors (e.g. from reborrowing).
|
||||
if qualifs[HasMutInterior] {
|
||||
qualifs[HasMutInterior] = false;
|
||||
qualifs[IsNotConst] = true;
|
||||
qualifs[IsNotPromotable] = true;
|
||||
|
||||
if self.mode != Mode::Fn {
|
||||
if let BorrowKind::Mut { .. } = kind {
|
||||
@ -817,7 +819,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the `IsNotConst` qualification is preserved.
|
||||
// Ensure the `IsNotPromotable` qualification is preserved.
|
||||
// NOTE(eddyb) this is actually unnecessary right now, as
|
||||
// we never replace the local's qualif, but we might in
|
||||
// the future, and so it serves to catch changes that unset
|
||||
@ -825,7 +827,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
// be replaced with calling `insert` to re-set the bit).
|
||||
if kind == LocalKind::Temp {
|
||||
if !self.temp_promotion_state[index].is_promotable() {
|
||||
assert!(self.cx.per_local[IsNotConst].contains(index));
|
||||
assert!(self.cx.per_local[IsNotPromotable].contains(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -911,7 +913,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
|
||||
// Account for errors in consts by using the
|
||||
// conservative type qualification instead.
|
||||
if qualifs[IsNotConst] {
|
||||
if qualifs[IsNotPromotable] {
|
||||
qualifs = self.qualifs_in_any_value_of_ty(mir.return_ty());
|
||||
}
|
||||
|
||||
@ -1326,7 +1328,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||
// which happens even without the user requesting it.
|
||||
// We can error out with a hard error if the argument is not
|
||||
// constant here.
|
||||
if !IsNotConst::in_operand(self, arg) {
|
||||
if !IsNotPromotable::in_operand(self, arg) {
|
||||
debug!("visit_terminator_kind: candidate={:?}", candidate);
|
||||
self.promotion_candidates.push(candidate);
|
||||
} else {
|
||||
@ -1444,7 +1446,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
if mir.return_ty().references_error() {
|
||||
tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: Mir had errors");
|
||||
return (1 << IsNotConst::IDX, Lrc::new(BitSet::new_empty(0)));
|
||||
return (1 << IsNotPromotable::IDX, Lrc::new(BitSet::new_empty(0)));
|
||||
}
|
||||
|
||||
Checker::new(tcx, def_id, mir, Mode::Const).check_const()
|
||||
|
@ -3136,7 +3136,6 @@ fn item_trait(
|
||||
// FIXME: we should be using a derived_id for the Anchors here
|
||||
write!(w, "{{\n")?;
|
||||
for t in &types {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
write!(w, ";\n")?;
|
||||
}
|
||||
@ -3144,7 +3143,6 @@ fn item_trait(
|
||||
w.write_str("\n")?;
|
||||
}
|
||||
for t in &consts {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
write!(w, ";\n")?;
|
||||
}
|
||||
@ -3152,7 +3150,6 @@ fn item_trait(
|
||||
w.write_str("\n")?;
|
||||
}
|
||||
for (pos, m) in required.iter().enumerate() {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
write!(w, ";\n")?;
|
||||
|
||||
@ -3164,7 +3161,6 @@ fn item_trait(
|
||||
w.write_str("\n")?;
|
||||
}
|
||||
for (pos, m) in provided.iter().enumerate() {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
match m.inner {
|
||||
clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => {
|
||||
@ -3473,8 +3469,9 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>,
|
||||
(0, true)
|
||||
};
|
||||
render_attributes(w, meth)?;
|
||||
write!(w, "{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
|
||||
write!(w, "{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
|
||||
{generics}{decl}{where_clause}",
|
||||
if parent == ItemType::Trait { " " } else { "" },
|
||||
VisSpace(&meth.visibility),
|
||||
ConstnessSpace(header.constness),
|
||||
UnsafetySpace(header.unsafety),
|
||||
@ -3775,7 +3772,7 @@ const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
|
||||
"non_exhaustive"
|
||||
];
|
||||
|
||||
fn render_attributes(w: &mut fmt::Formatter<'_>, it: &clean::Item) -> fmt::Result {
|
||||
fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
|
||||
let mut attrs = String::new();
|
||||
|
||||
for attr in &it.attrs.other_attrs {
|
||||
|
@ -1577,3 +1577,17 @@ div.name.expand::before {
|
||||
left: -15px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
/* This part is to fix the "Expand attributes" part in the type declaration. */
|
||||
.type-decl > pre > :first-child {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.type-decl > pre > :nth-child(2) {
|
||||
margin-left: 1.8em !important;
|
||||
}
|
||||
.type-decl > pre > .toggle-attributes {
|
||||
margin-left: 2.2em;
|
||||
}
|
||||
.type-decl > pre > .docblock.attributes {
|
||||
margin-left: 4em;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
use crate::fmt;
|
||||
use crate::ffi::OsString;
|
||||
use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write};
|
||||
use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write, IoVec, IoVecMut};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::fs as fs_imp;
|
||||
use crate::sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
|
||||
@ -615,6 +615,10 @@ impl Read for File {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -625,6 +629,11 @@ impl Write for File {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.write(buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -639,6 +648,10 @@ impl Read for &File {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -649,6 +662,11 @@ impl Write for &File {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.write(buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -5,7 +5,7 @@ use crate::io::prelude::*;
|
||||
use crate::cell::RefCell;
|
||||
use crate::fmt;
|
||||
use crate::io::lazy::Lazy;
|
||||
use crate::io::{self, Initializer, BufReader, LineWriter};
|
||||
use crate::io::{self, Initializer, BufReader, LineWriter, IoVec, IoVecMut};
|
||||
use crate::sync::{Arc, Mutex, MutexGuard};
|
||||
use crate::sys::stdio;
|
||||
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
||||
@ -75,6 +75,10 @@ fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) }
|
||||
impl Read for StdinRaw {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -82,10 +86,20 @@ impl Read for StdinRaw {
|
||||
}
|
||||
impl Write for StdoutRaw {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> { self.0.flush() }
|
||||
}
|
||||
impl Write for StderrRaw {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> { self.0.flush() }
|
||||
}
|
||||
|
||||
@ -102,6 +116,14 @@ impl<W: io::Write> io::Write for Maybe<W> {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
let total = bufs.iter().map(|b| b.len()).sum();
|
||||
match self {
|
||||
Maybe::Real(w) => handle_ebadf(w.write_vectored(bufs), total),
|
||||
Maybe::Fake => Ok(total),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
match *self {
|
||||
Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()),
|
||||
@ -117,6 +139,13 @@ impl<R: io::Read> io::Read for Maybe<R> {
|
||||
Maybe::Fake => Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self {
|
||||
Maybe::Real(r) => handle_ebadf(r.read_vectored(bufs), 0),
|
||||
Maybe::Fake => Ok(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
|
||||
@ -305,6 +334,9 @@ impl Read for Stdin {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.lock().read(buf)
|
||||
}
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.lock().read_vectored(bufs)
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -325,6 +357,11 @@ impl Read for StdinLock<'_> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -483,6 +520,9 @@ impl Write for Stdout {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.lock().write(buf)
|
||||
}
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.lock().write_vectored(bufs)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.lock().flush()
|
||||
}
|
||||
@ -498,6 +538,9 @@ impl Write for StdoutLock<'_> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.borrow_mut().write(buf)
|
||||
}
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.inner.borrow_mut().write_vectored(bufs)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.borrow_mut().flush()
|
||||
}
|
||||
@ -636,6 +679,9 @@ impl Write for Stderr {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.lock().write(buf)
|
||||
}
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.lock().write_vectored(bufs)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.lock().flush()
|
||||
}
|
||||
@ -651,6 +697,9 @@ impl Write for StderrLock<'_> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.borrow_mut().write(buf)
|
||||
}
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.inner.borrow_mut().write_vectored(bufs)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.borrow_mut().flush()
|
||||
}
|
||||
|
@ -25,8 +25,7 @@
|
||||
///
|
||||
/// For more information on what `as` is capable of, see the [Reference]
|
||||
///
|
||||
/// [Reference]:
|
||||
/// https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
|
||||
/// [Reference]: ../reference/expressions/operator-expr.html#type-cast-expressions
|
||||
/// [`crate`]: keyword.crate.html
|
||||
mod as_keyword { }
|
||||
|
||||
@ -80,8 +79,8 @@ mod as_keyword { }
|
||||
///
|
||||
/// [pointer]: primitive.pointer.html
|
||||
/// [Rust Book]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html
|
||||
/// ../book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
|
||||
/// [Reference]: ../reference/items/constant-items.html
|
||||
mod const_keyword { }
|
||||
|
||||
#[doc(keyword = "crate")]
|
||||
@ -114,7 +113,7 @@ mod const_keyword { }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html
|
||||
/// [Reference]: ../reference/items/extern-crates.html
|
||||
mod crate_keyword { }
|
||||
|
||||
#[doc(keyword = "enum")]
|
||||
@ -169,8 +168,8 @@ mod crate_keyword { }
|
||||
///
|
||||
/// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type
|
||||
/// [`Option`]: option/enum.Option.html
|
||||
/// [Rust Book]: https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html
|
||||
/// [Rust Book]: ../book/ch06-01-defining-an-enum.html
|
||||
/// [Reference]: ../reference/items/enumerations.html
|
||||
mod enum_keyword { }
|
||||
|
||||
#[doc(keyword = "extern")]
|
||||
@ -211,8 +210,8 @@ mod enum_keyword { }
|
||||
/// For more information on FFI, check the [Rust book] or the [Reference].
|
||||
///
|
||||
/// [Rust book]:
|
||||
/// https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html
|
||||
/// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
|
||||
/// [Reference]: ../reference/items/external-blocks.html
|
||||
mod extern_keyword { }
|
||||
|
||||
#[doc(keyword = "fn")]
|
||||
@ -278,8 +277,8 @@ mod extern_keyword { }
|
||||
///
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [`extern`]: keyword.extern.html
|
||||
/// [Rust book]: https://doc.rust-lang.org/book/ch03-03-how-functions-work.html
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/functions.html
|
||||
/// [Rust book]: ../book/ch03-03-how-functions-work.html
|
||||
/// [Reference]: ../reference/items/functions.html
|
||||
mod fn_keyword { }
|
||||
|
||||
#[doc(keyword = "for")]
|
||||
@ -352,12 +351,11 @@ mod fn_keyword { }
|
||||
/// For more information on for-loops, see the [Rust book] or the [Reference].
|
||||
///
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [higher-ranked trait bounds]:
|
||||
/// https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds
|
||||
/// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds
|
||||
/// [`IntoIterator`]: iter/trait.IntoIterator.html
|
||||
/// [Rust book]:
|
||||
/// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops
|
||||
/// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
|
||||
/// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops
|
||||
mod for_keyword { }
|
||||
|
||||
#[doc(keyword = "if")]
|
||||
@ -430,9 +428,8 @@ mod for_keyword { }
|
||||
///
|
||||
/// For more information on `if` expressions, see the [Rust book] or the [Reference].
|
||||
///
|
||||
/// [Rust book]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html
|
||||
/// [Rust book]: ../book/ch03-05-control-flow.html#if-expressions
|
||||
/// [Reference]: ../reference/expressions/if-expr.html
|
||||
mod if_keyword { }
|
||||
|
||||
#[doc(keyword = "impl")]
|
||||
@ -493,10 +490,9 @@ mod if_keyword { }
|
||||
///
|
||||
/// For more information on `impl Trait` syntax, see the [Rust book][book2].
|
||||
///
|
||||
/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch05-03-method-syntax.html
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/items/implementations.html
|
||||
/// [book2]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch10-02-traits.html#returning-traits
|
||||
/// [book1]: ../book/ch05-03-method-syntax.html
|
||||
/// [Reference]: ../reference/items/implementations.html
|
||||
/// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits
|
||||
mod impl_keyword { }
|
||||
|
||||
#[doc(keyword = "let")]
|
||||
@ -554,13 +550,12 @@ mod impl_keyword { }
|
||||
/// enumerations. `while let` also exists, which runs a loop with a pattern matched value until
|
||||
/// that pattern can't be matched.
|
||||
///
|
||||
/// For more information on the `let` keyword, see the [Rust book] or the [Reference]
|
||||
/// For more information on the `let` keyword, see the [Rust book][book2] or the [Reference]
|
||||
///
|
||||
/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch06-02-match.html
|
||||
/// [book1]: ../book/ch06-02-match.html
|
||||
/// [`if`]: keyword.if.html
|
||||
/// [book2]:
|
||||
/// https://doc.rust-lang.org/stable/book/2018-edition/ch18-01-all-the-places-for-patterns.html#let-statements
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/statements.html#let-statements
|
||||
/// [book2]: ../book/ch18-01-all-the-places-for-patterns.html#let-statements
|
||||
/// [Reference]: ../reference/statements.html#let-statements
|
||||
mod let_keyword { }
|
||||
|
||||
#[doc(keyword = "loop")]
|
||||
@ -605,7 +600,7 @@ mod let_keyword { }
|
||||
///
|
||||
/// For more information on `loop` and loops in general, see the [Reference].
|
||||
///
|
||||
/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html
|
||||
/// [Reference]: ../reference/expressions/loop-expr.html
|
||||
mod loop_keyword { }
|
||||
|
||||
#[doc(keyword = "struct")]
|
||||
@ -712,6 +707,6 @@ mod loop_keyword { }
|
||||
/// [Reference][reference].
|
||||
///
|
||||
/// [`PhantomData`]: marker/struct.PhantomData.html
|
||||
/// [book]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html
|
||||
/// [reference]: https://doc.rust-lang.org/reference/items/structs.html
|
||||
/// [book]: ../book/ch05-01-defining-structs.html
|
||||
/// [reference]: ../reference/items/structs.html
|
||||
mod struct_keyword { }
|
||||
|
@ -229,7 +229,6 @@
|
||||
#![feature(align_offset)]
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(alloc)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(allocator_internals)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
|
@ -13,6 +13,8 @@ pub use core::num::Wrapping;
|
||||
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
|
||||
#[stable(feature = "signed_nonzero", since = "1.34.0")]
|
||||
pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
|
||||
|
||||
#[cfg(test)] use crate::fmt;
|
||||
#[cfg(test)] use crate::ops::{Add, Sub, Mul, Div, Rem};
|
||||
|
@ -111,7 +111,7 @@ use crate::io::prelude::*;
|
||||
use crate::ffi::OsStr;
|
||||
use crate::fmt;
|
||||
use crate::fs;
|
||||
use crate::io::{self, Initializer};
|
||||
use crate::io::{self, Initializer, IoVec, IoVecMut};
|
||||
use crate::path::Path;
|
||||
use crate::str;
|
||||
use crate::sys::pipe::{read2, AnonPipe};
|
||||
@ -225,6 +225,10 @@ impl Write for ChildStdin {
|
||||
self.inner.write(buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -271,6 +275,11 @@ impl Read for ChildStdout {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -318,6 +327,11 @@ impl Read for ChildStderr {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, SeekFrom};
|
||||
use crate::io::{self, SeekFrom, IoVec, IoVecMut};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
@ -198,10 +198,18 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::sys::Void;
|
||||
|
||||
pub struct AnonPipe(Void);
|
||||
@ -8,10 +8,18 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::cmp;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
@ -22,7 +21,7 @@ unsafe impl Sync for Thread {}
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
let p = box p;
|
||||
let mut native: libc::pthread_t = mem::zeroed();
|
||||
let mut attr: libc::pthread_attr_t = mem::zeroed();
|
||||
|
@ -2,7 +2,7 @@ use crate::os::unix::prelude::*;
|
||||
|
||||
use crate::ffi::{OsString, OsStr};
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, SeekFrom};
|
||||
use crate::io::{self, Error, SeekFrom, IoVec, IoVecMut};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sync::Arc;
|
||||
use crate::sys::fd::FileDesc;
|
||||
@ -278,10 +278,18 @@ impl File {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> { Ok(()) }
|
||||
|
||||
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::sys::{cvt, syscall};
|
||||
use crate::sys::fd::FileDesc;
|
||||
|
||||
@ -24,10 +24,18 @@ impl AnonPipe {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
use crate::mem;
|
||||
@ -19,7 +18,7 @@ unsafe impl Sync for Thread {}
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
|
||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
|
||||
let p = box p;
|
||||
|
||||
let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, SeekFrom};
|
||||
use crate::io::{self, SeekFrom, IoVec, IoVecMut};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
@ -200,10 +200,18 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::sys::Void;
|
||||
|
||||
pub struct AnonPipe(Void);
|
||||
@ -8,18 +8,23 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe,
|
||||
_v1: &mut Vec<u8>,
|
||||
_p2: AnonPipe,
|
||||
_v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
match p1.0 {}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
|
||||
use crate::boxed::FnBox;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
use crate::time::Duration;
|
||||
@ -13,17 +12,16 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
||||
mod task_queue {
|
||||
use crate::sync::{Mutex, MutexGuard, Once};
|
||||
use crate::sync::mpsc;
|
||||
use crate::boxed::FnBox;
|
||||
|
||||
pub type JoinHandle = mpsc::Receiver<()>;
|
||||
|
||||
pub(super) struct Task {
|
||||
p: Box<dyn FnBox()>,
|
||||
p: Box<dyn FnOnce()>,
|
||||
done: mpsc::Sender<()>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
pub(super) fn new(p: Box<dyn FnBox()>) -> (Task, JoinHandle) {
|
||||
pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
|
||||
let (done, recv) = mpsc::channel();
|
||||
(Task { p, done }, recv)
|
||||
}
|
||||
@ -51,7 +49,7 @@ mod task_queue {
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>)
|
||||
pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
let mut queue_lock = task_queue::lock();
|
||||
|
@ -2,7 +2,7 @@ use crate::os::unix::prelude::*;
|
||||
|
||||
use crate::ffi::{CString, CStr, OsString, OsStr};
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, ErrorKind, SeekFrom};
|
||||
use crate::io::{self, Error, ErrorKind, SeekFrom, IoVec, IoVecMut};
|
||||
use crate::mem;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::ptr;
|
||||
@ -560,6 +560,10 @@ impl File {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
self.0.read_at(buf, offset)
|
||||
}
|
||||
@ -568,6 +572,10 @@ impl File {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
self.0.write_at(buf, offset)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::mem;
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
use crate::sys::fd::FileDesc;
|
||||
@ -60,10 +60,18 @@ impl AnonPipe {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc { &self.0 }
|
||||
pub fn into_fd(self) -> FileDesc { self.0 }
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::mem::ManuallyDrop;
|
||||
|
||||
pub struct Stdin(());
|
||||
pub struct Stdout(());
|
||||
@ -11,10 +12,11 @@ impl Stdin {
|
||||
|
||||
impl io::Read for Stdin {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let fd = FileDesc::new(libc::STDIN_FILENO);
|
||||
let ret = fd.read(buf);
|
||||
fd.into_raw(); // do not close this FD
|
||||
ret
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,10 +26,11 @@ impl Stdout {
|
||||
|
||||
impl io::Write for Stdout {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let fd = FileDesc::new(libc::STDOUT_FILENO);
|
||||
let ret = fd.write(buf);
|
||||
fd.into_raw(); // do not close this FD
|
||||
ret
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write(buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
@ -41,10 +44,11 @@ impl Stderr {
|
||||
|
||||
impl io::Write for Stderr {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let fd = FileDesc::new(libc::STDERR_FILENO);
|
||||
let ret = fd.write(buf);
|
||||
fd.into_raw(); // do not close this FD
|
||||
ret
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write(buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::cmp;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
@ -39,7 +38,7 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread> {
|
||||
let p = box p;
|
||||
let mut native: libc::pthread_t = mem::zeroed();
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::sys::Void;
|
||||
|
||||
pub struct AnonPipe(Void);
|
||||
@ -8,10 +8,18 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -13,8 +13,12 @@ impl Stdin {
|
||||
}
|
||||
|
||||
pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
|
||||
self.read_vectored(&mut [IoVecMut::new(data)])
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, data: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
|
||||
.read(&mut [IoVecMut::new(data)])
|
||||
.read(data)
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,8 +28,12 @@ impl Stdout {
|
||||
}
|
||||
|
||||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||
self.write_vectored(&[IoVec::new(data)])
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, data: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDOUT_FILENO as u32) })
|
||||
.write(&[IoVec::new(data)])
|
||||
.write(data)
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
@ -39,8 +47,12 @@ impl Stderr {
|
||||
}
|
||||
|
||||
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
|
||||
self.write_vectored(&[IoVec::new(data)])
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, data: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDERR_FILENO as u32) })
|
||||
.write(&[IoVec::new(data)])
|
||||
.write(data)
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::cmp;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
@ -13,7 +12,7 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
|
||||
pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
unsupported()
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, SeekFrom};
|
||||
use crate::io::{self, SeekFrom, IoVec, IoVecMut};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{unsupported, Void};
|
||||
@ -200,10 +200,18 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::sys::Void;
|
||||
|
||||
pub struct AnonPipe(Void);
|
||||
@ -8,10 +8,18 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
use crate::sys::{unsupported, Void};
|
||||
@ -10,7 +9,7 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
|
||||
pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
unsupported()
|
||||
|
@ -2,7 +2,7 @@ use crate::os::windows::prelude::*;
|
||||
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, SeekFrom};
|
||||
use crate::io::{self, Error, SeekFrom, IoVec, IoVecMut};
|
||||
use crate::mem;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::ptr;
|
||||
@ -314,6 +314,10 @@ impl File {
|
||||
self.handle.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.handle.read_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
self.handle.read_at(buf, offset)
|
||||
}
|
||||
@ -322,6 +326,10 @@ impl File {
|
||||
self.handle.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.handle.write_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
self.handle.write_at(buf, offset)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![unstable(issue = "0", feature = "windows_handle")]
|
||||
|
||||
use crate::cmp;
|
||||
use crate::io::{self, ErrorKind, Read};
|
||||
use crate::io::{self, ErrorKind, Read, IoVec, IoVecMut};
|
||||
use crate::mem;
|
||||
use crate::ops::Deref;
|
||||
use crate::ptr;
|
||||
@ -89,6 +89,10 @@ impl RawHandle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
let mut read = 0;
|
||||
let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
|
||||
@ -169,6 +173,10 @@ impl RawHandle {
|
||||
Ok(amt as usize)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
let mut written = 0;
|
||||
let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
|
||||
@ -199,4 +207,8 @@ impl<'a> Read for &'a RawHandle {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
(**self).read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
(**self).read_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::os::windows::prelude::*;
|
||||
|
||||
use crate::ffi::OsStr;
|
||||
use crate::io;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::mem;
|
||||
use crate::path::Path;
|
||||
use crate::ptr;
|
||||
@ -166,9 +166,17 @@ impl AnonPipe {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.write(buf)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe,
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::io;
|
||||
use crate::ffi::CStr;
|
||||
use crate::mem;
|
||||
@ -20,7 +19,7 @@ pub struct Thread {
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
||||
-> io::Result<Thread> {
|
||||
let p = box p;
|
||||
|
||||
|
@ -2,12 +2,11 @@
|
||||
//!
|
||||
//! Documentation can be found on the `rt::at_exit` function.
|
||||
|
||||
use crate::boxed::FnBox;
|
||||
use crate::ptr;
|
||||
use crate::mem;
|
||||
use crate::sys_common::mutex::Mutex;
|
||||
|
||||
type Queue = Vec<Box<dyn FnBox()>>;
|
||||
type Queue = Vec<Box<dyn FnOnce()>>;
|
||||
|
||||
// NB these are specifically not types from `std::sync` as they currently rely
|
||||
// on poisoning and this module needs to operate at a lower level than requiring
|
||||
@ -61,7 +60,7 @@ pub fn cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(f: Box<dyn FnBox()>) -> bool {
|
||||
pub fn push(f: Box<dyn FnOnce()>) -> bool {
|
||||
unsafe {
|
||||
let _guard = LOCK.lock();
|
||||
if init() {
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::boxed::FnBox;
|
||||
use crate::env;
|
||||
use crate::sync::atomic::{self, Ordering};
|
||||
use crate::sys::stack_overflow;
|
||||
@ -11,7 +10,7 @@ pub unsafe fn start_thread(main: *mut u8) {
|
||||
let _handler = stack_overflow::Handler::new();
|
||||
|
||||
// Finally, let's run some code.
|
||||
Box::from_raw(main as *mut Box<dyn FnBox()>)()
|
||||
Box::from_raw(main as *mut Box<dyn FnOnce()>)()
|
||||
}
|
||||
|
||||
pub fn min_stack() -> usize {
|
||||
|
@ -157,7 +157,6 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::any::Any;
|
||||
use crate::boxed::FnBox;
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::ffi::{CStr, CString};
|
||||
use crate::fmt;
|
||||
@ -488,7 +487,9 @@ impl Builder {
|
||||
// returning.
|
||||
native: Some(imp::Thread::new(
|
||||
stack_size,
|
||||
mem::transmute::<Box<dyn FnBox() + 'a>, Box<dyn FnBox() + 'static>>(Box::new(main))
|
||||
mem::transmute::<Box<dyn FnOnce() + 'a>, Box<dyn FnOnce() + 'static>>(Box::new(
|
||||
main,
|
||||
)),
|
||||
)?),
|
||||
thread: my_thread,
|
||||
packet: Packet(my_packet),
|
||||
|
@ -36,9 +36,9 @@ pub struct ErrorLocation {
|
||||
impl ErrorLocation {
|
||||
/// Creates an error location from a span.
|
||||
pub fn from_span(ecx: &ExtCtxt<'_>, sp: Span) -> ErrorLocation {
|
||||
let loc = ecx.source_map().lookup_char_pos_adj(sp.lo());
|
||||
let loc = ecx.source_map().lookup_char_pos(sp.lo());
|
||||
ErrorLocation {
|
||||
filename: loc.filename,
|
||||
filename: loc.file.name.clone(),
|
||||
line: loc.line
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,6 @@ pub enum BufferedEarlyLintId {
|
||||
/// Usage of `?` as a macro separator is deprecated.
|
||||
QuestionMarkMacroSep,
|
||||
IllFormedAttributeInput,
|
||||
/// Usage of a duplicate macro matcher binding name.
|
||||
DuplicateMacroMatcherBindingName,
|
||||
}
|
||||
|
||||
/// Stores buffered lint info which can later be passed to `librustc`.
|
||||
|
@ -497,22 +497,14 @@ fn check_lhs_duplicate_matcher_bindings(
|
||||
node_id: ast::NodeId,
|
||||
) -> bool {
|
||||
use self::quoted::TokenTree;
|
||||
use crate::early_buffered_lints::BufferedEarlyLintId;
|
||||
for tt in tts {
|
||||
match *tt {
|
||||
TokenTree::MetaVarDecl(span, name, _kind) => {
|
||||
if let Some(&prev_span) = metavar_names.get(&name) {
|
||||
// FIXME(mark-i-m): in a few cycles, make this a hard error.
|
||||
// sess.span_diagnostic
|
||||
// .struct_span_err(span, "duplicate matcher binding")
|
||||
// .span_note(prev_span, "previous declaration was here")
|
||||
// .emit();
|
||||
sess.buffer_lint(
|
||||
BufferedEarlyLintId::DuplicateMacroMatcherBindingName,
|
||||
crate::source_map::MultiSpan::from(vec![prev_span, span]),
|
||||
node_id,
|
||||
"duplicate matcher binding"
|
||||
);
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(span, "duplicate matcher binding")
|
||||
.span_note(prev_span, "previous declaration was here")
|
||||
.emit();
|
||||
return false;
|
||||
} else {
|
||||
metavar_names.insert(name, span);
|
||||
|
@ -388,16 +388,6 @@ impl SourceMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt {
|
||||
let loc = self.lookup_char_pos(pos);
|
||||
LocWithOpt {
|
||||
filename: loc.file.name.clone(),
|
||||
line: loc.line,
|
||||
col: loc.col,
|
||||
file: Some(loc.file)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Some(span)`, a union of the lhs and rhs span. The lhs must precede the rhs. If
|
||||
/// there are gaps between lhs and rhs, the resulting union will cross these gaps.
|
||||
/// For this to work, the spans have to be:
|
||||
@ -438,10 +428,10 @@ impl SourceMap {
|
||||
return "no-location".to_string();
|
||||
}
|
||||
|
||||
let lo = self.lookup_char_pos_adj(sp.lo());
|
||||
let hi = self.lookup_char_pos_adj(sp.hi());
|
||||
let lo = self.lookup_char_pos(sp.lo());
|
||||
let hi = self.lookup_char_pos(sp.hi());
|
||||
format!("{}:{}:{}: {}:{}",
|
||||
lo.filename,
|
||||
lo.file.name,
|
||||
lo.line,
|
||||
lo.col.to_usize() + 1,
|
||||
hi.line,
|
||||
|
@ -1295,7 +1295,7 @@ impl Sub for CharPos {
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
// Loc, LocWithOpt, SourceFileAndLine, SourceFileAndBytePos
|
||||
// Loc, SourceFileAndLine, SourceFileAndBytePos
|
||||
//
|
||||
|
||||
/// A source code location used for error reporting.
|
||||
@ -1311,17 +1311,6 @@ pub struct Loc {
|
||||
pub col_display: usize,
|
||||
}
|
||||
|
||||
/// A source code location used as the result of `lookup_char_pos_adj`.
|
||||
// Actually, *none* of the clients use the filename *or* file field;
|
||||
// perhaps they should just be removed.
|
||||
#[derive(Debug)]
|
||||
pub struct LocWithOpt {
|
||||
pub filename: FileName,
|
||||
pub line: usize,
|
||||
pub col: CharPos,
|
||||
pub file: Option<Lrc<SourceFile>>,
|
||||
}
|
||||
|
||||
// Used to be structural records.
|
||||
#[derive(Debug)]
|
||||
pub struct SourceFileAndLine { pub sf: Lrc<SourceFile>, pub line: usize }
|
||||
|
@ -7,8 +7,8 @@ from subprocess import PIPE, Popen
|
||||
|
||||
# This is a whitelist of files which are stable crates or simply are not crates,
|
||||
# we don't check for the instability of these crates as they're all stable!
|
||||
STABLE_CRATES = ['std', 'core', 'proc_macro', 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o',
|
||||
'clang_rt']
|
||||
STABLE_CRATES = ['std', 'alloc', 'core', 'proc_macro',
|
||||
'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', 'clang_rt']
|
||||
|
||||
|
||||
def convert_to_string(s):
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
// ignore-emscripten no no_std executables
|
||||
|
||||
#![feature(lang_items, start, rustc_private, alloc)]
|
||||
#![feature(lang_items, start, rustc_private)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// run-pass
|
||||
#![feature(extern_prelude, lang_items, start, alloc)]
|
||||
#![feature(extern_prelude, lang_items, start)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
@ -1,7 +1,7 @@
|
||||
warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable
|
||||
--> $DIR/extern-prelude-core.rs:2:12
|
||||
|
|
||||
LL | #![feature(extern_prelude, lang_items, start, alloc)]
|
||||
LL | #![feature(extern_prelude, lang_items, start)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: #[warn(stable_features)] on by default
|
||||
|
@ -1,6 +1,6 @@
|
||||
// run-pass
|
||||
#![allow(unused_imports)]
|
||||
#![feature(lang_items, start, alloc)]
|
||||
#![feature(lang_items, start)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ignore-emscripten no no_std executables
|
||||
|
||||
#![feature(lang_items, start, alloc)]
|
||||
#![feature(lang_items, start)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
@ -3,9 +3,6 @@
|
||||
|
||||
// Make sure the destructor is run for unit-like structs.
|
||||
|
||||
|
||||
#![feature(alloc)]
|
||||
|
||||
use std::thread;
|
||||
|
||||
struct Foo;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Tests that it is possible to create a global allocator in a submodule, rather than in the crate
|
||||
// root.
|
||||
|
||||
#![feature(alloc, allocator_api, global_allocator)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use std::{
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: `global_allocator` cannot be used in submodules
|
||||
--> $DIR/allocator-submodule.rs:27:5
|
||||
--> $DIR/allocator-submodule.rs:25:5
|
||||
|
|
||||
LL | static MY_HEAP: MyAlloc = MyAlloc;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(alloc)]
|
||||
#![allow(unused_extern_crates, non_camel_case_types)]
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0254]: the name `alloc` is defined multiple times
|
||||
--> $DIR/E0254.rs:12:5
|
||||
--> $DIR/E0254.rs:11:5
|
||||
|
|
||||
LL | extern crate alloc;
|
||||
| ------------------- previous import of the extern crate `alloc` here
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(alloc, rustc_private)]
|
||||
#![feature(rustc_private)]
|
||||
#![allow(unused_extern_crates)]
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(alloc)]
|
||||
#![allow(unused_extern_crates)]
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0260]: the name `alloc` is defined multiple times
|
||||
--> $DIR/E0260.rs:6:1
|
||||
--> $DIR/E0260.rs:5:1
|
||||
|
|
||||
LL | extern crate alloc;
|
||||
| ------------------- previous import of the extern crate `alloc` here
|
||||
|
@ -1,16 +1,11 @@
|
||||
// Test that duplicate matcher binding names are caught at declaration time, rather than at macro
|
||||
// invocation time.
|
||||
//
|
||||
// FIXME(mark-i-m): Update this when it becomes a hard error.
|
||||
|
||||
// compile-pass
|
||||
|
||||
#![allow(unused_macros)]
|
||||
#![warn(duplicate_matcher_binding_name)]
|
||||
|
||||
macro_rules! foo1 {
|
||||
($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding
|
||||
($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding
|
||||
($a:ident, $a:ident) => {}; //~ERROR duplicate matcher binding
|
||||
($a:ident, $a:path) => {}; //~ERROR duplicate matcher binding
|
||||
}
|
||||
|
||||
macro_rules! foo2 {
|
||||
@ -19,8 +14,8 @@ macro_rules! foo2 {
|
||||
}
|
||||
|
||||
macro_rules! foo3 {
|
||||
($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding
|
||||
($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding
|
||||
($a:ident, $($a:ident),*) => {}; //~ERROR duplicate matcher binding
|
||||
($($a:ident)+ # $($($a:path),+);*) => {}; //~ERROR duplicate matcher binding
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,41 +1,50 @@
|
||||
warning: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:12:6
|
||||
error: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:7:16
|
||||
|
|
||||
LL | ($a:ident, $a:ident) => {};
|
||||
| ^^^^^^^^ ^^^^^^^^
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:9:9
|
||||
note: previous declaration was here
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:7:6
|
||||
|
|
||||
LL | #![warn(duplicate_matcher_binding_name)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
|
||||
LL | ($a:ident, $a:ident) => {};
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:13:6
|
||||
error: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:8:16
|
||||
|
|
||||
LL | ($a:ident, $a:path) => {};
|
||||
| ^^^^^^^^ ^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
|
||||
note: previous declaration was here
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:8:6
|
||||
|
|
||||
LL | ($a:ident, $a:path) => {};
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:22:6
|
||||
error: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:17:18
|
||||
|
|
||||
LL | ($a:ident, $($a:ident),*) => {};
|
||||
| ^^^^^^^^ ^^^^^^^^
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
|
||||
note: previous declaration was here
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:17:6
|
||||
|
|
||||
LL | ($a:ident, $($a:ident),*) => {};
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:23:8
|
||||
error: duplicate matcher binding
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:18:25
|
||||
|
|
||||
LL | ($($a:ident)+ # $($($a:path),+);*) => {};
|
||||
| ^^^^^^^^ ^^^^^^^
|
||||
| ^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
|
||||
note: previous declaration was here
|
||||
--> $DIR/macro-multiple-matcher-bindings.rs:18:8
|
||||
|
|
||||
LL | ($($a:ident)+ # $($($a:path),+);*) => {};
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#![no_std]
|
||||
#![crate_type = "staticlib"]
|
||||
#![feature(panic_handler, alloc_error_handler, alloc)]
|
||||
#![feature(panic_handler, alloc_error_handler)]
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_: &core::panic::PanicInfo) -> ! {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#![no_std]
|
||||
#![crate_type = "staticlib"]
|
||||
#![feature(panic_handler, alloc_error_handler, alloc)]
|
||||
#![feature(panic_handler, alloc_error_handler)]
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_: &core::panic::PanicInfo) -> ! {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// extra unused mut lint tests for #51918
|
||||
|
||||
// run-pass
|
||||
// compile-pass
|
||||
|
||||
#![feature(generators, nll)]
|
||||
#![deny(unused_mut)]
|
||||
@ -53,11 +53,14 @@ fn if_guard(x: Result<i32, i32>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
ref_argument(0);
|
||||
mutable_upvar();
|
||||
generator_mutable_upvar();
|
||||
ref_closure_argument();
|
||||
parse_dot_or_call_expr_with(Vec::new());
|
||||
if_guard(Ok(0));
|
||||
// #59620
|
||||
fn nested_closures() {
|
||||
let mut i = 0;
|
||||
[].iter().for_each(|_: &i32| {
|
||||
[].iter().for_each(move |_: &i32| {
|
||||
i += 1;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,9 @@
|
||||
print-type-size type: `Enum`: 51 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Small`: 7 bytes
|
||||
print-type-size field `.0`: 7 bytes
|
||||
print-type-size variant `Large`: 50 bytes
|
||||
print-type-size field `.0`: 50 bytes
|
||||
print-type-size variant `Small`: 7 bytes
|
||||
print-type-size field `.0`: 7 bytes
|
||||
print-type-size type: `FiftyBytes`: 50 bytes, alignment: 1 bytes
|
||||
print-type-size field `.0`: 50 bytes
|
||||
print-type-size type: `SevenBytes`: 7 bytes, alignment: 1 bytes
|
||||
|
@ -4,15 +4,15 @@ print-type-size field `.post`: 2 bytes
|
||||
print-type-size field `.pre`: 1 bytes
|
||||
print-type-size end padding: 1 bytes
|
||||
print-type-size type: `MyOption<IndirectNonZero>`: 12 bytes, alignment: 4 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 12 bytes
|
||||
print-type-size field `.0`: 12 bytes
|
||||
print-type-size type: `EmbeddedDiscr`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `EmbeddedDiscr`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size variant `Record`: 7 bytes
|
||||
print-type-size field `.val`: 4 bytes
|
||||
print-type-size field `.post`: 2 bytes
|
||||
print-type-size field `.pre`: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size end padding: 1 bytes
|
||||
print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size field `.val`: 4 bytes
|
||||
@ -20,59 +20,59 @@ print-type-size field `.post`: 2 bytes
|
||||
print-type-size field `.pre`: 1 bytes
|
||||
print-type-size end padding: 1 bytes
|
||||
print-type-size type: `Enum4<(), char, (), ()>`: 4 bytes, alignment: 4 bytes
|
||||
print-type-size variant `One`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Two`: 4 bytes
|
||||
print-type-size field `.0`: 4 bytes
|
||||
print-type-size variant `One`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Three`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Four`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size type: `MyOption<char>`: 4 bytes, alignment: 4 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 4 bytes
|
||||
print-type-size field `.0`: 4 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `MyOption<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 4 bytes
|
||||
print-type-size field `.0`: 4 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes
|
||||
print-type-size field `.0`: 4 bytes
|
||||
print-type-size type: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Four`: 2 bytes
|
||||
print-type-size field `.0`: 2 bytes
|
||||
print-type-size variant `One`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Two`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Three`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Four`: 2 bytes
|
||||
print-type-size field `.0`: 2 bytes
|
||||
print-type-size type: `MyOption<MyOption<u8>>`: 2 bytes, alignment: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 2 bytes
|
||||
print-type-size field `.0`: 2 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `MyOption<u8>`: 2 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 1 bytes
|
||||
print-type-size field `.0`: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `Enum4<(), (), bool, ()>`: 1 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Three`: 1 bytes
|
||||
print-type-size field `.0`: 1 bytes
|
||||
print-type-size variant `One`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Two`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size variant `Three`: 1 bytes
|
||||
print-type-size field `.0`: 1 bytes
|
||||
print-type-size variant `Four`: 0 bytes
|
||||
print-type-size field `.0`: 0 bytes
|
||||
print-type-size type: `MyOption<bool>`: 1 bytes, alignment: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 1 bytes
|
||||
print-type-size field `.0`: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `MyOption<std::cmp::Ordering>`: 1 bytes, alignment: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size variant `Some`: 1 bytes
|
||||
print-type-size field `.0`: 1 bytes
|
||||
print-type-size variant `None`: 0 bytes
|
||||
print-type-size type: `std::cmp::Ordering`: 1 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Less`: 0 bytes
|
||||
|
@ -1,21 +1,21 @@
|
||||
print-type-size type: `E1`: 12 bytes, alignment: 4 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `B`: 11 bytes
|
||||
print-type-size padding: 3 bytes
|
||||
print-type-size field `.0`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size variant `A`: 7 bytes
|
||||
print-type-size field `.1`: 1 bytes
|
||||
print-type-size padding: 2 bytes
|
||||
print-type-size field `.0`: 4 bytes, alignment: 4 bytes
|
||||
print-type-size type: `E2`: 12 bytes, alignment: 4 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `B`: 11 bytes
|
||||
print-type-size padding: 3 bytes
|
||||
print-type-size field `.0`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size type: `E2`: 12 bytes, alignment: 4 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `A`: 7 bytes
|
||||
print-type-size field `.0`: 1 bytes
|
||||
print-type-size padding: 2 bytes
|
||||
print-type-size field `.1`: 4 bytes, alignment: 4 bytes
|
||||
print-type-size variant `B`: 11 bytes
|
||||
print-type-size padding: 3 bytes
|
||||
print-type-size field `.0`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size type: `S`: 8 bytes, alignment: 4 bytes
|
||||
print-type-size field `.g`: 4 bytes
|
||||
print-type-size field `.a`: 1 bytes
|
||||
|
@ -1,10 +1,10 @@
|
||||
print-type-size type: `E`: 32 bytes, alignment: 16 bytes
|
||||
print-type-size discriminant: 4 bytes
|
||||
print-type-size variant `A`: 4 bytes
|
||||
print-type-size field `.0`: 4 bytes
|
||||
print-type-size variant `B`: 28 bytes
|
||||
print-type-size padding: 12 bytes
|
||||
print-type-size field `.0`: 16 bytes, alignment: 16 bytes
|
||||
print-type-size variant `A`: 4 bytes
|
||||
print-type-size field `.0`: 4 bytes
|
||||
print-type-size type: `S`: 32 bytes, alignment: 16 bytes
|
||||
print-type-size field `.c`: 16 bytes
|
||||
print-type-size field `.a`: 4 bytes
|
||||
|
@ -1,9 +1,9 @@
|
||||
print-type-size type: `Enum`: 51 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Small`: 7 bytes
|
||||
print-type-size field `.0`: 7 bytes
|
||||
print-type-size variant `Large`: 50 bytes
|
||||
print-type-size field `.0`: 50 bytes
|
||||
print-type-size variant `Small`: 7 bytes
|
||||
print-type-size field `.0`: 7 bytes
|
||||
print-type-size type: `FiftyBytes`: 50 bytes, alignment: 1 bytes
|
||||
print-type-size field `.0`: 50 bytes
|
||||
print-type-size type: `SevenBytes`: 7 bytes, alignment: 1 bytes
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(alloc)]
|
||||
#![allow(unused_extern_crates)]
|
||||
|
||||
mod a {
|
||||
|
@ -1,17 +1,17 @@
|
||||
error[E0432]: unresolved import `alloc`
|
||||
--> $DIR/resolve_self_super_hint.rs:6:9
|
||||
--> $DIR/resolve_self_super_hint.rs:5:9
|
||||
|
|
||||
LL | use alloc::HashMap;
|
||||
| ^^^^^ help: a similar path exists: `self::alloc`
|
||||
|
||||
error[E0432]: unresolved import `alloc`
|
||||
--> $DIR/resolve_self_super_hint.rs:11:13
|
||||
--> $DIR/resolve_self_super_hint.rs:10:13
|
||||
|
|
||||
LL | use alloc::HashMap;
|
||||
| ^^^^^ help: a similar path exists: `super::alloc`
|
||||
|
||||
error[E0432]: unresolved import `alloc`
|
||||
--> $DIR/resolve_self_super_hint.rs:16:17
|
||||
--> $DIR/resolve_self_super_hint.rs:15:17
|
||||
|
|
||||
LL | use alloc::HashMap;
|
||||
| ^^^^^
|
||||
@ -20,7 +20,7 @@ LL | use alloc::HashMap;
|
||||
| help: a similar path exists: `a::alloc`
|
||||
|
||||
error[E0432]: unresolved import `alloc`
|
||||
--> $DIR/resolve_self_super_hint.rs:21:21
|
||||
--> $DIR/resolve_self_super_hint.rs:20:21
|
||||
|
|
||||
LL | use alloc::HashMap;
|
||||
| ^^^^^
|
||||
|
@ -4,7 +4,6 @@
|
||||
// aux-build:remove-extern-crate.rs
|
||||
// compile-flags:--extern remove_extern_crate
|
||||
|
||||
#![feature(alloc)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
// aux-build:remove-extern-crate.rs
|
||||
// compile-flags:--extern remove_extern_crate
|
||||
|
||||
#![feature(alloc)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
extern crate core;
|
||||
|
@ -1,24 +1,24 @@
|
||||
warning: unused extern crate
|
||||
--> $DIR/remove-extern-crate.rs:10:1
|
||||
--> $DIR/remove-extern-crate.rs:9:1
|
||||
|
|
||||
LL | extern crate core;
|
||||
| ^^^^^^^^^^^^^^^^^^ help: remove it
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/remove-extern-crate.rs:8:9
|
||||
--> $DIR/remove-extern-crate.rs:7:9
|
||||
|
|
||||
LL | #![warn(rust_2018_idioms)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)]
|
||||
|
||||
warning: `extern crate` is not idiomatic in the new edition
|
||||
--> $DIR/remove-extern-crate.rs:11:1
|
||||
--> $DIR/remove-extern-crate.rs:10:1
|
||||
|
|
||||
LL | extern crate core as another_name;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
|
||||
|
||||
warning: `extern crate` is not idiomatic in the new edition
|
||||
--> $DIR/remove-extern-crate.rs:29:5
|
||||
--> $DIR/remove-extern-crate.rs:28:5
|
||||
|
|
||||
LL | extern crate core;
|
||||
| ^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
|
||||
|
@ -6,9 +6,9 @@ LL | Err("")?;
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<i32 as std::convert::From<bool>>
|
||||
<i32 as std::convert::From<core::num::NonZeroI32>>
|
||||
<i32 as std::convert::From<i16>>
|
||||
<i32 as std::convert::From<i8>>
|
||||
<i32 as std::convert::From<std::num::NonZeroI32>>
|
||||
and 2 others
|
||||
= note: required by `std::convert::From::from`
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// edition:2018
|
||||
|
||||
#![deny(unused_extern_crates)]
|
||||
#![feature(alloc, test, rustc_private, crate_visibility_modifier)]
|
||||
#![feature(test, rustc_private, crate_visibility_modifier)]
|
||||
|
||||
extern crate libc;
|
||||
//~^ ERROR unused extern crate
|
||||
|
@ -3,13 +3,13 @@ use std::fs;
|
||||
use std::path;
|
||||
use crate::features::{collect_lang_features, collect_lib_features, Features, Status};
|
||||
|
||||
pub const PATH_STR: &str = "doc/unstable-book/src";
|
||||
pub const PATH_STR: &str = "doc/unstable-book";
|
||||
|
||||
pub const COMPILER_FLAGS_DIR: &str = "compiler-flags";
|
||||
pub const COMPILER_FLAGS_DIR: &str = "src/compiler-flags";
|
||||
|
||||
pub const LANG_FEATURES_DIR: &str = "language-features";
|
||||
pub const LANG_FEATURES_DIR: &str = "src/language-features";
|
||||
|
||||
pub const LIB_FEATURES_DIR: &str = "library-features";
|
||||
pub const LIB_FEATURES_DIR: &str = "src/library-features";
|
||||
|
||||
/// Builds the path to the Unstable Book source directory from the Rust 'src' directory.
|
||||
pub fn unstable_book_path(base_src_path: &path::Path) -> path::PathBuf {
|
||||
|
@ -52,7 +52,7 @@ fn set_to_summary_str(set: &BTreeSet<String>, dir: &str
|
||||
|
||||
fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Features) {
|
||||
let compiler_flags = collect_unstable_book_section_file_names(
|
||||
&path.join("compiler-flags"));
|
||||
&path.join("src/compiler-flags"));
|
||||
|
||||
let compiler_flags_str = set_to_summary_str(&compiler_flags,
|
||||
"compiler-flags");
|
||||
@ -61,11 +61,11 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur
|
||||
let unstable_lib_features = collect_unstable_feature_names(&lib_features);
|
||||
|
||||
let lang_features_str = set_to_summary_str(&unstable_lang_features,
|
||||
LANG_FEATURES_DIR);
|
||||
"language-features");
|
||||
let lib_features_str = set_to_summary_str(&unstable_lib_features,
|
||||
LIB_FEATURES_DIR);
|
||||
"library-features");
|
||||
|
||||
let mut file = t!(File::create(&path.join("SUMMARY.md")));
|
||||
let mut file = t!(File::create(&path.join("src/SUMMARY.md")));
|
||||
t!(file.write_fmt(format_args!(include_str!("SUMMARY.md"),
|
||||
compiler_flags = compiler_flags_str,
|
||||
language_features = lang_features_str,
|
||||
@ -102,8 +102,8 @@ fn generate_unstable_book_files(src :&Path, out: &Path, features :&Features) {
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_recursive(path: &Path, to: &Path) {
|
||||
for entry in t!(fs::read_dir(path)) {
|
||||
fn copy_recursive(from: &Path, to: &Path) {
|
||||
for entry in t!(fs::read_dir(from)) {
|
||||
let e = t!(entry);
|
||||
let t = t!(e.metadata());
|
||||
let dest = &to.join(e.file_name());
|
||||
@ -120,7 +120,7 @@ fn main() {
|
||||
let src_path_str = env::args_os().skip(1).next().expect("source path required");
|
||||
let dest_path_str = env::args_os().skip(2).next().expect("destination path required");
|
||||
let src_path = Path::new(&src_path_str);
|
||||
let dest_path = Path::new(&dest_path_str).join("src");
|
||||
let dest_path = Path::new(&dest_path_str);
|
||||
|
||||
let lang_features = collect_lang_features(src_path, &mut false);
|
||||
let lib_features = collect_lib_features(src_path).into_iter().filter(|&(ref name, _)| {
|
||||
|
Loading…
Reference in New Issue
Block a user