Auto merge of #59478 - Centril:rollup, r=Centril
Rollup of 12 pull requests Successful merges: - #57987 (Fix some AArch64 typos) - #58581 (Refactor generic parameter encoder functions) - #58803 (fs::copy() unix: set file mode early) - #58848 (Prevent cache issues on version updates) - #59198 (Do not complain about unmentioned fields in recovered patterns) - #59351 (Include llvm-ar with llvm-tools component) - #59413 (HirIdify hir::ItemId) - #59441 (Remove the block on natvis for lld-link.) - #59448 (Use consistent phrasing for all macro summaries) - #59456 (Add documentation about `for` used as higher ranked trait bounds) - #59472 (Document that `std::io::BufReader` discards contents on drop) - #59474 (Fix link capitalization in documentation of std::io::BufWriter.) Failed merges: r? @ghost
This commit is contained in:
commit
237bf3244f
@ -69,6 +69,17 @@ fn main() {
|
||||
.arg("unstable-options");
|
||||
}
|
||||
cmd.arg("--generate-redirect-pages");
|
||||
has_unstable = true;
|
||||
}
|
||||
|
||||
// Needed to be able to run all rustdoc tests.
|
||||
if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") {
|
||||
// This "unstable-options" can be removed when `--resource-suffix` is stabilized
|
||||
if !has_unstable {
|
||||
cmd.arg("-Z")
|
||||
.arg("unstable-options");
|
||||
}
|
||||
cmd.arg("--resource-suffix").arg(x);
|
||||
}
|
||||
|
||||
if verbose > 1 {
|
||||
|
@ -343,12 +343,9 @@ fn invoke_rustdoc(
|
||||
.arg("--html-before-content").arg(&version_info)
|
||||
.arg("--html-in-header").arg(&header)
|
||||
.arg("--markdown-no-toc")
|
||||
.arg("--markdown-playground-url")
|
||||
.arg("https://play.rust-lang.org/")
|
||||
.arg("-o").arg(&out)
|
||||
.arg(&path)
|
||||
.arg("--markdown-css")
|
||||
.arg("../rust.css");
|
||||
.arg("--markdown-playground-url").arg("https://play.rust-lang.org/")
|
||||
.arg("-o").arg(&out).arg(&path)
|
||||
.arg("--markdown-css").arg("../rust.css");
|
||||
|
||||
builder.run(&mut cmd);
|
||||
}
|
||||
@ -431,8 +428,7 @@ impl Step for Standalone {
|
||||
.arg("--html-in-header").arg(&favicon)
|
||||
.arg("--markdown-no-toc")
|
||||
.arg("--index-page").arg(&builder.src.join("src/doc/index.md"))
|
||||
.arg("--markdown-playground-url")
|
||||
.arg("https://play.rust-lang.org/")
|
||||
.arg("--markdown-playground-url").arg("https://play.rust-lang.org/")
|
||||
.arg("-o").arg(&out)
|
||||
.arg(&path);
|
||||
|
||||
@ -523,6 +519,7 @@ impl Step for Std {
|
||||
.arg("--markdown-css").arg("rust.css")
|
||||
.arg("--markdown-no-toc")
|
||||
.arg("--generate-redirect-pages")
|
||||
.arg("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM)
|
||||
.arg("--index-page").arg(&builder.src.join("src/doc/index.md"));
|
||||
|
||||
builder.run(&mut cargo);
|
||||
@ -589,6 +586,7 @@ impl Step for Test {
|
||||
|
||||
cargo.arg("--no-deps")
|
||||
.arg("-p").arg("test")
|
||||
.env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
|
||||
.env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
|
||||
|
||||
builder.run(&mut cargo);
|
||||
@ -660,6 +658,7 @@ impl Step for WhitelistedRustc {
|
||||
// for which docs must be built.
|
||||
for krate in &["proc_macro"] {
|
||||
cargo.arg("-p").arg(krate)
|
||||
.env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
|
||||
.env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
|
||||
}
|
||||
|
||||
@ -890,6 +889,7 @@ impl Step for ErrorIndex {
|
||||
);
|
||||
index.arg("html");
|
||||
index.arg(out.join("error-index.html"));
|
||||
index.arg(crate::channel::CFG_RELEASE_NUM);
|
||||
|
||||
// FIXME: shouldn't have to pass this env var
|
||||
index.env("CFG_BUILD", &builder.config.build)
|
||||
|
@ -190,6 +190,7 @@ const LLVM_TOOLS: &[&str] = &[
|
||||
"llvm-readobj", // used to get information from ELFs/objects that the other tools don't provide
|
||||
"llvm-size", // used to prints the size of the linker sections of a program
|
||||
"llvm-strip", // used to discard symbols from binary files to reduce their size
|
||||
"llvm-ar" // used for creating and modifying archive files
|
||||
];
|
||||
|
||||
/// A structure representing a Rust compiler.
|
||||
|
@ -47,7 +47,7 @@ impl fmt::Debug for c_void {
|
||||
/// Basic implementation of a `va_list`.
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch4", target_os = "ios"),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
windows))]
|
||||
#[unstable(feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
@ -59,6 +59,7 @@ extern {
|
||||
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
windows))]
|
||||
impl fmt::Debug for VaListImpl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@ -67,11 +68,11 @@ impl fmt::Debug for VaListImpl {
|
||||
}
|
||||
|
||||
/// AArch64 ABI implementation of a `va_list`. See the
|
||||
/// [Aarch64 Procedure Call Standard] for more details.
|
||||
/// [AArch64 Procedure Call Standard] for more details.
|
||||
///
|
||||
/// [AArch64 Procedure Call Standard]:
|
||||
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
|
||||
#[cfg(all(target_arch = "aarch64", not(windows)))]
|
||||
#[cfg(all(target_arch = "aarch64", not(target_os = "ios"), not(windows)))]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "c_variadic",
|
||||
@ -193,14 +194,14 @@ impl<'a> VaList<'a> {
|
||||
where F: for<'copy> FnOnce(VaList<'copy>) -> R {
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch4", target_os = "ios"),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
windows))]
|
||||
let mut ap = va_copy(self);
|
||||
#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||
not(windows)))]
|
||||
not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
|
||||
let mut ap_inner = va_copy(self);
|
||||
#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||
not(windows)))]
|
||||
not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
|
||||
let mut ap = VaList(&mut ap_inner);
|
||||
let ret = f(VaList(ap.0));
|
||||
va_end(&mut ap);
|
||||
@ -216,10 +217,11 @@ extern "rust-intrinsic" {
|
||||
/// Copies the current location of arglist `src` to the arglist `dst`.
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
windows))]
|
||||
fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>;
|
||||
#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||
not(windows)))]
|
||||
not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
|
||||
fn va_copy(src: &VaList) -> VaListImpl;
|
||||
|
||||
/// Loads an argument of type `T` from the `va_list` `ap` and increment the
|
||||
|
@ -1,4 +1,6 @@
|
||||
/// Entry point of thread panic. For details, see `std::macros`.
|
||||
/// Panics the current thread.
|
||||
///
|
||||
/// For details, see `std::macros`.
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable(core_panic, __rust_unstable_column)]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
@ -132,7 +134,7 @@ macro_rules! assert_ne {
|
||||
});
|
||||
}
|
||||
|
||||
/// Ensure that a boolean expression is `true` at runtime.
|
||||
/// Asserts that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
||||
/// evaluated to `true` at runtime.
|
||||
@ -236,8 +238,7 @@ macro_rules! debug_assert_ne {
|
||||
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); })
|
||||
}
|
||||
|
||||
/// Helper macro for reducing boilerplate code for matching `Result` together
|
||||
/// with converting downstream errors.
|
||||
/// Unwraps a result or propagates its error.
|
||||
///
|
||||
/// The `?` operator was added to replace `try!` and should be used instead.
|
||||
/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use
|
||||
@ -312,7 +313,7 @@ macro_rules! r#try {
|
||||
($expr:expr,) => (r#try!($expr));
|
||||
}
|
||||
|
||||
/// Write formatted data into a buffer.
|
||||
/// Writes formatted data into a buffer.
|
||||
///
|
||||
/// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
|
||||
/// formatted according to the specified format string and the result will be passed to the writer.
|
||||
@ -434,7 +435,7 @@ macro_rules! writeln {
|
||||
);
|
||||
}
|
||||
|
||||
/// A utility macro for indicating unreachable code.
|
||||
/// Indicates unreachable code.
|
||||
///
|
||||
/// This is useful any time that the compiler can't determine that some code is unreachable. For
|
||||
/// example:
|
||||
@ -502,7 +503,7 @@ macro_rules! unreachable {
|
||||
});
|
||||
}
|
||||
|
||||
/// A standardized placeholder for marking unfinished code.
|
||||
/// Indicates unfinished code.
|
||||
///
|
||||
/// This can be useful if you are prototyping and are just looking to have your
|
||||
/// code type-check, or if you're implementing a trait that requires multiple
|
||||
@ -559,10 +560,10 @@ macro_rules! unimplemented {
|
||||
($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// A standardized placeholder for marking unfinished code.
|
||||
/// Indicates unfinished code.
|
||||
///
|
||||
/// This can be useful if you are prototyping and are just looking to have your
|
||||
/// code typecheck. `todo!` works exactly like `unimplemented!`, there only
|
||||
/// code typecheck. `todo!` works exactly like `unimplemented!`. The only
|
||||
/// difference between the two macros is the name.
|
||||
///
|
||||
/// # Panics
|
||||
@ -618,7 +619,7 @@ macro_rules! todo {
|
||||
($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// A macro to create an array of [`MaybeUninit`]
|
||||
/// Creates an array of [`MaybeUninit`].
|
||||
///
|
||||
/// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
|
||||
///
|
||||
@ -645,7 +646,7 @@ macro_rules! uninitialized_array {
|
||||
#[cfg(rustdoc)]
|
||||
mod builtin {
|
||||
|
||||
/// Unconditionally causes compilation to fail with the given error message when encountered.
|
||||
/// Causes compilation to fail with the given error message when encountered.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::compile_error!`].
|
||||
///
|
||||
@ -657,7 +658,7 @@ mod builtin {
|
||||
($msg:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// The core macro for formatted string creation & output.
|
||||
/// Constructs parameters for the other string-formatting macros.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::format_args!`].
|
||||
///
|
||||
@ -669,7 +670,7 @@ mod builtin {
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Inspect an environment variable at compile time.
|
||||
/// Inspects an environment variable at compile time.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::env!`].
|
||||
///
|
||||
@ -681,7 +682,7 @@ mod builtin {
|
||||
($name:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Optionally inspect an environment variable at compile time.
|
||||
/// Optionally inspects an environment variable at compile time.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::option_env!`].
|
||||
///
|
||||
@ -693,7 +694,7 @@ mod builtin {
|
||||
($name:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Concatenate identifiers into one identifier.
|
||||
/// Concatenates identifiers into one identifier.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::concat_idents!`].
|
||||
///
|
||||
@ -717,7 +718,7 @@ mod builtin {
|
||||
($($e:expr,)*) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// A macro which expands to the line number on which it was invoked.
|
||||
/// Expands to the line number on which it was invoked.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::line!`].
|
||||
///
|
||||
@ -726,7 +727,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! line { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// A macro which expands to the column number on which it was invoked.
|
||||
/// Expands to the column number on which it was invoked.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::column!`].
|
||||
///
|
||||
@ -735,7 +736,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! column { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// A macro which expands to the file name from which it was invoked.
|
||||
/// Expands to the file name from which it was invoked.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::file!`].
|
||||
///
|
||||
@ -744,7 +745,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! file { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// A macro which stringifies its arguments.
|
||||
/// Stringifies its arguments.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::stringify!`].
|
||||
///
|
||||
@ -786,7 +787,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! module_path { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// Boolean evaluation of configuration flags, at compile-time.
|
||||
/// Evaluates boolean combinations of configuration flags, at compile-time.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::cfg!`].
|
||||
///
|
||||
@ -795,7 +796,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// Parse a file as an expression or an item according to the context.
|
||||
/// Parses a file as an expression or an item according to the context.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::include!`].
|
||||
///
|
||||
@ -807,7 +808,7 @@ mod builtin {
|
||||
($file:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Ensure that a boolean expression is `true` at runtime.
|
||||
/// Asserts that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// For more information, see the documentation for [`std::assert!`].
|
||||
///
|
||||
|
@ -163,7 +163,7 @@ pub trait Visitor<'v> : Sized {
|
||||
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
|
||||
#[allow(unused_variables)]
|
||||
fn visit_nested_item(&mut self, id: ItemId) {
|
||||
let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item(id.id));
|
||||
let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item_by_hir_id(id.id));
|
||||
if let Some(item) = opt_item {
|
||||
self.visit_item(item);
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
use std::collections::{BTreeSet, BTreeMap};
|
||||
use std::fmt::Debug;
|
||||
use std::mem;
|
||||
use smallvec::SmallVec;
|
||||
use syntax::attr;
|
||||
@ -82,7 +81,7 @@ pub struct LoweringContext<'a> {
|
||||
resolver: &'a mut dyn Resolver,
|
||||
|
||||
/// The items being lowered are collected here.
|
||||
items: BTreeMap<NodeId, hir::Item>,
|
||||
items: BTreeMap<hir::HirId, hir::Item>,
|
||||
|
||||
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
|
||||
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
|
||||
@ -321,7 +320,7 @@ enum AnonymousLifetimeMode {
|
||||
PassThrough,
|
||||
}
|
||||
|
||||
struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[hir::ItemId; 1]> }
|
||||
struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> }
|
||||
|
||||
impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
|
||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||
@ -330,7 +329,7 @@ impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
|
||||
| TyKind::BareFn(_)
|
||||
=> return,
|
||||
|
||||
TyKind::ImplTrait(id, _) => self.ids.push(hir::ItemId { id }),
|
||||
TyKind::ImplTrait(id, _) => self.ids.push(id),
|
||||
_ => {},
|
||||
}
|
||||
visit::walk_ty(self, ty);
|
||||
@ -361,9 +360,40 @@ impl<'a> LoweringContext<'a> {
|
||||
lctx: &'lcx mut LoweringContext<'interner>,
|
||||
}
|
||||
|
||||
impl MiscCollector<'_, '_> {
|
||||
fn allocate_use_tree_hir_id_counters(
|
||||
&mut self,
|
||||
tree: &UseTree,
|
||||
owner: DefIndex,
|
||||
) {
|
||||
match tree.kind {
|
||||
UseTreeKind::Simple(_, id1, id2) => {
|
||||
for &id in &[id1, id2] {
|
||||
self.lctx.resolver.definitions().create_def_with_parent(
|
||||
owner,
|
||||
id,
|
||||
DefPathData::Misc,
|
||||
DefIndexAddressSpace::High,
|
||||
Mark::root(),
|
||||
tree.prefix.span,
|
||||
);
|
||||
self.lctx.allocate_hir_id_counter(id);
|
||||
}
|
||||
}
|
||||
UseTreeKind::Glob => (),
|
||||
UseTreeKind::Nested(ref trees) => {
|
||||
for &(ref use_tree, id) in trees {
|
||||
let hir_id = self.lctx.allocate_hir_id_counter(id).hir_id;
|
||||
self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
|
||||
fn visit_item(&mut self, item: &'lcx Item) {
|
||||
self.lctx.allocate_hir_id_counter(item.id, item);
|
||||
let hir_id = self.lctx.allocate_hir_id_counter(item.id).hir_id;
|
||||
|
||||
match item.node {
|
||||
ItemKind::Struct(_, ref generics)
|
||||
@ -383,18 +413,21 @@ impl<'a> LoweringContext<'a> {
|
||||
.count();
|
||||
self.lctx.type_def_lifetime_params.insert(def_id, count);
|
||||
}
|
||||
ItemKind::Use(ref use_tree) => {
|
||||
self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
|
||||
self.lctx.allocate_hir_id_counter(item.id, item);
|
||||
self.lctx.allocate_hir_id_counter(item.id);
|
||||
visit::walk_trait_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
|
||||
self.lctx.allocate_hir_id_counter(item.id, item);
|
||||
self.lctx.allocate_hir_id_counter(item.id);
|
||||
visit::walk_impl_item(self, item);
|
||||
}
|
||||
}
|
||||
@ -434,17 +467,16 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &'lcx Item) {
|
||||
let mut item_lowered = true;
|
||||
let mut item_hir_id = None;
|
||||
self.lctx.with_hir_id_owner(item.id, |lctx| {
|
||||
if let Some(hir_item) = lctx.lower_item(item) {
|
||||
lctx.insert_item(item.id, hir_item);
|
||||
} else {
|
||||
item_lowered = false;
|
||||
item_hir_id = Some(hir_item.hir_id);
|
||||
lctx.insert_item(hir_item);
|
||||
}
|
||||
});
|
||||
|
||||
if item_lowered {
|
||||
let item_generics = match self.lctx.items.get(&item.id).unwrap().node {
|
||||
if let Some(hir_id) = item_hir_id {
|
||||
let item_generics = match self.lctx.items.get(&hir_id).unwrap().node {
|
||||
hir::ItemKind::Impl(_, _, _, ref generics, ..)
|
||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
||||
generics.params.clone()
|
||||
@ -516,20 +548,21 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_item(&mut self, id: NodeId, item: hir::Item) {
|
||||
fn insert_item(&mut self, item: hir::Item) {
|
||||
let id = item.hir_id;
|
||||
// FIXME: Use debug_asset-rt
|
||||
assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0));
|
||||
self.items.insert(id, item);
|
||||
self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
|
||||
}
|
||||
|
||||
fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) -> LoweredNodeId {
|
||||
if self.item_local_id_counters.insert(owner, 0).is_some() {
|
||||
bug!(
|
||||
"Tried to allocate item_local_id_counter for {:?} twice",
|
||||
debug
|
||||
);
|
||||
}
|
||||
fn allocate_hir_id_counter(&mut self, owner: NodeId) -> LoweredNodeId {
|
||||
// Setup the counter if needed
|
||||
self.item_local_id_counters.entry(owner).or_insert(0);
|
||||
// Always allocate the first `HirId` for the owner itself.
|
||||
self.lower_node_id_with_owner(owner, owner)
|
||||
let lowered = self.lower_node_id_with_owner(owner, owner);
|
||||
debug_assert_eq!(lowered.hir_id.local_id.as_u32(), 0);
|
||||
lowered
|
||||
}
|
||||
|
||||
fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
|
||||
@ -1381,7 +1414,7 @@ impl<'a> LoweringContext<'a> {
|
||||
.opt_def_index(exist_ty_node_id)
|
||||
.unwrap();
|
||||
|
||||
self.allocate_hir_id_counter(exist_ty_node_id, &"existential impl trait");
|
||||
self.allocate_hir_id_counter(exist_ty_node_id);
|
||||
|
||||
let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, lower_bounds);
|
||||
|
||||
@ -1422,10 +1455,10 @@ impl<'a> LoweringContext<'a> {
|
||||
// Insert the item into the global list. This usually happens
|
||||
// automatically for all AST items. But this existential type item
|
||||
// does not actually exist in the AST.
|
||||
lctx.insert_item(exist_ty_id.node_id, exist_ty_item);
|
||||
lctx.insert_item(exist_ty_item);
|
||||
|
||||
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
|
||||
hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
|
||||
hir::TyKind::Def(hir::ItemId { id: exist_ty_id.hir_id }, lifetimes)
|
||||
})
|
||||
}
|
||||
|
||||
@ -2002,9 +2035,9 @@ impl<'a> LoweringContext<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[hir::ItemId; 1]>) {
|
||||
fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
|
||||
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(l.id);
|
||||
let mut ids = SmallVec::<[hir::ItemId; 1]>::new();
|
||||
let mut ids = SmallVec::<[NodeId; 1]>::new();
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
if let Some(ref ty) = l.ty {
|
||||
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
|
||||
@ -3065,7 +3098,6 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
|
||||
let mut defs = self.expect_full_def_from_use(id);
|
||||
// We want to return *something* from this function, so hold onto the first item
|
||||
// for later.
|
||||
@ -3084,14 +3116,6 @@ impl<'a> LoweringContext<'a> {
|
||||
seg.id = self.sess.next_node_id();
|
||||
}
|
||||
let span = path.span;
|
||||
self.resolver.definitions().create_def_with_parent(
|
||||
parent_def_index,
|
||||
new_node_id,
|
||||
DefPathData::Misc,
|
||||
DefIndexAddressSpace::High,
|
||||
Mark::root(),
|
||||
span);
|
||||
self.allocate_hir_id_counter(new_node_id, &path);
|
||||
|
||||
self.with_hir_id_owner(new_node_id, |this| {
|
||||
let new_id = this.lower_node_id(new_node_id);
|
||||
@ -3114,7 +3138,6 @@ impl<'a> LoweringContext<'a> {
|
||||
let vis = respan(vis.span, vis_kind);
|
||||
|
||||
this.insert_item(
|
||||
new_id.node_id,
|
||||
hir::Item {
|
||||
hir_id: new_id.hir_id,
|
||||
ident,
|
||||
@ -3174,8 +3197,6 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
// Add all the nested `PathListItem`s to the HIR.
|
||||
for &(ref use_tree, id) in trees {
|
||||
self.allocate_hir_id_counter(id, &use_tree);
|
||||
|
||||
let LoweredNodeId {
|
||||
node_id: new_id,
|
||||
hir_id: new_hir_id,
|
||||
@ -3219,7 +3240,6 @@ impl<'a> LoweringContext<'a> {
|
||||
let vis = respan(vis.span, vis_kind);
|
||||
|
||||
this.insert_item(
|
||||
new_id,
|
||||
hir::Item {
|
||||
hir_id: new_hir_id,
|
||||
ident,
|
||||
@ -3443,17 +3463,17 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
|
||||
match i.node {
|
||||
let node_ids = match i.node {
|
||||
ItemKind::Use(ref use_tree) => {
|
||||
let mut vec = smallvec![hir::ItemId { id: i.id }];
|
||||
let mut vec = smallvec![i.id];
|
||||
self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
|
||||
vec
|
||||
}
|
||||
ItemKind::MacroDef(..) => SmallVec::new(),
|
||||
ItemKind::Fn(..) |
|
||||
ItemKind::Impl(.., None, _, _) => smallvec![hir::ItemId { id: i.id }],
|
||||
ItemKind::Impl(.., None, _, _) => smallvec![i.id],
|
||||
ItemKind::Static(ref ty, ..) => {
|
||||
let mut ids = smallvec![hir::ItemId { id: i.id }];
|
||||
let mut ids = smallvec![i.id];
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
|
||||
visitor.visit_ty(ty);
|
||||
@ -3461,25 +3481,29 @@ impl<'a> LoweringContext<'a> {
|
||||
ids
|
||||
},
|
||||
ItemKind::Const(ref ty, ..) => {
|
||||
let mut ids = smallvec![hir::ItemId { id: i.id }];
|
||||
let mut ids = smallvec![i.id];
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
|
||||
visitor.visit_ty(ty);
|
||||
}
|
||||
ids
|
||||
},
|
||||
_ => smallvec![hir::ItemId { id: i.id }],
|
||||
}
|
||||
_ => smallvec![i.id],
|
||||
};
|
||||
|
||||
node_ids.into_iter().map(|node_id| hir::ItemId {
|
||||
id: self.allocate_hir_id_counter(node_id).hir_id
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn lower_item_id_use_tree(&mut self,
|
||||
tree: &UseTree,
|
||||
base_id: NodeId,
|
||||
vec: &mut SmallVec<[hir::ItemId; 1]>)
|
||||
vec: &mut SmallVec<[NodeId; 1]>)
|
||||
{
|
||||
match tree.kind {
|
||||
UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
|
||||
vec.push(hir::ItemId { id });
|
||||
vec.push(id);
|
||||
self.lower_item_id_use_tree(nested, id, vec);
|
||||
},
|
||||
UseTreeKind::Glob => {}
|
||||
@ -3488,7 +3512,7 @@ impl<'a> LoweringContext<'a> {
|
||||
.skip(1)
|
||||
.zip([id1, id2].iter())
|
||||
{
|
||||
vec.push(hir::ItemId { id });
|
||||
vec.push(id);
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -4604,6 +4628,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
|
||||
.into_iter()
|
||||
.map(|item_id| {
|
||||
let item_id = hir::ItemId { id: self.lower_node_id(item_id).hir_id };
|
||||
let LoweredNodeId { node_id: _, hir_id } = self.next_id();
|
||||
|
||||
hir::Stmt {
|
||||
|
@ -609,7 +609,7 @@ impl<'hir> Map<'hir> {
|
||||
let module = &self.forest.krate.modules[&node_id];
|
||||
|
||||
for id in &module.items {
|
||||
visitor.visit_item(self.expect_item(*id));
|
||||
visitor.visit_item(self.expect_item_by_hir_id(*id));
|
||||
}
|
||||
|
||||
for id in &module.trait_items {
|
||||
@ -1293,7 +1293,7 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
|
||||
impl<'hir> print::PpAnn for Map<'hir> {
|
||||
fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) -> io::Result<()> {
|
||||
match nested {
|
||||
Nested::Item(id) => state.print_item(self.expect_item(id.id)),
|
||||
Nested::Item(id) => state.print_item(self.expect_item_by_hir_id(id.id)),
|
||||
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
|
||||
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
|
||||
Nested::Body(id) => state.print_expr(&self.body(id).value),
|
||||
|
@ -698,7 +698,7 @@ pub struct WhereEqPredicate {
|
||||
pub struct ModuleItems {
|
||||
// Use BTreeSets here so items are in the same order as in the
|
||||
// list of all items in Crate
|
||||
pub items: BTreeSet<NodeId>,
|
||||
pub items: BTreeSet<HirId>,
|
||||
pub trait_items: BTreeSet<TraitItemId>,
|
||||
pub impl_items: BTreeSet<ImplItemId>,
|
||||
}
|
||||
@ -722,7 +722,7 @@ pub struct Crate {
|
||||
// does, because it can affect the order in which errors are
|
||||
// detected, which in turn can make compile-fail tests yield
|
||||
// slightly different results.
|
||||
pub items: BTreeMap<NodeId, Item>,
|
||||
pub items: BTreeMap<HirId, Item>,
|
||||
|
||||
pub trait_items: BTreeMap<TraitItemId, TraitItem>,
|
||||
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
|
||||
@ -741,7 +741,7 @@ pub struct Crate {
|
||||
}
|
||||
|
||||
impl Crate {
|
||||
pub fn item(&self, id: NodeId) -> &Item {
|
||||
pub fn item(&self, id: HirId) -> &Item {
|
||||
&self.items[&id]
|
||||
}
|
||||
|
||||
@ -2215,7 +2215,7 @@ impl VariantData {
|
||||
// so it can fetched later.
|
||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ItemId {
|
||||
pub id: NodeId,
|
||||
pub id: HirId,
|
||||
}
|
||||
|
||||
/// An item
|
||||
|
@ -48,7 +48,7 @@ pub trait PpAnn {
|
||||
fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn try_fetch_item(&self, _: ast::NodeId) -> Option<&hir::Item> {
|
||||
fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item> {
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ impl PpAnn for NoAnn {}
|
||||
pub const NO_ANN: &dyn PpAnn = &NoAnn;
|
||||
|
||||
impl PpAnn for hir::Crate {
|
||||
fn try_fetch_item(&self, item: ast::NodeId) -> Option<&hir::Item> {
|
||||
fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item> {
|
||||
Some(self.item(item))
|
||||
}
|
||||
fn nested(&self, state: &mut State<'_>, nested: Nested) -> io::Result<()> {
|
||||
|
@ -292,7 +292,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
||||
match ty.node {
|
||||
TyKind::Def(item_id, _) => {
|
||||
let item = self.tcx.hir().expect_item(item_id.id);
|
||||
let item = self.tcx.hir().expect_item_by_hir_id(item_id.id);
|
||||
intravisit::walk_item(self, item);
|
||||
}
|
||||
_ => ()
|
||||
|
@ -638,7 +638,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
// `abstract type MyAnonTy<'b>: MyTrait<'b>;`
|
||||
// ^ ^ this gets resolved in the scope of
|
||||
// the exist_ty generics
|
||||
let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node {
|
||||
let (generics, bounds) = match self.tcx.hir().expect_item_by_hir_id(item_id.id).node
|
||||
{
|
||||
// named existential types are reached via TyKind::Path
|
||||
// this arm is for `impl Trait` in the types of statics, constants and locals
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
@ -678,8 +679,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
let parent_impl_id = hir::ImplItemId { hir_id: parent_id };
|
||||
let parent_trait_id = hir::TraitItemId { hir_id: parent_id };
|
||||
let krate = self.tcx.hir().forest.krate();
|
||||
let parent_node_id = self.tcx.hir().hir_to_node_id(parent_id);
|
||||
if !(krate.items.contains_key(&parent_node_id)
|
||||
|
||||
if !(krate.items.contains_key(&parent_id)
|
||||
|| krate.impl_items.contains_key(&parent_impl_id)
|
||||
|| krate.trait_items.contains_key(&parent_trait_id))
|
||||
{
|
||||
|
@ -108,12 +108,12 @@ pub(super) fn emit_va_arg(
|
||||
emit_ptr_va_arg(bx, addr, target_ty, false,
|
||||
Align::from_bytes(4).unwrap(), true)
|
||||
}
|
||||
// Windows Aarch64
|
||||
// Windows AArch64
|
||||
("aarch64", true) => {
|
||||
emit_ptr_va_arg(bx, addr, target_ty, false,
|
||||
Align::from_bytes(8).unwrap(), false)
|
||||
}
|
||||
// iOS Aarch64
|
||||
// iOS AArch64
|
||||
("aarch64", _) if target.target_os == "ios" => {
|
||||
emit_ptr_va_arg(bx, addr, target_ty, false,
|
||||
Align::from_bytes(8).unwrap(), true)
|
||||
|
@ -596,18 +596,6 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||
// This will cause the Microsoft linker to embed .natvis info into the PDB file
|
||||
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
|
||||
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
|
||||
// LLVM 5.0.0's lld-link frontend doesn't yet recognize, and chokes
|
||||
// on, the /NATVIS:... flags. LLVM 6 (or earlier) should at worst ignore
|
||||
// them, eventually mooting this workaround, per this landed patch:
|
||||
// https://github.com/llvm-mirror/lld/commit/27b9c4285364d8d76bb43839daa100
|
||||
if let Some(ref linker_path) = self.sess.opts.cg.linker {
|
||||
if let Some(linker_name) = Path::new(&linker_path).file_stem() {
|
||||
if linker_name.to_str().unwrap().to_lowercase() == "lld-link" {
|
||||
self.sess.warn("not embedding natvis: lld-link may not support the flag");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for entry in natvis_dir {
|
||||
match entry {
|
||||
Ok(entry) => {
|
||||
|
@ -413,6 +413,8 @@ impl<'tcx> EntryKind<'tcx> {
|
||||
EntryKind::ForeignFn(_) => Def::Fn(did),
|
||||
EntryKind::Method(_) => Def::Method(did),
|
||||
EntryKind::Type => Def::TyAlias(did),
|
||||
EntryKind::TypeParam => Def::TyParam(did),
|
||||
EntryKind::ConstParam => Def::ConstParam(did),
|
||||
EntryKind::Existential => Def::Existential(did),
|
||||
EntryKind::AssociatedType(_) => Def::AssociatedTy(did),
|
||||
EntryKind::AssociatedExistential(_) => Def::AssociatedExistential(did),
|
||||
|
@ -7,6 +7,7 @@ use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
|
||||
EncodedMetadata, ForeignModule};
|
||||
use rustc::hir::def::CtorKind;
|
||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc::hir::GenericParamKind;
|
||||
use rustc::hir::map::definitions::DefPathTable;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc::middle::dependency_format::Linkage;
|
||||
@ -692,7 +693,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
span: self.lazy(&tcx.def_span(def_id)),
|
||||
attributes: self.encode_attributes(attrs),
|
||||
children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
|
||||
tcx.hir().local_def_id(item_id.id).index
|
||||
tcx.hir().local_def_id_from_hir_id(item_id.id).index
|
||||
})),
|
||||
stability: self.encode_stability(def_id),
|
||||
deprecation: self.encode_deprecation(def_id),
|
||||
@ -1352,25 +1353,22 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_info_for_ty_param(&mut self,
|
||||
(def_id, Untracked(has_default)): (DefId, Untracked<bool>))
|
||||
-> Entry<'tcx> {
|
||||
debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id);
|
||||
fn encode_info_for_generic_param(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
entry_kind: EntryKind<'tcx>,
|
||||
encode_type: bool,
|
||||
) -> Entry<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
Entry {
|
||||
kind: EntryKind::Type,
|
||||
kind: entry_kind,
|
||||
visibility: self.lazy(&ty::Visibility::Public),
|
||||
span: self.lazy(&tcx.def_span(def_id)),
|
||||
attributes: LazySeq::empty(),
|
||||
children: LazySeq::empty(),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
|
||||
ty: if has_default {
|
||||
Some(self.encode_item_type(def_id))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
ty: if encode_type { Some(self.encode_item_type(def_id)) } else { None },
|
||||
inherent_impls: LazySeq::empty(),
|
||||
variances: LazySeq::empty(),
|
||||
generics: None,
|
||||
@ -1381,27 +1379,20 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_info_for_const_param(&mut self, def_id: DefId) -> Entry<'tcx> {
|
||||
fn encode_info_for_ty_param(
|
||||
&mut self,
|
||||
(def_id, Untracked(encode_type)): (DefId, Untracked<bool>),
|
||||
) -> Entry<'tcx> {
|
||||
debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id);
|
||||
self.encode_info_for_generic_param(def_id, EntryKind::TypeParam, encode_type)
|
||||
}
|
||||
|
||||
fn encode_info_for_const_param(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
) -> Entry<'tcx> {
|
||||
debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id);
|
||||
let tcx = self.tcx;
|
||||
Entry {
|
||||
kind: EntryKind::Type,
|
||||
visibility: self.lazy(&ty::Visibility::Public),
|
||||
span: self.lazy(&tcx.def_span(def_id)),
|
||||
attributes: LazySeq::empty(),
|
||||
children: LazySeq::empty(),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
|
||||
ty: Some(self.encode_item_type(def_id)),
|
||||
inherent_impls: LazySeq::empty(),
|
||||
variances: LazySeq::empty(),
|
||||
generics: None,
|
||||
predicates: None,
|
||||
predicates_defined_on: None,
|
||||
|
||||
mir: None,
|
||||
}
|
||||
self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true)
|
||||
}
|
||||
|
||||
fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
|
||||
@ -1748,18 +1739,18 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||
|
||||
fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
|
||||
for param in &generics.params {
|
||||
let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
|
||||
match param.kind {
|
||||
hir::GenericParamKind::Lifetime { .. } => {}
|
||||
hir::GenericParamKind::Type { ref default, .. } => {
|
||||
let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
|
||||
let has_default = Untracked(default.is_some());
|
||||
let encode_info = IsolatedEncoder::encode_info_for_ty_param;
|
||||
self.record(def_id, encode_info, (def_id, has_default));
|
||||
GenericParamKind::Lifetime { .. } => continue,
|
||||
GenericParamKind::Type { ref default, .. } => {
|
||||
self.record(
|
||||
def_id,
|
||||
IsolatedEncoder::encode_info_for_ty_param,
|
||||
(def_id, Untracked(default.is_some())),
|
||||
);
|
||||
}
|
||||
hir::GenericParamKind::Const { .. } => {
|
||||
let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
|
||||
let encode_info = IsolatedEncoder::encode_info_for_const_param;
|
||||
self.record(def_id, encode_info, def_id);
|
||||
GenericParamKind::Const { .. } => {
|
||||
self.record(def_id, IsolatedEncoder::encode_info_for_const_param, def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +299,8 @@ pub enum EntryKind<'tcx> {
|
||||
ForeignType,
|
||||
GlobalAsm,
|
||||
Type,
|
||||
TypeParam,
|
||||
ConstParam,
|
||||
Existential,
|
||||
Enum(ReprOptions),
|
||||
Field,
|
||||
@ -335,7 +337,9 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
|
||||
EntryKind::ForeignType |
|
||||
EntryKind::Field |
|
||||
EntryKind::Existential |
|
||||
EntryKind::Type => {
|
||||
EntryKind::Type |
|
||||
EntryKind::TypeParam |
|
||||
EntryKind::ConstParam => {
|
||||
// Nothing else to hash here.
|
||||
}
|
||||
EntryKind::Const(qualif, ref const_data) => {
|
||||
|
@ -472,8 +472,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||
{
|
||||
if let hir::ItemKind::Mod(m) = &item.node {
|
||||
for item_id in m.item_ids.as_ref() {
|
||||
let item = self.tcx.hir().expect_item(item_id.id);
|
||||
let def_id = self.tcx.hir().local_def_id(item_id.id);
|
||||
let item = self.tcx.hir().expect_item_by_hir_id(item_id.id);
|
||||
let def_id = self.tcx.hir().local_def_id_from_hir_id(item_id.id);
|
||||
if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; }
|
||||
if let hir::ItemKind::Use(..) = item.node {
|
||||
self.update(item.hir_id, Some(AccessLevel::Exported));
|
||||
@ -737,8 +737,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||
unreachable!()
|
||||
};
|
||||
for id in &module.item_ids {
|
||||
let hir_id = self.tcx.hir().node_to_hir_id(id.id);
|
||||
self.update(hir_id, level);
|
||||
self.update(id.id, level);
|
||||
}
|
||||
let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id);
|
||||
if let Some(exports) = self.tcx.module_exports(def_id) {
|
||||
|
@ -1817,7 +1817,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
self.def_to_ty(opt_self_ty, path, false)
|
||||
}
|
||||
hir::TyKind::Def(item_id, ref lifetimes) => {
|
||||
let did = tcx.hir().local_def_id(item_id.id);
|
||||
let did = tcx.hir().local_def_id_from_hir_id(item_id.id);
|
||||
self.impl_trait_ty_to_ty(did, lifetimes)
|
||||
},
|
||||
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
||||
|
@ -853,7 +853,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, '
|
||||
}
|
||||
// Find a `use` statement.
|
||||
for item_id in &module.item_ids {
|
||||
let item = self.tcx.hir().expect_item(item_id.id);
|
||||
let item = self.tcx.hir().expect_item_by_hir_id(item_id.id);
|
||||
match item.node {
|
||||
hir::ItemKind::Use(..) => {
|
||||
// Don't suggest placing a `use` before the prelude
|
||||
|
@ -278,16 +278,16 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
};
|
||||
let primitives = if root.is_local() {
|
||||
cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| {
|
||||
let item = cx.tcx.hir().expect_item(id.id);
|
||||
let item = cx.tcx.hir().expect_item_by_hir_id(id.id);
|
||||
match item.node {
|
||||
hir::ItemKind::Mod(_) => {
|
||||
as_primitive(Def::Mod(cx.tcx.hir().local_def_id(id.id)))
|
||||
as_primitive(Def::Mod(cx.tcx.hir().local_def_id_from_hir_id(id.id)))
|
||||
}
|
||||
hir::ItemKind::Use(ref path, hir::UseKind::Single)
|
||||
if item.vis.node.is_pub() => {
|
||||
as_primitive(path.def).map(|(_, prim, attrs)| {
|
||||
// Pretend the primitive is local.
|
||||
(cx.tcx.hir().local_def_id(id.id), prim, attrs)
|
||||
(cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
@ -320,15 +320,15 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
};
|
||||
let keywords = if root.is_local() {
|
||||
cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| {
|
||||
let item = cx.tcx.hir().expect_item(id.id);
|
||||
let item = cx.tcx.hir().expect_item_by_hir_id(id.id);
|
||||
match item.node {
|
||||
hir::ItemKind::Mod(_) => {
|
||||
as_keyword(Def::Mod(cx.tcx.hir().local_def_id(id.id)))
|
||||
as_keyword(Def::Mod(cx.tcx.hir().local_def_id_from_hir_id(id.id)))
|
||||
}
|
||||
hir::ItemKind::Use(ref path, hir::UseKind::Single)
|
||||
if item.vis.node.is_pub() => {
|
||||
as_keyword(path.def).map(|(_, prim, attrs)| {
|
||||
(cx.tcx.hir().local_def_id(id.id), prim, attrs)
|
||||
(cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
@ -2762,7 +2762,7 @@ impl Clean<Type> for hir::Ty {
|
||||
},
|
||||
TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
|
||||
TyKind::Def(item_id, _) => {
|
||||
let item = cx.tcx.hir().expect_item(item_id.id);
|
||||
let item = cx.tcx.hir().expect_item_by_hir_id(item_id.id);
|
||||
if let hir::ItemKind::Existential(ref ty) = item.node {
|
||||
ImplTrait(ty.bounds.clean(cx))
|
||||
} else {
|
||||
@ -4393,10 +4393,10 @@ pub fn path_to_def_local(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefI
|
||||
let segment = path_it.next()?;
|
||||
|
||||
for item_id in mem::replace(&mut items, HirVec::new()).iter() {
|
||||
let item = tcx.hir().expect_item(item_id.id);
|
||||
let item = tcx.hir().expect_item_by_hir_id(item_id.id);
|
||||
if item.ident.name == *segment {
|
||||
if path_it.peek().is_none() {
|
||||
return Some(tcx.hir().local_def_id(item_id.id))
|
||||
return Some(tcx.hir().local_def_id_from_hir_id(item_id.id))
|
||||
}
|
||||
|
||||
items = match &item.node {
|
||||
|
@ -247,7 +247,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
let orig_inside_public_path = self.inside_public_path;
|
||||
self.inside_public_path &= vis.node.is_pub();
|
||||
for i in &m.item_ids {
|
||||
let item = self.cx.tcx.hir().expect_item(i.id);
|
||||
let item = self.cx.tcx.hir().expect_item_by_hir_id(i.id);
|
||||
self.visit_item(item, None, &mut om);
|
||||
}
|
||||
self.inside_public_path = orig_inside_public_path;
|
||||
@ -344,7 +344,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
Node::Item(&hir::Item { node: hir::ItemKind::Mod(ref m), .. }) if glob => {
|
||||
let prev = mem::replace(&mut self.inlining, true);
|
||||
for i in &m.item_ids {
|
||||
let i = self.cx.tcx.hir().expect_item(i.id);
|
||||
let i = self.cx.tcx.hir().expect_item_by_hir_id(i.id);
|
||||
self.visit_item(i, None, om);
|
||||
}
|
||||
self.inlining = prev;
|
||||
|
@ -21,6 +21,10 @@ use crate::memchr;
|
||||
/// times. It also provides no advantage when reading from a source that is
|
||||
/// already in memory, like a `Vec<u8>`.
|
||||
///
|
||||
/// When the `BufReader` is dropped, the contents of its buffer will be
|
||||
/// discarded. Creating multiple instances of a `BufReader` on the same
|
||||
/// stream can cause data loss.
|
||||
///
|
||||
/// [`Read`]: ../../std/io/trait.Read.html
|
||||
/// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
|
||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
||||
@ -350,7 +354,7 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with something that
|
||||
/// implements [`Write`]. For example, every call to
|
||||
/// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A
|
||||
/// [`write`][`TcpStream::write`] on [`TcpStream`] results in a system call. A
|
||||
/// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
|
||||
/// writer in large, infrequent batches.
|
||||
///
|
||||
@ -401,7 +405,7 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||
/// the `stream` is dropped.
|
||||
///
|
||||
/// [`Write`]: ../../std/io/trait.Write.html
|
||||
/// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
|
||||
/// [`TcpStream::write`]: ../../std/net/struct.TcpStream.html#method.write
|
||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
||||
/// [`flush`]: #method.flush
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -286,11 +286,16 @@ mod fn_keyword { }
|
||||
//
|
||||
/// The `for` keyword.
|
||||
///
|
||||
/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as
|
||||
/// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more
|
||||
/// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice
|
||||
/// within Rust, which is to loop over an iterator until that iterator returns `None` (or `break`
|
||||
/// is called).
|
||||
/// The `for` keyword is used in many syntactic locations:
|
||||
///
|
||||
/// * `for` is used in for-in-loops (see below).
|
||||
/// * `for` is used when implementing traits as in `impl Trait for Type` (see [`impl`] for more info
|
||||
/// on that).
|
||||
/// * `for` is also used for [higher-ranked trait bounds] as in `for<'a> &'a T: PartialEq<i32>`.
|
||||
///
|
||||
/// for-in-loops, or to be more precise, iterator loops, are a simple syntactic sugar over a common
|
||||
/// practice within Rust, which is to loop over an iterator until that iterator returns `None` (or
|
||||
/// `break` is called).
|
||||
///
|
||||
/// ```rust
|
||||
/// for i in 0..5 {
|
||||
@ -347,6 +352,8 @@ 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
|
||||
/// [`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
|
||||
|
@ -4,7 +4,7 @@
|
||||
//! library. Each macro is available for use when linking against the standard
|
||||
//! library.
|
||||
|
||||
/// The entry point for panic of Rust threads.
|
||||
/// Panics the current thread.
|
||||
///
|
||||
/// This allows a program to terminate immediately and provide feedback
|
||||
/// to the caller of the program. `panic!` should be used when a program reaches
|
||||
@ -70,7 +70,7 @@ macro_rules! panic {
|
||||
});
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard output.
|
||||
/// Prints to the standard output.
|
||||
///
|
||||
/// Equivalent to the [`println!`] macro except that a newline is not printed at
|
||||
/// the end of the message.
|
||||
@ -116,7 +116,7 @@ macro_rules! print {
|
||||
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard output, with a newline.
|
||||
/// Prints to the standard output, with a newline.
|
||||
///
|
||||
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
|
||||
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
|
||||
@ -151,7 +151,7 @@ macro_rules! println {
|
||||
})
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard error.
|
||||
/// Prints to the standard error.
|
||||
///
|
||||
/// Equivalent to the [`print!`] macro, except that output goes to
|
||||
/// [`io::stderr`] instead of `io::stdout`. See [`print!`] for
|
||||
@ -179,7 +179,7 @@ macro_rules! eprint {
|
||||
($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard error, with a newline.
|
||||
/// Prints to the standard error, with a newline.
|
||||
///
|
||||
/// Equivalent to the [`println!`] macro, except that output goes to
|
||||
/// [`io::stderr`] instead of `io::stdout`. See [`println!`] for
|
||||
@ -210,8 +210,10 @@ macro_rules! eprintln {
|
||||
})
|
||||
}
|
||||
|
||||
/// A macro for quick and dirty debugging with which you can inspect
|
||||
/// the value of a given expression. An example:
|
||||
/// Prints and returns the value of a given expression for quick and dirty
|
||||
/// debugging.
|
||||
///
|
||||
/// An example:
|
||||
///
|
||||
/// ```rust
|
||||
/// let a = 2;
|
||||
@ -328,7 +330,7 @@ macro_rules! dbg {
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro to await on an async call.
|
||||
/// Awaits the completion of an async call.
|
||||
#[macro_export]
|
||||
#[unstable(feature = "await_macro", issue = "50547")]
|
||||
#[allow_internal_unstable(gen_future, generators)]
|
||||
@ -351,7 +353,7 @@ macro_rules! r#await {
|
||||
} }
|
||||
}
|
||||
|
||||
/// A macro to select an event from a number of receivers.
|
||||
/// Selects the first successful receive event from a number of receivers.
|
||||
///
|
||||
/// This macro is used to wait for the first event to occur on a number of
|
||||
/// receivers. It places no restrictions on the types of receivers given to
|
||||
@ -423,7 +425,7 @@ macro_rules! assert_approx_eq {
|
||||
#[cfg(rustdoc)]
|
||||
mod builtin {
|
||||
|
||||
/// Unconditionally causes compilation to fail with the given error message when encountered.
|
||||
/// Causes compilation to fail with the given error message when encountered.
|
||||
///
|
||||
/// This macro should be used when a crate uses a conditional compilation strategy to provide
|
||||
/// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
|
||||
@ -465,7 +467,7 @@ mod builtin {
|
||||
($msg:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// The core macro for formatted string creation & output.
|
||||
/// Constructs parameters for the other string-formatting macros.
|
||||
///
|
||||
/// This macro functions by taking a formatting string literal containing
|
||||
/// `{}` for each additional argument passed. `format_args!` prepares the
|
||||
@ -517,7 +519,7 @@ mod builtin {
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Inspect an environment variable at compile time.
|
||||
/// Inspects an environment variable at compile time.
|
||||
///
|
||||
/// This macro will expand to the value of the named environment variable at
|
||||
/// compile time, yielding an expression of type `&'static str`.
|
||||
@ -555,7 +557,7 @@ mod builtin {
|
||||
($name:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Optionally inspect an environment variable at compile time.
|
||||
/// Optionally inspects an environment variable at compile time.
|
||||
///
|
||||
/// If the named environment variable is present at compile time, this will
|
||||
/// expand into an expression of type `Option<&'static str>` whose value is
|
||||
@ -581,7 +583,7 @@ mod builtin {
|
||||
($name:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Concatenate identifiers into one identifier.
|
||||
/// Concatenates identifiers into one identifier.
|
||||
///
|
||||
/// This macro takes any number of comma-separated identifiers, and
|
||||
/// concatenates them all into one, yielding an expression which is a new
|
||||
@ -634,7 +636,7 @@ mod builtin {
|
||||
($($e:expr,)*) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// A macro which expands to the line number on which it was invoked.
|
||||
/// Expands to the line number on which it was invoked.
|
||||
///
|
||||
/// With [`column!`] and [`file!`], these macros provide debugging information for
|
||||
/// developers about the location within the source.
|
||||
@ -659,7 +661,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! line { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// A macro which expands to the column number on which it was invoked.
|
||||
/// Expands to the column number at which it was invoked.
|
||||
///
|
||||
/// With [`line!`] and [`file!`], these macros provide debugging information for
|
||||
/// developers about the location within the source.
|
||||
@ -684,7 +686,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! column { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// A macro which expands to the file name from which it was invoked.
|
||||
/// Expands to the file name in which it was invoked.
|
||||
///
|
||||
/// With [`line!`] and [`column!`], these macros provide debugging information for
|
||||
/// developers about the location within the source.
|
||||
@ -708,7 +710,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! file { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// A macro which stringifies its arguments.
|
||||
/// Stringifies its arguments.
|
||||
///
|
||||
/// This macro will yield an expression of type `&'static str` which is the
|
||||
/// stringification of all the tokens passed to the macro. No restrictions
|
||||
@ -822,7 +824,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! module_path { () => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// Boolean evaluation of configuration flags, at compile-time.
|
||||
/// Evaluates boolean combinations of configuration flags at compile-time.
|
||||
///
|
||||
/// In addition to the `#[cfg]` attribute, this macro is provided to allow
|
||||
/// boolean expression evaluation of configuration flags. This frequently
|
||||
@ -844,7 +846,7 @@ mod builtin {
|
||||
#[rustc_doc_only_macro]
|
||||
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
|
||||
|
||||
/// Parse a file as an expression or an item according to the context.
|
||||
/// Parses a file as an expression or an item according to the context.
|
||||
///
|
||||
/// The file is located relative to the current file (similarly to how
|
||||
/// modules are found).
|
||||
@ -890,7 +892,7 @@ mod builtin {
|
||||
($file:expr,) => ({ /* compiler built-in */ });
|
||||
}
|
||||
|
||||
/// Ensure that a boolean expression is `true` at runtime.
|
||||
/// Asserts that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
||||
/// evaluated to `true` at runtime.
|
||||
@ -944,7 +946,7 @@ mod builtin {
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro for defining `#[cfg]` if-else statements.
|
||||
/// Defines `#[cfg]` if-else statements.
|
||||
///
|
||||
/// This is similar to the `if/elif` C preprocessor macro by allowing definition
|
||||
/// of a cascade of `#[cfg]` cases, emitting the implementation which matches
|
||||
|
@ -827,30 +827,54 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
||||
Ok(PathBuf::from(OsString::from_vec(buf)))
|
||||
}
|
||||
|
||||
fn open_and_set_permissions(
|
||||
from: &Path,
|
||||
to: &Path,
|
||||
) -> io::Result<(crate::fs::File, crate::fs::File, u64, crate::fs::Metadata)> {
|
||||
use crate::fs::{File, OpenOptions};
|
||||
use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt};
|
||||
|
||||
let reader = File::open(from)?;
|
||||
let (perm, len) = {
|
||||
let metadata = reader.metadata()?;
|
||||
if !metadata.is_file() {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file",
|
||||
));
|
||||
}
|
||||
(metadata.permissions(), metadata.len())
|
||||
};
|
||||
let writer = OpenOptions::new()
|
||||
// create the file with the correct mode right away
|
||||
.mode(perm.mode())
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(to)?;
|
||||
let writer_metadata = writer.metadata()?;
|
||||
if writer_metadata.is_file() {
|
||||
// Set the correct file permissions, in case the file already existed.
|
||||
// Don't set the permissions on already existing non-files like
|
||||
// pipes/FIFOs or device nodes.
|
||||
writer.set_permissions(perm)?;
|
||||
}
|
||||
Ok((reader, writer, len, writer_metadata))
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "macos",
|
||||
target_os = "ios")))]
|
||||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
use crate::fs::File;
|
||||
if !from.is_file() {
|
||||
return Err(Error::new(ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file"))
|
||||
}
|
||||
let (mut reader, mut writer, _, _) = open_and_set_permissions(from, to)?;
|
||||
|
||||
let mut reader = File::open(from)?;
|
||||
let mut writer = File::create(to)?;
|
||||
let perm = reader.metadata()?.permissions();
|
||||
|
||||
let ret = io::copy(&mut reader, &mut writer)?;
|
||||
writer.set_permissions(perm)?;
|
||||
Ok(ret)
|
||||
io::copy(&mut reader, &mut writer)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
use crate::cmp;
|
||||
use crate::fs::File;
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
// Kernel prior to 4.5 don't have copy_file_range
|
||||
@ -876,17 +900,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
)
|
||||
}
|
||||
|
||||
if !from.is_file() {
|
||||
return Err(Error::new(ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file"))
|
||||
}
|
||||
|
||||
let mut reader = File::open(from)?;
|
||||
let mut writer = File::create(to)?;
|
||||
let (perm, len) = {
|
||||
let metadata = reader.metadata()?;
|
||||
(metadata.permissions(), metadata.size())
|
||||
};
|
||||
let (mut reader, mut writer, len, _) = open_and_set_permissions(from, to)?;
|
||||
|
||||
let has_copy_file_range = HAS_COPY_FILE_RANGE.load(Ordering::Relaxed);
|
||||
let mut written = 0u64;
|
||||
@ -896,13 +910,14 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
let copy_result = unsafe {
|
||||
// We actually don't have to adjust the offsets,
|
||||
// because copy_file_range adjusts the file offset automatically
|
||||
cvt(copy_file_range(reader.as_raw_fd(),
|
||||
ptr::null_mut(),
|
||||
writer.as_raw_fd(),
|
||||
ptr::null_mut(),
|
||||
bytes_to_copy,
|
||||
0)
|
||||
)
|
||||
cvt(copy_file_range(
|
||||
reader.as_raw_fd(),
|
||||
ptr::null_mut(),
|
||||
writer.as_raw_fd(),
|
||||
ptr::null_mut(),
|
||||
bytes_to_copy,
|
||||
0,
|
||||
))
|
||||
};
|
||||
if let Err(ref copy_err) = copy_result {
|
||||
match copy_err.raw_os_error() {
|
||||
@ -920,24 +935,25 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
Ok(ret) => written += ret as u64,
|
||||
Err(err) => {
|
||||
match err.raw_os_error() {
|
||||
Some(os_err) if os_err == libc::ENOSYS
|
||||
|| os_err == libc::EXDEV
|
||||
|| os_err == libc::EPERM => {
|
||||
// Try fallback io::copy if either:
|
||||
// - Kernel version is < 4.5 (ENOSYS)
|
||||
// - Files are mounted on different fs (EXDEV)
|
||||
// - copy_file_range is disallowed, for example by seccomp (EPERM)
|
||||
assert_eq!(written, 0);
|
||||
let ret = io::copy(&mut reader, &mut writer)?;
|
||||
writer.set_permissions(perm)?;
|
||||
return Ok(ret)
|
||||
},
|
||||
Some(os_err)
|
||||
if os_err == libc::ENOSYS
|
||||
|| os_err == libc::EXDEV
|
||||
|| os_err == libc::EINVAL
|
||||
|| os_err == libc::EPERM =>
|
||||
{
|
||||
// Try fallback io::copy if either:
|
||||
// - Kernel version is < 4.5 (ENOSYS)
|
||||
// - Files are mounted on different fs (EXDEV)
|
||||
// - copy_file_range is disallowed, for example by seccomp (EPERM)
|
||||
// - copy_file_range cannot be used with pipes or device nodes (EINVAL)
|
||||
assert_eq!(written, 0);
|
||||
return io::copy(&mut reader, &mut writer);
|
||||
}
|
||||
_ => return Err(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.set_permissions(perm)?;
|
||||
Ok(written)
|
||||
}
|
||||
|
||||
@ -960,9 +976,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
type copyfile_flags_t = u32;
|
||||
|
||||
extern "C" {
|
||||
fn copyfile(
|
||||
from: *const libc::c_char,
|
||||
to: *const libc::c_char,
|
||||
fn fcopyfile(
|
||||
from: libc::c_int,
|
||||
to: libc::c_int,
|
||||
state: copyfile_state_t,
|
||||
flags: copyfile_flags_t,
|
||||
) -> libc::c_int;
|
||||
@ -988,10 +1004,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
}
|
||||
}
|
||||
|
||||
if !from.is_file() {
|
||||
return Err(Error::new(ErrorKind::InvalidInput,
|
||||
"the source path is not an existing regular file"))
|
||||
}
|
||||
let (reader, writer, _, writer_metadata) = open_and_set_permissions(from, to)?;
|
||||
|
||||
// We ensure that `FreeOnDrop` never contains a null pointer so it is
|
||||
// always safe to call `copyfile_state_free`
|
||||
@ -1003,12 +1016,18 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
FreeOnDrop(state)
|
||||
};
|
||||
|
||||
let flags = if writer_metadata.is_file() {
|
||||
COPYFILE_ALL
|
||||
} else {
|
||||
COPYFILE_DATA
|
||||
};
|
||||
|
||||
cvt(unsafe {
|
||||
copyfile(
|
||||
cstr(from)?.as_ptr(),
|
||||
cstr(to)?.as_ptr(),
|
||||
fcopyfile(
|
||||
reader.as_raw_fd(),
|
||||
writer.as_raw_fd(),
|
||||
state.0,
|
||||
COPYFILE_ALL,
|
||||
flags,
|
||||
)
|
||||
})?;
|
||||
|
||||
|
@ -4734,7 +4734,7 @@ impl<'a> Parser<'a> {
|
||||
let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
|
||||
e.emit();
|
||||
self.recover_stmt();
|
||||
(vec![], false)
|
||||
(vec![], true)
|
||||
});
|
||||
self.bump();
|
||||
pat = PatKind::Struct(path, fields, etc);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![allow(deprecated)]
|
||||
// ignore-cloudabi no files or I/O
|
||||
// ignore-wasm32-bare no files or I/O
|
||||
// ignore-emscripten no files
|
||||
|
||||
use std::fs;
|
||||
use std::io;
|
||||
@ -22,14 +23,18 @@ fn main() {
|
||||
assert_invalid_input("remove_file", fs::remove_file("\0"));
|
||||
assert_invalid_input("metadata", fs::metadata("\0"));
|
||||
assert_invalid_input("symlink_metadata", fs::symlink_metadata("\0"));
|
||||
|
||||
// If `dummy_file` does not exist, then we might get another unrelated error
|
||||
let dummy_file = std::env::current_exe().unwrap();
|
||||
|
||||
assert_invalid_input("rename1", fs::rename("\0", "a"));
|
||||
assert_invalid_input("rename2", fs::rename("a", "\0"));
|
||||
assert_invalid_input("rename2", fs::rename(&dummy_file, "\0"));
|
||||
assert_invalid_input("copy1", fs::copy("\0", "a"));
|
||||
assert_invalid_input("copy2", fs::copy("a", "\0"));
|
||||
assert_invalid_input("copy2", fs::copy(&dummy_file, "\0"));
|
||||
assert_invalid_input("hard_link1", fs::hard_link("\0", "a"));
|
||||
assert_invalid_input("hard_link2", fs::hard_link("a", "\0"));
|
||||
assert_invalid_input("hard_link2", fs::hard_link(&dummy_file, "\0"));
|
||||
assert_invalid_input("soft_link1", fs::soft_link("\0", "a"));
|
||||
assert_invalid_input("soft_link2", fs::soft_link("a", "\0"));
|
||||
assert_invalid_input("soft_link2", fs::soft_link(&dummy_file, "\0"));
|
||||
assert_invalid_input("read_link", fs::read_link("\0"));
|
||||
assert_invalid_input("canonicalize", fs::canonicalize("\0"));
|
||||
assert_invalid_input("create_dir", fs::create_dir("\0"));
|
||||
|
@ -2,7 +2,6 @@ fn main() {
|
||||
struct Foo { x: isize }
|
||||
match (Foo { x: 10 }) {
|
||||
Foo { ref x: ref x } => {}, //~ ERROR expected `,`
|
||||
//~| ERROR pattern does not mention field `x`
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,5 @@ error: expected `,`
|
||||
LL | Foo { ref x: ref x } => {},
|
||||
| ^
|
||||
|
||||
error[E0027]: pattern does not mention field `x`
|
||||
--> $DIR/bind-struct-early-modifiers.rs:4:9
|
||||
|
|
||||
LL | Foo { ref x: ref x } => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^ missing field `x`
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0027`.
|
||||
|
@ -4,5 +4,4 @@ fn a() -> A { panic!() }
|
||||
|
||||
fn main() {
|
||||
let A { , } = a(); //~ ERROR expected ident
|
||||
//~| ERROR pattern does not mention field `foo`
|
||||
}
|
||||
|
@ -4,12 +4,5 @@ error: expected identifier, found `,`
|
||||
LL | let A { , } = a();
|
||||
| ^ expected identifier
|
||||
|
||||
error[E0027]: pattern does not mention field `foo`
|
||||
--> $DIR/issue-10392.rs:6:9
|
||||
|
|
||||
LL | let A { , } = a();
|
||||
| ^^^^^^^ missing field `foo`
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0027`.
|
||||
|
@ -6,7 +6,7 @@ fn main() {
|
||||
let thing = MyStruct { s1: None };
|
||||
|
||||
match thing {
|
||||
MyStruct { .., Some(_) } => {}, //~ ERROR pattern does not mention field `s1`
|
||||
MyStruct { .., Some(_) } => {},
|
||||
//~^ ERROR expected `,`
|
||||
//~| ERROR expected `}`, found `,`
|
||||
_ => {}
|
||||
|
@ -13,12 +13,5 @@ error: expected `,`
|
||||
LL | MyStruct { .., Some(_) } => {},
|
||||
| ^^^^
|
||||
|
||||
error[E0027]: pattern does not mention field `s1`
|
||||
--> $DIR/issue-54379.rs:9:9
|
||||
|
|
||||
LL | MyStruct { .., Some(_) } => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ missing field `s1`
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0027`.
|
||||
|
@ -27,9 +27,10 @@ enum OutputFormat {
|
||||
}
|
||||
|
||||
impl OutputFormat {
|
||||
fn from(format: &str) -> OutputFormat {
|
||||
fn from(format: &str, resource_suffix: &str) -> OutputFormat {
|
||||
match &*format.to_lowercase() {
|
||||
"html" => OutputFormat::HTML(HTMLFormatter(RefCell::new(IdMap::new()))),
|
||||
"html" => OutputFormat::HTML(HTMLFormatter(RefCell::new(IdMap::new()),
|
||||
resource_suffix.to_owned())),
|
||||
"markdown" => OutputFormat::Markdown(MarkdownFormatter),
|
||||
s => OutputFormat::Unknown(s.to_owned()),
|
||||
}
|
||||
@ -44,7 +45,7 @@ trait Formatter {
|
||||
fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
|
||||
}
|
||||
|
||||
struct HTMLFormatter(RefCell<IdMap>);
|
||||
struct HTMLFormatter(RefCell<IdMap>, String);
|
||||
struct MarkdownFormatter;
|
||||
|
||||
impl Formatter for HTMLFormatter {
|
||||
@ -55,7 +56,7 @@ impl Formatter for HTMLFormatter {
|
||||
<title>Rust Compiler Error Index</title>
|
||||
<meta charset="utf-8">
|
||||
<!-- Include rust.css after light.css so its rules take priority. -->
|
||||
<link rel="stylesheet" type="text/css" href="light.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="light{suffix}.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="rust.css"/>
|
||||
<style>
|
||||
.error-undescribed {{
|
||||
@ -64,7 +65,7 @@ impl Formatter for HTMLFormatter {
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
"##)?;
|
||||
"##, suffix=self.1)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -242,9 +243,12 @@ fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Erro
|
||||
|
||||
fn parse_args() -> (OutputFormat, PathBuf) {
|
||||
let mut args = env::args().skip(1);
|
||||
let format = args.next().map(|a| OutputFormat::from(&a))
|
||||
.unwrap_or(OutputFormat::from("html"));
|
||||
let dst = args.next().map(PathBuf::from).unwrap_or_else(|| {
|
||||
let format = args.next();
|
||||
let dst = args.next();
|
||||
let resource_suffix = args.next().unwrap_or_else(String::new);
|
||||
let format = format.map(|a| OutputFormat::from(&a, &resource_suffix))
|
||||
.unwrap_or(OutputFormat::from("html", &resource_suffix));
|
||||
let dst = dst.map(PathBuf::from).unwrap_or_else(|| {
|
||||
match format {
|
||||
OutputFormat::HTML(..) => PathBuf::from("doc/error-index.html"),
|
||||
OutputFormat::Markdown(..) => PathBuf::from("doc/error-index.md"),
|
||||
|
Loading…
Reference in New Issue
Block a user