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:
bors 2019-03-28 08:56:34 +00:00
commit 237bf3244f
35 changed files with 341 additions and 298 deletions

View File

@ -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 {

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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!`].
///

View File

@ -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);
}

View File

@ -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 {

View File

@ -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),

View File

@ -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

View File

@ -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<()> {

View File

@ -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);
}
_ => ()

View File

@ -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))
{

View File

@ -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)

View File

@ -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) => {

View File

@ -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),

View File

@ -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);
}
}
}

View File

@ -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) => {

View File

@ -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) {

View File

@ -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)) => {

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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")]

View File

@ -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

View File

@ -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

View File

@ -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,
)
})?;

View File

@ -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);

View File

@ -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"));

View File

@ -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`
_ => {}
}
}

View File

@ -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`.

View File

@ -4,5 +4,4 @@ fn a() -> A { panic!() }
fn main() {
let A { , } = a(); //~ ERROR expected ident
//~| ERROR pattern does not mention field `foo`
}

View File

@ -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`.

View File

@ -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 `,`
_ => {}

View File

@ -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`.

View File

@ -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"),