mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 04:04:06 +00:00
Auto merge of #71620 - Dylan-DPC:rollup-9wgtisb, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #67841 (Add Read/Write::can_read/write_vectored) - #71524 (Minimize parameter of coerce_borrowed_pointer()) - #71558 (Cleanup and document `-Z tls-model` ) - #71578 (linkchecker: fix typo in main.rs) - #71596 (Fix broken link in `QPath` documentation) - #71604 (make recursive-zst test unleashed) - #71605 (No need to whitelist E0750 anymore) Failed merges: r? @ghost
This commit is contained in:
commit
c354509343
25
src/doc/unstable-book/src/compiler-flags/tls-model.md
Normal file
25
src/doc/unstable-book/src/compiler-flags/tls-model.md
Normal file
@ -0,0 +1,25 @@
|
||||
# `tls_model`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
||||
Option `-Z tls-model` controls [TLS model](https://www.akkadia.org/drepper/tls.pdf) used to
|
||||
generate code for accessing `#[thread_local]` `static` items.
|
||||
|
||||
Supported values for this option are:
|
||||
|
||||
- `global-dynamic` - General Dynamic TLS Model (alternatively called Global Dynamic) is the most
|
||||
general option usable in all circumstances, even if the TLS data is defined in a shared library
|
||||
loaded at runtime and is accessed from code outside of that library.
|
||||
This is the default for most targets.
|
||||
- `local-dynamic` - model usable if the TLS data is only accessed from the shared library or
|
||||
executable it is defined in. The TLS data may be in a library loaded after startup (via `dlopen`).
|
||||
- `initial-exec` - model usable if the TLS data is defined in the executable or in a shared library
|
||||
loaded at program startup.
|
||||
The TLS data must not be in a library loaded after startup (via `dlopen`).
|
||||
- `local-exec` - model usable only if the TLS data is defined directly in the executable,
|
||||
but not in a shared library, and is accessed only from that executable.
|
||||
|
||||
`rustc` and LLVM may use a more optimized model than specified if they know that we are producing
|
||||
and executable rather than a library, or that the `static` item is private enough.
|
@ -43,13 +43,6 @@ pub const CODE_GEN_MODEL_ARGS: &[(&str, llvm::CodeModel)] = &[
|
||||
("large", llvm::CodeModel::Large),
|
||||
];
|
||||
|
||||
pub const TLS_MODEL_ARGS: [(&str, llvm::ThreadLocalMode); 4] = [
|
||||
("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
|
||||
("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
|
||||
("initial-exec", llvm::ThreadLocalMode::InitialExec),
|
||||
("local-exec", llvm::ThreadLocalMode::LocalExec),
|
||||
];
|
||||
|
||||
pub fn llvm_err(handler: &rustc_errors::Handler, msg: &str) -> FatalError {
|
||||
match llvm::last_error() {
|
||||
Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
|
||||
|
@ -21,7 +21,7 @@ use rustc_session::Session;
|
||||
use rustc_span::source_map::{Span, DUMMY_SP};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx};
|
||||
use rustc_target::spec::{HasTargetSpec, RelocModel, Target};
|
||||
use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::ffi::CStr;
|
||||
@ -87,19 +87,12 @@ pub struct CodegenCx<'ll, 'tcx> {
|
||||
local_gen_sym_counter: Cell<usize>,
|
||||
}
|
||||
|
||||
fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode {
|
||||
let tls_model_arg = match sess.opts.debugging_opts.tls_model {
|
||||
Some(ref s) => &s[..],
|
||||
None => &sess.target.target.options.tls_model[..],
|
||||
};
|
||||
|
||||
match crate::back::write::TLS_MODEL_ARGS.iter().find(|&&arg| arg.0 == tls_model_arg) {
|
||||
Some(x) => x.1,
|
||||
_ => {
|
||||
sess.err(&format!("{:?} is not a valid TLS model", tls_model_arg));
|
||||
sess.abort_if_errors();
|
||||
bug!();
|
||||
}
|
||||
fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
|
||||
match tls_model {
|
||||
TlsModel::GeneralDynamic => llvm::ThreadLocalMode::GeneralDynamic,
|
||||
TlsModel::LocalDynamic => llvm::ThreadLocalMode::LocalDynamic,
|
||||
TlsModel::InitialExec => llvm::ThreadLocalMode::InitialExec,
|
||||
TlsModel::LocalExec => llvm::ThreadLocalMode::LocalExec,
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,7 +260,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||
|
||||
let check_overflow = tcx.sess.overflow_checks();
|
||||
|
||||
let tls_model = get_tls_model(&tcx.sess);
|
||||
let tls_model = to_llvm_tls_model(tcx.sess.tls_model());
|
||||
|
||||
let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());
|
||||
|
||||
|
@ -216,7 +216,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
}
|
||||
PrintRequest::TlsModels => {
|
||||
println!("Available TLS models:");
|
||||
for &(name, _) in back::write::TLS_MODEL_ARGS.iter() {
|
||||
for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec"] {
|
||||
println!(" {}", name);
|
||||
}
|
||||
println!();
|
||||
|
@ -1601,7 +1601,7 @@ pub enum ExprKind<'hir> {
|
||||
///
|
||||
/// To resolve the path to a `DefId`, call [`qpath_res`].
|
||||
///
|
||||
/// [`qpath_res`]: ../ty/struct.TypeckTables.html#method.qpath_res
|
||||
/// [`qpath_res`]: ../rustc_middle/ty/struct.TypeckTables.html#method.qpath_res
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
|
||||
pub enum QPath<'hir> {
|
||||
/// Path to a definition, optionally "fully-qualified" with a `Self`
|
||||
|
@ -14,7 +14,8 @@ use rustc_session::{build_session, Session};
|
||||
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::SourceFileHashAlgorithm;
|
||||
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelocModel, RelroLevel};
|
||||
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy};
|
||||
use rustc_target::spec::{RelocModel, RelroLevel, TlsModel};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::iter::FromIterator;
|
||||
use std::path::PathBuf;
|
||||
@ -567,7 +568,7 @@ fn test_debugging_options_tracking_hash() {
|
||||
tracked!(symbol_mangling_version, SymbolManglingVersion::V0);
|
||||
tracked!(teach, true);
|
||||
tracked!(thinlto, Some(true));
|
||||
tracked!(tls_model, Some(String::from("tls model")));
|
||||
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
|
||||
tracked!(treat_err_as_bug, Some(1));
|
||||
tracked!(unleash_the_miri_inside_of_you, true);
|
||||
tracked!(verify_llvm_ir, true);
|
||||
|
@ -1315,10 +1315,6 @@ fn collect_print_requests(
|
||||
prints.push(PrintRequest::CodeModels);
|
||||
cg.code_model = None;
|
||||
}
|
||||
if dopts.tls_model.as_ref().map_or(false, |s| s == "help") {
|
||||
prints.push(PrintRequest::TlsModels);
|
||||
dopts.tls_model = None;
|
||||
}
|
||||
|
||||
prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
|
||||
"crate-name" => PrintRequest::CrateName,
|
||||
@ -2001,7 +1997,8 @@ crate mod dep_tracking {
|
||||
use crate::utils::NativeLibraryKind;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_target::spec::{MergeFunctions, PanicStrategy, RelocModel, RelroLevel, TargetTriple};
|
||||
use rustc_target::spec::{MergeFunctions, PanicStrategy, RelocModel};
|
||||
use rustc_target::spec::{RelroLevel, TargetTriple, TlsModel};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::BTreeMap;
|
||||
use std::hash::Hash;
|
||||
@ -2050,6 +2047,7 @@ crate mod dep_tracking {
|
||||
impl_dep_tracking_hash_via_hash!(Option<Vec<String>>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<MergeFunctions>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<RelocModel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<TlsModel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
|
||||
|
@ -6,7 +6,8 @@ use crate::search_paths::SearchPath;
|
||||
use crate::utils::NativeLibraryKind;
|
||||
|
||||
use rustc_target::spec::TargetTriple;
|
||||
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelocModel, RelroLevel};
|
||||
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy};
|
||||
use rustc_target::spec::{RelocModel, RelroLevel, TlsModel};
|
||||
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_span::edition::Edition;
|
||||
@ -267,6 +268,8 @@ macro_rules! options {
|
||||
pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
|
||||
pub const parse_relocation_model: &str =
|
||||
"one of supported relocation models (`rustc --print relocation-models`)";
|
||||
pub const parse_tls_model: &str =
|
||||
"one of supported TLS models (`rustc --print tls-models`)";
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -606,6 +609,14 @@ macro_rules! options {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_tls_model(slot: &mut Option<TlsModel>, v: Option<&str>) -> bool {
|
||||
match v.and_then(|s| TlsModel::from_str(s).ok()) {
|
||||
Some(tls_model) => *slot = Some(tls_model),
|
||||
_ => return false,
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_symbol_mangling_version(
|
||||
slot: &mut SymbolManglingVersion,
|
||||
v: Option<&str>,
|
||||
@ -977,7 +988,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
"measure time of each LLVM pass (default: no)"),
|
||||
time_passes: bool = (false, parse_bool, [UNTRACKED],
|
||||
"measure time of each rustc pass (default: no)"),
|
||||
tls_model: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||
tls_model: Option<TlsModel> = (None, parse_tls_model, [TRACKED],
|
||||
"choose the TLS model to use (`rustc --print tls-models` for details)"),
|
||||
trace_macros: bool = (false, parse_bool, [UNTRACKED],
|
||||
"for every macro invocation, print its name and arguments (default: no)"),
|
||||
|
@ -22,7 +22,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
|
||||
use rustc_span::SourceFileHashAlgorithm;
|
||||
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTriple};
|
||||
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTriple, TlsModel};
|
||||
|
||||
use std::cell::{self, RefCell};
|
||||
use std::env;
|
||||
@ -588,6 +588,10 @@ impl Session {
|
||||
self.opts.cg.relocation_model.unwrap_or(self.target.target.options.relocation_model)
|
||||
}
|
||||
|
||||
pub fn tls_model(&self) -> TlsModel {
|
||||
self.opts.debugging_opts.tls_model.unwrap_or(self.target.target.options.tls_model)
|
||||
}
|
||||
|
||||
pub fn must_not_eliminate_frame_pointers(&self) -> bool {
|
||||
// "mcount" function relies on stack pointer.
|
||||
// See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions, TlsModel};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut args = LinkArgs::new();
|
||||
@ -29,7 +29,7 @@ pub fn opts() -> TargetOptions {
|
||||
// (Global Offset Table) to obtain the effective address of a
|
||||
// thread-local variable. Using a GOT is useful only when doing
|
||||
// dynamic linking.
|
||||
tls_model: "local-exec".to_string(),
|
||||
tls_model: TlsModel::LocalExec,
|
||||
relro_level: RelroLevel::Full,
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions};
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy};
|
||||
use crate::spec::{RelocModel, TargetOptions, TlsModel};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
@ -17,7 +18,7 @@ pub fn opts() -> TargetOptions {
|
||||
position_independent_executables: true,
|
||||
relocation_model: RelocModel::Static,
|
||||
target_family: None,
|
||||
tls_model: "initial-exec".to_string(),
|
||||
tls_model: TlsModel::InitialExec,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions};
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy};
|
||||
use crate::spec::{RelocModel, TargetOptions, TlsModel};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
@ -18,7 +19,7 @@ pub fn opts() -> TargetOptions {
|
||||
position_independent_executables: true,
|
||||
relocation_model: RelocModel::Static,
|
||||
target_family: None,
|
||||
tls_model: "initial-exec".to_string(),
|
||||
tls_model: TlsModel::InitialExec,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +305,42 @@ impl ToJson for RelocModel {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
||||
pub enum TlsModel {
|
||||
GeneralDynamic,
|
||||
LocalDynamic,
|
||||
InitialExec,
|
||||
LocalExec,
|
||||
}
|
||||
|
||||
impl FromStr for TlsModel {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<TlsModel, ()> {
|
||||
Ok(match s {
|
||||
// Note the difference "general" vs "global" difference. The model name is "general",
|
||||
// but the user-facing option name is "global" for consistency with other compilers.
|
||||
"global-dynamic" => TlsModel::GeneralDynamic,
|
||||
"local-dynamic" => TlsModel::LocalDynamic,
|
||||
"initial-exec" => TlsModel::InitialExec,
|
||||
"local-exec" => TlsModel::LocalExec,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for TlsModel {
|
||||
fn to_json(&self) -> Json {
|
||||
match *self {
|
||||
TlsModel::GeneralDynamic => "global-dynamic",
|
||||
TlsModel::LocalDynamic => "local-dynamic",
|
||||
TlsModel::InitialExec => "initial-exec",
|
||||
TlsModel::LocalExec => "local-exec",
|
||||
}
|
||||
.to_json()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LoadTargetError {
|
||||
BuiltinTargetNotFound(String),
|
||||
Other(String),
|
||||
@ -660,7 +696,7 @@ pub struct TargetOptions {
|
||||
pub code_model: Option<String>,
|
||||
/// TLS model to use. Options are "global-dynamic" (default), "local-dynamic", "initial-exec"
|
||||
/// and "local-exec". This is similar to the -ftls-model option in GCC/Clang.
|
||||
pub tls_model: String,
|
||||
pub tls_model: TlsModel,
|
||||
/// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false.
|
||||
pub disable_redzone: bool,
|
||||
/// Eliminate frame pointers from stack frames if possible. Defaults to true.
|
||||
@ -863,7 +899,7 @@ impl Default for TargetOptions {
|
||||
executables: false,
|
||||
relocation_model: RelocModel::Pic,
|
||||
code_model: None,
|
||||
tls_model: "global-dynamic".to_string(),
|
||||
tls_model: TlsModel::GeneralDynamic,
|
||||
disable_redzone: false,
|
||||
eliminate_frame_pointer: true,
|
||||
function_sections: true,
|
||||
@ -1060,6 +1096,18 @@ impl Target {
|
||||
Some(Ok(()))
|
||||
})).unwrap_or(Ok(()))
|
||||
} );
|
||||
($key_name:ident, TlsModel) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
||||
match s.parse::<TlsModel>() {
|
||||
Ok(tls_model) => base.options.$key_name = tls_model,
|
||||
_ => return Some(Err(format!("'{}' is not a valid TLS model. \
|
||||
Run `rustc --print tls-models` to \
|
||||
see the list of supported values.", s))),
|
||||
}
|
||||
Some(Ok(()))
|
||||
})).unwrap_or(Ok(()))
|
||||
} );
|
||||
($key_name:ident, PanicStrategy) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
||||
@ -1200,7 +1248,7 @@ impl Target {
|
||||
key!(executables, bool);
|
||||
key!(relocation_model, RelocModel)?;
|
||||
key!(code_model, optional);
|
||||
key!(tls_model);
|
||||
key!(tls_model, TlsModel)?;
|
||||
key!(disable_redzone, bool);
|
||||
key!(eliminate_frame_pointer, bool);
|
||||
key!(function_sections, bool);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions};
|
||||
use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub fn options() -> TargetOptions {
|
||||
@ -138,7 +138,7 @@ pub fn options() -> TargetOptions {
|
||||
// `has_elf_tls`) and we need to get it to work by specifying
|
||||
// `local-exec` as that's all that's implemented in LLVM today for wasm.
|
||||
has_elf_tls: true,
|
||||
tls_model: "local-exec".to_string(),
|
||||
tls_model: TlsModel::LocalExec,
|
||||
|
||||
// gdb scripts don't work on wasm blobs
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
@ -211,12 +211,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
ty::RawPtr(mt_b) => {
|
||||
return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);
|
||||
}
|
||||
|
||||
ty::Ref(r_b, ty, mutbl) => {
|
||||
let mt_b = ty::TypeAndMut { ty, mutbl };
|
||||
return self.coerce_borrowed_pointer(a, b, r_b, mt_b);
|
||||
ty::Ref(r_b, _, mutbl_b) => {
|
||||
return self.coerce_borrowed_pointer(a, b, r_b, mutbl_b);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -255,7 +252,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
r_b: ty::Region<'tcx>,
|
||||
mt_b: TypeAndMut<'tcx>,
|
||||
mutbl_b: hir::Mutability,
|
||||
) -> CoerceResult<'tcx> {
|
||||
debug!("coerce_borrowed_pointer(a={:?}, b={:?})", a, b);
|
||||
|
||||
@ -268,7 +265,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
let (r_a, mt_a) = match a.kind {
|
||||
ty::Ref(r_a, ty, mutbl) => {
|
||||
let mt_a = ty::TypeAndMut { ty, mutbl };
|
||||
coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?;
|
||||
coerce_mutbls(mt_a.mutbl, mutbl_b)?;
|
||||
(r_a, mt_a)
|
||||
}
|
||||
_ => return self.unify_and(a, b, identity),
|
||||
@ -364,7 +361,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
r_a // [3] above
|
||||
} else {
|
||||
if r_borrow_var.is_none() {
|
||||
// create var lazilly, at most once
|
||||
// create var lazily, at most once
|
||||
let coercion = Coercion(span);
|
||||
let r = self.next_region_var(coercion);
|
||||
r_borrow_var = Some(r); // [4] above
|
||||
@ -375,7 +372,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
r,
|
||||
TypeAndMut {
|
||||
ty: referent_ty,
|
||||
mutbl: mt_b.mutbl, // [1] above
|
||||
mutbl: mutbl_b, // [1] above
|
||||
},
|
||||
);
|
||||
match self.unify(derefd_ty_a, b) {
|
||||
@ -417,11 +414,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// `self.x` both have `&mut `type would be a move of
|
||||
// `self.x`, but we auto-coerce it to `foo(&mut *self.x)`,
|
||||
// which is a borrow.
|
||||
assert_eq!(mt_b.mutbl, hir::Mutability::Not); // can only coerce &T -> &U
|
||||
assert_eq!(mutbl_b, hir::Mutability::Not); // can only coerce &T -> &U
|
||||
return success(vec![], ty, obligations);
|
||||
}
|
||||
|
||||
let needs = Needs::maybe_mut_place(mt_b.mutbl);
|
||||
let needs = Needs::maybe_mut_place(mutbl_b);
|
||||
let InferOk { value: mut adjustments, obligations: o } =
|
||||
autoderef.adjust_steps_as_infer_ok(self, needs);
|
||||
obligations.extend(o);
|
||||
@ -433,7 +430,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
ty::Ref(r_borrow, _, _) => r_borrow,
|
||||
_ => span_bug!(span, "expected a ref type, got {:?}", ty),
|
||||
};
|
||||
let mutbl = match mt_b.mutbl {
|
||||
let mutbl = match mutbl_b {
|
||||
hir::Mutability::Not => AutoBorrowMutability::Not,
|
||||
hir::Mutability::Mut => {
|
||||
AutoBorrowMutability::Mut { allow_two_phase_borrow: self.allow_two_phase }
|
||||
|
@ -659,6 +659,11 @@ impl Read for File {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -674,6 +679,11 @@ impl Write for File {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.inner.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.flush()
|
||||
}
|
||||
@ -694,6 +704,11 @@ impl Read for &File {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -709,6 +724,11 @@ impl Write for &File {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.inner.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.flush()
|
||||
}
|
||||
|
@ -292,6 +292,10 @@ impl<R: Read> Read for BufReader<R> {
|
||||
Ok(nread)
|
||||
}
|
||||
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
// we can't skip unconditionally because of the large buffer case in read.
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
self.inner.initializer()
|
||||
@ -680,6 +684,10 @@ impl<W: Write> Write for BufWriter<W> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.get_ref().is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.flush_buf().and_then(|()| self.get_mut().flush())
|
||||
}
|
||||
|
@ -266,6 +266,10 @@ where
|
||||
Ok(nread)
|
||||
}
|
||||
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||
let n = buf.len();
|
||||
Read::read_exact(&mut self.fill_buf()?, buf)?;
|
||||
@ -372,6 +376,11 @@ impl Write for Cursor<&mut [u8]> {
|
||||
slice_write_vectored(&mut self.pos, self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@ -388,6 +397,11 @@ impl Write for Cursor<&mut Vec<u8>> {
|
||||
vec_write_vectored(&mut self.pos, self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@ -404,6 +418,11 @@ impl Write for Cursor<Vec<u8>> {
|
||||
vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@ -422,6 +441,11 @@ impl Write for Cursor<Box<[u8]>> {
|
||||
slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
|
@ -20,6 +20,11 @@ impl<R: Read + ?Sized> Read for &mut R {
|
||||
(**self).read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
(**self).is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
(**self).initializer()
|
||||
@ -52,6 +57,11 @@ impl<W: Write + ?Sized> Write for &mut W {
|
||||
(**self).write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
(**self).is_write_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
(**self).flush()
|
||||
@ -109,6 +119,11 @@ impl<R: Read + ?Sized> Read for Box<R> {
|
||||
(**self).read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
(**self).is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
(**self).initializer()
|
||||
@ -141,6 +156,11 @@ impl<W: Write + ?Sized> Write for Box<W> {
|
||||
(**self).write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
(**self).is_write_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
(**self).flush()
|
||||
@ -240,6 +260,11 @@ impl Read for &[u8] {
|
||||
Ok(nread)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -316,6 +341,11 @@ impl Write for &mut [u8] {
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
|
||||
if self.write(data)? == data.len() {
|
||||
@ -351,6 +381,11 @@ impl Write for Vec<u8> {
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
self.extend_from_slice(buf);
|
||||
|
@ -256,6 +256,7 @@
|
||||
//! [`Read::read`]: trait.Read.html#tymethod.read
|
||||
//! [`Result`]: ../result/enum.Result.html
|
||||
//! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap
|
||||
// ignore-tidy-filelength
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
@ -580,6 +581,19 @@ pub trait Read {
|
||||
default_read_vectored(|b| self.read(b), bufs)
|
||||
}
|
||||
|
||||
/// Determines if this `Read`er has an efficient `read_vectored`
|
||||
/// implementation.
|
||||
///
|
||||
/// If a `Read`er does not override the default `read_vectored`
|
||||
/// implementation, code using it may want to avoid the method all together
|
||||
/// and coalesce writes into a single buffer for higher performance.
|
||||
///
|
||||
/// The default implementation returns `false`.
|
||||
#[unstable(feature = "can_vector", issue = "69941")]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines if this `Read`er can work with buffers of uninitialized
|
||||
/// memory.
|
||||
///
|
||||
@ -1304,6 +1318,19 @@ pub trait Write {
|
||||
default_write_vectored(|b| self.write(b), bufs)
|
||||
}
|
||||
|
||||
/// Determines if this `Write`er has an efficient `write_vectored`
|
||||
/// implementation.
|
||||
///
|
||||
/// If a `Write`er does not override the default `write_vectored`
|
||||
/// implementation, code using it may want to avoid the method all together
|
||||
/// and coalesce writes into a single buffer for higher performance.
|
||||
///
|
||||
/// The default implementation returns `false`.
|
||||
#[unstable(feature = "can_vector", issue = "69941")]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Flush this output stream, ensuring that all intermediately buffered
|
||||
/// contents reach their destination.
|
||||
///
|
||||
|
@ -87,6 +87,11 @@ impl Read for StdinRaw {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -101,6 +106,11 @@ impl Write for StdoutRaw {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.flush()
|
||||
}
|
||||
@ -114,6 +124,11 @@ impl Write for StderrRaw {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.flush()
|
||||
}
|
||||
@ -140,6 +155,14 @@ impl<W: io::Write> io::Write for Maybe<W> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
match self {
|
||||
Maybe::Real(w) => w.is_write_vectored(),
|
||||
Maybe::Fake => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
match *self {
|
||||
Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()),
|
||||
@ -162,6 +185,14 @@ impl<R: io::Read> io::Read for Maybe<R> {
|
||||
Maybe::Fake => Ok(0),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
match self {
|
||||
Maybe::Real(w) => w.is_read_vectored(),
|
||||
Maybe::Fake => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
|
||||
@ -352,6 +383,10 @@ impl Read for Stdin {
|
||||
self.lock().read_vectored(bufs)
|
||||
}
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.lock().is_read_vectored()
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
}
|
||||
@ -376,6 +411,11 @@ impl Read for StdinLock<'_> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -543,6 +583,10 @@ impl Write for Stdout {
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.lock().write_vectored(bufs)
|
||||
}
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.lock().is_write_vectored()
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.lock().flush()
|
||||
}
|
||||
@ -561,6 +605,10 @@ impl Write for StdoutLock<'_> {
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.inner.borrow_mut().write_vectored(bufs)
|
||||
}
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.inner.borrow_mut().is_write_vectored()
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.borrow_mut().flush()
|
||||
}
|
||||
@ -709,6 +757,10 @@ impl Write for Stderr {
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.lock().write_vectored(bufs)
|
||||
}
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.lock().is_write_vectored()
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.lock().flush()
|
||||
}
|
||||
@ -727,6 +779,10 @@ impl Write for StderrLock<'_> {
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.inner.borrow_mut().write_vectored(bufs)
|
||||
}
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.inner.borrow_mut().is_write_vectored()
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.borrow_mut().flush()
|
||||
}
|
||||
|
@ -179,6 +179,11 @@ impl Read for Repeat {
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -235,6 +240,11 @@ impl Write for Sink {
|
||||
Ok(total_len)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
|
@ -243,6 +243,7 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(cfg_accessible)]
|
||||
#![feature(can_vector)]
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(cfg_target_thread_local)]
|
||||
#![feature(char_error_internals)]
|
||||
|
@ -576,6 +576,11 @@ impl Read for TcpStream {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -591,6 +596,11 @@ impl Write for TcpStream {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -605,6 +615,11 @@ impl Read for &TcpStream {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -620,6 +635,11 @@ impl Write for &TcpStream {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -245,6 +245,10 @@ impl Write for ChildStdin {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.inner.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -300,6 +304,11 @@ impl Read for ChildStdout {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -356,6 +365,11 @@ impl Read for ChildStderr {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
|
@ -202,6 +202,10 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -210,6 +214,10 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ impl TcpStream {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -55,6 +59,10 @@ impl TcpStream {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -20,6 +24,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -301,6 +301,11 @@ impl File {
|
||||
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
@ -309,6 +314,11 @@ impl File {
|
||||
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -99,6 +99,11 @@ impl TcpStream {
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
|
||||
self.write_vectored(&[IoSlice::new(buffer)])
|
||||
}
|
||||
@ -114,6 +119,11 @@ impl TcpStream {
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported"))
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -20,6 +24,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -20,6 +20,11 @@ impl Stdin {
|
||||
// .read(data)
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Stdout {
|
||||
@ -51,6 +56,11 @@ impl Stdout {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -85,6 +95,11 @@ impl Stderr {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -34,6 +34,11 @@ impl FileDesc {
|
||||
usercalls::read(self.fd, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
usercalls::write(self.fd, &[IoSlice::new(buf)])
|
||||
}
|
||||
@ -42,6 +47,11 @@ impl FileDesc {
|
||||
usercalls::write(self.fd, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
usercalls::flush(self.fd)
|
||||
}
|
||||
|
@ -202,6 +202,10 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -210,6 +214,10 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -149,6 +149,11 @@ impl TcpStream {
|
||||
self.inner.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.inner.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.inner.write(buf)
|
||||
}
|
||||
@ -157,6 +162,11 @@ impl TcpStream {
|
||||
self.inner.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.inner.inner.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
addr_to_sockaddr(&self.peer_addr)
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -20,6 +24,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -613,6 +613,11 @@ impl io::Read for UnixStream {
|
||||
io::Read::read_vectored(&mut &*self, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
io::Read::is_read_vectored(&&*self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -629,6 +634,11 @@ impl<'a> io::Read for &'a UnixStream {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@ -645,6 +655,11 @@ impl io::Write for UnixStream {
|
||||
io::Write::write_vectored(&mut &*self, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
io::Write::is_write_vectored(&&*self)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
io::Write::flush(&mut &*self)
|
||||
}
|
||||
@ -660,6 +675,11 @@ impl<'a> io::Write for &'a UnixStream {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -64,6 +64,11 @@ impl FileDesc {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
let mut me = self;
|
||||
(&mut me).read_to_end(buf)
|
||||
@ -116,6 +121,11 @@ impl FileDesc {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
#[cfg(target_os = "android")]
|
||||
use super::android::cvt_pwrite64;
|
||||
|
@ -828,6 +828,11 @@ impl File {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
self.0.read_at(buf, offset)
|
||||
}
|
||||
@ -840,6 +845,11 @@ impl File {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
self.0.write_at(buf, offset)
|
||||
}
|
||||
|
@ -55,6 +55,10 @@ pub mod net {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
@ -75,6 +79,10 @@ pub mod net {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
@ -171,6 +179,10 @@ pub mod net {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
@ -179,6 +191,10 @@ pub mod net {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
}
|
||||
|
@ -226,6 +226,11 @@ impl Socket {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
fn recv_from_with_flags(
|
||||
&self,
|
||||
buf: &mut [u8],
|
||||
@ -263,6 +268,11 @@ impl Socket {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
|
||||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
|
@ -64,6 +64,11 @@ impl AnonPipe {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
@ -72,6 +77,11 @@ impl AnonPipe {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc {
|
||||
&self.0
|
||||
}
|
||||
|
@ -20,6 +20,11 @@ impl io::Read for Stdin {
|
||||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Stdout {
|
||||
@ -37,6 +42,11 @@ impl io::Write for Stdout {
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -57,6 +67,11 @@ impl io::Write for Stderr {
|
||||
ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -54,6 +54,11 @@ impl FileDesc {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
let mut me = self;
|
||||
(&mut me).read_to_end(buf)
|
||||
@ -99,6 +104,11 @@ impl FileDesc {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
unsafe fn cvt_pwrite(
|
||||
fd: c_int,
|
||||
|
@ -351,6 +351,11 @@ impl File {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
self.0.read_at(buf, offset)
|
||||
}
|
||||
@ -363,6 +368,11 @@ impl File {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
self.0.write_at(buf, offset)
|
||||
}
|
||||
|
@ -163,6 +163,11 @@ impl Socket {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
fn recv_from_with_flags(
|
||||
&self,
|
||||
buf: &mut [u8],
|
||||
@ -200,6 +205,11 @@ impl Socket {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
|
||||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
|
@ -24,10 +24,16 @@ impl AnonPipe {
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
@ -36,6 +42,11 @@ impl AnonPipe {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> &FileDesc {
|
||||
&self.0
|
||||
}
|
||||
|
@ -399,6 +399,11 @@ impl File {
|
||||
self.fd.read(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.write_vectored(&[IoSlice::new(buf)])
|
||||
}
|
||||
@ -407,6 +412,11 @@ impl File {
|
||||
self.fd.write(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ impl TcpStream {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
unsupported()
|
||||
}
|
||||
@ -56,6 +60,10 @@ impl TcpStream {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
unsupported()
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -20,6 +24,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -19,6 +19,11 @@ impl Stdin {
|
||||
ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).read(data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn as_raw_fd(&self) -> u32 {
|
||||
0
|
||||
}
|
||||
@ -37,6 +42,11 @@ impl Stdout {
|
||||
ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -59,6 +69,11 @@ impl Stderr {
|
||||
ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -202,6 +202,10 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -210,6 +214,10 @@ impl File {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -44,6 +44,10 @@ impl TcpStream {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -52,6 +56,10 @@ impl TcpStream {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
@ -20,6 +24,10 @@ impl AnonPipe {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
|
@ -409,6 +409,11 @@ impl File {
|
||||
self.handle.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.handle.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
self.handle.read_at(buf, offset)
|
||||
}
|
||||
@ -421,6 +426,11 @@ impl File {
|
||||
self.handle.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.handle.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
self.handle.write_at(buf, offset)
|
||||
}
|
||||
|
@ -92,6 +92,11 @@ impl RawHandle {
|
||||
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
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;
|
||||
@ -171,6 +176,11 @@ impl RawHandle {
|
||||
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -266,6 +266,11 @@ impl Socket {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.recv_with_flags(buf, c::MSG_PEEK)
|
||||
}
|
||||
@ -324,6 +329,11 @@ impl Socket {
|
||||
Ok(nwritten as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, dur: Option<Duration>, kind: c_int) -> io::Result<()> {
|
||||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
|
@ -182,6 +182,11 @@ impl AnonPipe {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.write(buf)
|
||||
}
|
||||
@ -189,6 +194,11 @@ impl AnonPipe {
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.inner.is_write_vectored()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
|
@ -265,6 +265,11 @@ impl TcpStream {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
|
||||
let ret = cvt(unsafe {
|
||||
@ -277,6 +282,11 @@ impl TcpStream {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.inner.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe { c::getpeername(*self.inner.as_inner(), buf, len) })
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
error[E0391]: cycle detected when const-evaluating `FOO`
|
||||
--> $DIR/recursive-zst-static.rs:7:18
|
||||
--> $DIR/recursive-zst-static.rs:10:18
|
||||
|
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^
|
||||
|
|
||||
note: ...which requires const-evaluating `FOO`...
|
||||
--> $DIR/recursive-zst-static.rs:7:1
|
||||
--> $DIR/recursive-zst-static.rs:10:1
|
||||
|
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires const-evaluating `FOO`, completing the cycle
|
||||
note: cycle used when const-evaluating + checking `FOO`
|
||||
--> $DIR/recursive-zst-static.rs:7:1
|
||||
--> $DIR/recursive-zst-static.rs:10:1
|
||||
|
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
@ -1,3 +1,6 @@
|
||||
// revisions: default unleash
|
||||
//[unleash]compile-flags: -Zunleash-the-miri-inside-of-you
|
||||
|
||||
// This test ensures that we do not allow ZST statics to initialize themselves without ever
|
||||
// actually creating a value of that type. This is important, as the ZST may have private fields
|
||||
// that users can reasonably expect to only get initialized by their own code. Thus unsafe code
|
||||
|
21
src/test/ui/consts/recursive-zst-static.unleash.stderr
Normal file
21
src/test/ui/consts/recursive-zst-static.unleash.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0391]: cycle detected when const-evaluating `FOO`
|
||||
--> $DIR/recursive-zst-static.rs:10:18
|
||||
|
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^
|
||||
|
|
||||
note: ...which requires const-evaluating `FOO`...
|
||||
--> $DIR/recursive-zst-static.rs:10:1
|
||||
|
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires const-evaluating `FOO`, completing the cycle
|
||||
note: cycle used when const-evaluating + checking `FOO`
|
||||
--> $DIR/recursive-zst-static.rs:10:1
|
||||
|
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
@ -114,7 +114,7 @@ fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) {
|
||||
}
|
||||
|
||||
fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Option<PathBuf> {
|
||||
// Ignore none HTML files.
|
||||
// Ignore non-HTML files.
|
||||
if file.extension().and_then(|s| s.to_str()) != Some("html") {
|
||||
return None;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ const WHITELIST: &[&str] = &[
|
||||
|
||||
// Some error codes don't have any tests apparently...
|
||||
const IGNORE_EXPLANATION_CHECK: &[&str] =
|
||||
&["E0570", "E0601", "E0602", "E0639", "E0729", "E0749", "E0750", "E0751"];
|
||||
&["E0570", "E0601", "E0602", "E0639", "E0729", "E0749", "E0750"];
|
||||
|
||||
fn check_error_code_explanation(
|
||||
f: &str,
|
||||
|
Loading…
Reference in New Issue
Block a user