From b524ade782d20b63b84febbcfe58e2b54bfe7ab8 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 19 Feb 2019 21:20:45 +0000 Subject: [PATCH 01/25] Refactor generic parameter encoder functions --- src/librustc_metadata/encoder.rs | 60 ++++++++++---------------------- 1 file changed, 18 insertions(+), 42 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index ce0618d4599e7..ed1113677d044 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -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; @@ -1307,10 +1308,11 @@ 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)) - -> Entry<'tcx> { - debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id); + fn encode_info_for_generic_param( + &mut self, + (def_id, Untracked(encode_type)): (DefId, Untracked), + ) -> Entry<'tcx> { + debug!("IsolatedEncoder::encode_info_for_generic_param({:?})", def_id); let tcx = self.tcx; Entry { kind: EntryKind::Type, @@ -1321,7 +1323,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { stability: None, deprecation: None, - ty: if has_default { + ty: if encode_type { Some(self.encode_item_type(def_id)) } else { None @@ -1336,29 +1338,6 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } } - 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, - } - } - fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> { debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id); let tcx = self.tcx; @@ -1703,20 +1682,17 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_info_for_generics(&mut self, generics: &hir::Generics) { for param in &generics.params { - 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)); - } - 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); - } - } + let encode_type = match param.kind { + GenericParamKind::Lifetime { .. } => continue, + GenericParamKind::Type { ref default, .. } => default.is_some(), + GenericParamKind::Const { .. } => true, + }; + let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id); + self.record( + def_id, + IsolatedEncoder::encode_info_for_generic_param, + (def_id, Untracked(encode_type)), + ); } } From 7a23725e48617b797779971ca077742a1b984dc6 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 26 Feb 2019 21:11:02 +0000 Subject: [PATCH 02/25] Rename encode_info_for_generic_param to encode_info_for_ty_in_generic_param --- src/librustc_metadata/encoder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index ed1113677d044..712dc869a7d09 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1308,11 +1308,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } } - fn encode_info_for_generic_param( + fn encode_info_for_ty_in_generic_param( &mut self, (def_id, Untracked(encode_type)): (DefId, Untracked), ) -> Entry<'tcx> { - debug!("IsolatedEncoder::encode_info_for_generic_param({:?})", def_id); + debug!("IsolatedEncoder::encode_info_for_ty_in_generic_param({:?})", def_id); let tcx = self.tcx; Entry { kind: EntryKind::Type, @@ -1690,7 +1690,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id); self.record( def_id, - IsolatedEncoder::encode_info_for_generic_param, + IsolatedEncoder::encode_info_for_ty_in_generic_param, (def_id, Untracked(encode_type)), ); } From 6217ee12824574256ca22e848db9421210e0ceed Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 14 Mar 2019 00:14:33 +0000 Subject: [PATCH 03/25] Add `EntryKind::TypeParam` and `EntryKind::ConstParam` --- src/librustc_metadata/decoder.rs | 2 ++ src/librustc_metadata/encoder.rs | 55 ++++++++++++++++++++------------ src/librustc_metadata/schema.rs | 6 +++- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 6fe00a4ad2ff2..ca76de613914d 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -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), diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 712dc869a7d09..1edcef8f14c62 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1308,26 +1308,22 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } } - fn encode_info_for_ty_in_generic_param( + fn encode_info_for_generic_param( &mut self, - (def_id, Untracked(encode_type)): (DefId, Untracked), + def_id: DefId, + entry_kind: EntryKind<'tcx>, + encode_type: bool, ) -> Entry<'tcx> { - debug!("IsolatedEncoder::encode_info_for_ty_in_generic_param({:?})", def_id); 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 encode_type { - 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, @@ -1338,6 +1334,22 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } } + fn encode_info_for_ty_param( + &mut self, + (def_id, Untracked(encode_type)): (DefId, Untracked), + ) -> 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); + self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true) + } + fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> { debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id); let tcx = self.tcx; @@ -1682,17 +1694,20 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_info_for_generics(&mut self, generics: &hir::Generics) { for param in &generics.params { - let encode_type = match param.kind { - GenericParamKind::Lifetime { .. } => continue, - GenericParamKind::Type { ref default, .. } => default.is_some(), - GenericParamKind::Const { .. } => true, - }; let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id); - self.record( - def_id, - IsolatedEncoder::encode_info_for_ty_in_generic_param, - (def_id, Untracked(encode_type)), - ); + match param.kind { + GenericParamKind::Lifetime { .. } => continue, + GenericParamKind::Type { ref default, .. } => { + self.record( + def_id, + IsolatedEncoder::encode_info_for_ty_param, + (def_id, Untracked(default.is_some())), + ); + } + GenericParamKind::Const { .. } => { + self.record(def_id, IsolatedEncoder::encode_info_for_const_param, def_id); + } + } } } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index afeea9947b5e3..ff97134df35fc 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -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> 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) => { From 6cd6759cfcb9794dba4cc2a5a1fae6ae63706d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 14 Mar 2019 18:28:24 -0700 Subject: [PATCH 04/25] Do not complain about unmentioned fields in recovered patterns When the parser has to recover from malformed code in a pattern, do not complain about missing fields. --- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/parser/bind-struct-early-modifiers.rs | 1 - src/test/ui/parser/bind-struct-early-modifiers.stderr | 9 +-------- src/test/ui/parser/issue-10392.rs | 1 - src/test/ui/parser/issue-10392.stderr | 9 +-------- src/test/ui/resolve/issue-54379.rs | 2 +- src/test/ui/resolve/issue-54379.stderr | 9 +-------- 7 files changed, 5 insertions(+), 28 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fe31311094b89..a3894a332230e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4698,7 +4698,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); diff --git a/src/test/ui/parser/bind-struct-early-modifiers.rs b/src/test/ui/parser/bind-struct-early-modifiers.rs index c1de0df54e278..c4b1937de104f 100644 --- a/src/test/ui/parser/bind-struct-early-modifiers.rs +++ b/src/test/ui/parser/bind-struct-early-modifiers.rs @@ -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` _ => {} } } diff --git a/src/test/ui/parser/bind-struct-early-modifiers.stderr b/src/test/ui/parser/bind-struct-early-modifiers.stderr index 50c95b8cf4023..03482a41f5465 100644 --- a/src/test/ui/parser/bind-struct-early-modifiers.stderr +++ b/src/test/ui/parser/bind-struct-early-modifiers.stderr @@ -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 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/parser/issue-10392.rs b/src/test/ui/parser/issue-10392.rs index dd84af393003c..5b0c2fc2be407 100644 --- a/src/test/ui/parser/issue-10392.rs +++ b/src/test/ui/parser/issue-10392.rs @@ -4,5 +4,4 @@ fn a() -> A { panic!() } fn main() { let A { , } = a(); //~ ERROR expected ident - //~| ERROR pattern does not mention field `foo` } diff --git a/src/test/ui/parser/issue-10392.stderr b/src/test/ui/parser/issue-10392.stderr index 7bf5aa93f0a59..34991151c1eb6 100644 --- a/src/test/ui/parser/issue-10392.stderr +++ b/src/test/ui/parser/issue-10392.stderr @@ -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 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/resolve/issue-54379.rs b/src/test/ui/resolve/issue-54379.rs index a48f66bf0fda0..807c54393f29b 100644 --- a/src/test/ui/resolve/issue-54379.rs +++ b/src/test/ui/resolve/issue-54379.rs @@ -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 `,` _ => {} diff --git a/src/test/ui/resolve/issue-54379.stderr b/src/test/ui/resolve/issue-54379.stderr index 60a6f904610b6..2a6b54572de03 100644 --- a/src/test/ui/resolve/issue-54379.stderr +++ b/src/test/ui/resolve/issue-54379.stderr @@ -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 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0027`. From 727a15f296bce39383d0c08cd57e1575dea8950d Mon Sep 17 00:00:00 2001 From: James Duley Date: Sun, 20 Jan 2019 11:44:11 +0000 Subject: [PATCH 05/25] Fix aarch64 typo --- src/libcore/ffi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 5cc9c25c21e0f..3daa2474c521b 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -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 \ @@ -193,7 +193,7 @@ 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"), From 8485f58abf48cf893aa1af73629d0684962e0732 Mon Sep 17 00:00:00 2001 From: James Duley Date: Sun, 20 Jan 2019 11:47:29 +0000 Subject: [PATCH 06/25] Fix AArch64 typo in comments --- src/libcore/ffi.rs | 2 +- src/librustc_codegen_llvm/va_arg.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 3daa2474c521b..96dbfdcb57de4 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -67,7 +67,7 @@ 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 diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs index 7aceaea4510ce..7fc17d17f99df 100644 --- a/src/librustc_codegen_llvm/va_arg.rs +++ b/src/librustc_codegen_llvm/va_arg.rs @@ -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) From 62c159e500dac61dd6f20c8a50f1b1570ed481ee Mon Sep 17 00:00:00 2001 From: James Duley Date: Mon, 25 Feb 2019 18:08:57 +0000 Subject: [PATCH 07/25] Fix missing cfg for aarch64 + ios in ffi.rs --- src/libcore/ffi.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 96dbfdcb57de4..231a1f199bdd6 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -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 { @@ -71,7 +72,7 @@ impl fmt::Debug for VaListImpl { /// /// [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", @@ -197,10 +198,10 @@ impl<'a> VaList<'a> { 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 From 45e9accecb18cbdbadad05abeed860f68d7a46f3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 21 Mar 2019 23:29:47 +0100 Subject: [PATCH 08/25] Include llvm-ar with llvm-tools component --- src/bootstrap/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 976b30a55c94b..4887c9be6709a 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -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. From cf8347ba6bc82c41de2ad9bf561af593a89cbe45 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 28 Feb 2019 10:25:54 +0100 Subject: [PATCH 09/25] fs::copy() set file mode early A convenience method like fs::copy() should try to prevent pitfalls a normal user doesn't think about. In case of an empty umask, setting the file mode early prevents temporarily world readable or even writeable files, because the default mode is 0o666. In case the target is a named pipe or special device node, setting the file mode can lead to unwanted side effects, like setting permissons on `/dev/stdout` or for root setting permissions on `/dev/null`. copy_file_range() returns EINVAL, if the destination is a FIFO/pipe or a device like "/dev/null", so fallback to io::copy, too. Use `fcopyfile` on MacOS instead of `copyfile`. Fixes: https://github.com/rust-lang/rust/issues/26933 Fixed: https://github.com/rust-lang/rust/issues/37885 --- src/libstd/sys/unix/fs.rs | 129 +++++++++++++--------- src/test/run-pass/paths-containing-nul.rs | 13 ++- 2 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 7ff098bc9e123..c73f7983146d4 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -827,30 +827,54 @@ pub fn canonicalize(p: &Path) -> io::Result { 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 { - 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 { 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 { ) } - 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 { 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 { 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 { 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 { } } - 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 { 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, ) })?; diff --git a/src/test/run-pass/paths-containing-nul.rs b/src/test/run-pass/paths-containing-nul.rs index 8c800089d1ce3..dfcef59aa5782 100644 --- a/src/test/run-pass/paths-containing-nul.rs +++ b/src/test/run-pass/paths-containing-nul.rs @@ -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")); From 7dd8b776b5107f11bf0988d8c1947f49d2f6cec2 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 11 Mar 2019 09:44:19 +0100 Subject: [PATCH 10/25] hir: replace NodeId with HirId in ItemId --- src/librustc/hir/intravisit.rs | 2 +- src/librustc/hir/lowering.rs | 55 +++++++++++---------- src/librustc/hir/map/mod.rs | 4 +- src/librustc/hir/mod.rs | 8 +-- src/librustc/hir/print.rs | 4 +- src/librustc/middle/resolve_lifetime.rs | 7 +-- src/librustc_metadata/encoder.rs | 2 +- src/librustc_privacy/lib.rs | 7 ++- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustdoc/clean/mod.rs | 18 +++---- src/librustdoc/visit_ast.rs | 4 +- 12 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index bce528189ad1e..39069b66f2904 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -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); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 891210511ca79..ad517bfc3ed75 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -82,7 +82,7 @@ pub struct LoweringContext<'a> { resolver: &'a mut dyn Resolver, /// The items being lowered are collected here. - items: BTreeMap, + items: BTreeMap, trait_items: BTreeMap, impl_items: BTreeMap, @@ -321,7 +321,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 +330,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); @@ -434,17 +434,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,7 +515,8 @@ 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; self.items.insert(id, item); self.modules.get_mut(&self.current_module).unwrap().items.insert(id); } @@ -1422,10 +1422,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 +2002,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 }; @@ -3114,7 +3114,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, @@ -3219,7 +3218,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 +3441,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 +3459,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.lower_node_id(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 +3490,7 @@ impl<'a> LoweringContext<'a> { .skip(1) .zip([id1, id2].iter()) { - vec.push(hir::ItemId { id }); + vec.push(id); } }, } @@ -4604,6 +4606,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 { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d810a9310c55f..a01cf4a4ca149 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -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 { @@ -1292,7 +1292,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), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1bf7eed71bf0f..8509ddaccf7b4 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -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, + pub items: BTreeSet, pub trait_items: BTreeSet, pub impl_items: BTreeSet, } @@ -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, + pub items: BTreeMap, pub trait_items: BTreeMap, pub impl_items: BTreeMap, @@ -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 diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index cdd4043f4bc21..0a65473de8ff1 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -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<()> { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index ab10536038872..73e232a6a4ff2 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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)) { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 78a186fbb714a..1958f52e25f54 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -692,7 +692,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), diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index bbd03e82a3730..fe11609d70f78 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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) { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 3e61b175b76e0..fba4414c1275c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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)) => { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 7b530c69a8882..fde0e47650d80 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -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 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 61dbf00a1f536..3ef8be6b8edee 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -278,16 +278,16 @@ impl Clean 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 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 @@ -2584,7 +2584,7 @@ impl Clean 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 { @@ -4212,10 +4212,10 @@ pub fn path_to_def_local(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option 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; From cb4ac714e1155c9ae66a25300250bdd887bb8e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 16 Mar 2019 07:16:25 +0100 Subject: [PATCH 11/25] Allocate HIR id counters for use trees in MiscCollector --- src/librustc/hir/lowering.rs | 57 ++++++++++++++++++++++++++---------- src/librustc/middle/dead.rs | 2 +- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index ad517bfc3ed75..2a085f1c0a879 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -361,9 +361,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, &tree); + } + } + UseTreeKind::Glob => (), + UseTreeKind::Nested(ref trees) => { + for &(ref use_tree, id) in trees { + let hir_id = self.lctx.allocate_hir_id_counter(id, &use_tree).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, item).hir_id; match item.node { ItemKind::Struct(_, ref generics) @@ -383,6 +414,9 @@ 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); @@ -517,6 +551,8 @@ impl<'a> LoweringContext<'a> { 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); } @@ -3065,7 +3101,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 +3119,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); @@ -3173,8 +3200,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, @@ -3469,9 +3494,11 @@ impl<'a> LoweringContext<'a> { _ => smallvec![i.id], }; - node_ids.into_iter() - .map(|node_id| hir::ItemId { id: self.lower_node_id(node_id).hir_id }) - .collect() + node_ids.into_iter().map(|node_id| hir::ItemId { + id: self.lower_node_id_generic(node_id, |_| { + panic!("expected node_id to be lowered already {:#?}", i) + }).hir_id + }).collect() } fn lower_item_id_use_tree(&mut self, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index f12367a89bbf3..0a0a1dee7f07c 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -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); } _ => () From f7c66fb625ad61bcac325c844180c1c32a04aa13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 25 Mar 2019 19:43:04 +0100 Subject: [PATCH 12/25] Allocate HIR id counters on demand --- src/librustc/hir/lowering.rs | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2a085f1c0a879..7dfb16602a3d4 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -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; @@ -378,13 +377,13 @@ impl<'a> LoweringContext<'a> { Mark::root(), tree.prefix.span, ); - self.lctx.allocate_hir_id_counter(id, &tree); + 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, &use_tree).hir_id; + let hir_id = self.lctx.allocate_hir_id_counter(id).hir_id; self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner); } } @@ -394,7 +393,7 @@ impl<'a> LoweringContext<'a> { impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> { fn visit_item(&mut self, item: &'lcx Item) { - let hir_id = self.lctx.allocate_hir_id_counter(item.id, item).hir_id; + let hir_id = self.lctx.allocate_hir_id_counter(item.id).hir_id; match item.node { ItemKind::Struct(_, ref generics) @@ -423,12 +422,12 @@ impl<'a> LoweringContext<'a> { } 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); } } @@ -557,15 +556,13 @@ impl<'a> LoweringContext<'a> { self.modules.get_mut(&self.current_module).unwrap().items.insert(id); } - fn allocate_hir_id_counter(&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(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId @@ -1417,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); @@ -3495,9 +3492,7 @@ impl<'a> LoweringContext<'a> { }; node_ids.into_iter().map(|node_id| hir::ItemId { - id: self.lower_node_id_generic(node_id, |_| { - panic!("expected node_id to be lowered already {:#?}", i) - }).hir_id + id: self.allocate_hir_id_counter(node_id).hir_id }).collect() } From 2a4281998b6cac4893dabea52d38518973bac41a Mon Sep 17 00:00:00 2001 From: TheGoddessInari Date: Tue, 26 Mar 2019 08:46:41 -0700 Subject: [PATCH 13/25] Remove the block on natvis for lld-link. --- src/librustc_codegen_ssa/back/linker.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index e6470dbb61ce1..244505976b6c2 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -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) => { From 080a8e7a7137482b91cb4c76326f0d9d1243a6d7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 1 Mar 2019 17:03:15 +0100 Subject: [PATCH 14/25] Prevent cache issues on version updates --- src/bootstrap/doc.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index ae329286486d6..7434d39a44bba 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -343,12 +343,10 @@ fn invoke_rustdoc( .arg("--html-before-content").arg(&version_info) .arg("--html-in-header").arg(&favicon) .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("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM) + .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); } @@ -430,9 +428,9 @@ impl Step for Standalone { .arg("--html-before-content").arg(&version_info) .arg("--html-in-header").arg(&favicon) .arg("--markdown-no-toc") + .arg("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM) .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 +521,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); From 2d6745de0e4c6c8f304982e812ce40c50b813d6f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 13 Mar 2019 00:32:13 +0100 Subject: [PATCH 15/25] Add resource suffix for libtest and proc_macro as well --- src/bootstrap/doc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 7434d39a44bba..cab6abf74b6bd 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -343,7 +343,6 @@ fn invoke_rustdoc( .arg("--html-before-content").arg(&version_info) .arg("--html-in-header").arg(&favicon) .arg("--markdown-no-toc") - .arg("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM) .arg("--markdown-playground-url").arg("https://play.rust-lang.org/") .arg("-o").arg(&out).arg(&path) .arg("--markdown-css").arg("../rust.css"); @@ -428,7 +427,6 @@ impl Step for Standalone { .arg("--html-before-content").arg(&version_info) .arg("--html-in-header").arg(&favicon) .arg("--markdown-no-toc") - .arg("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM) .arg("--index-page").arg(&builder.src.join("src/doc/index.md")) .arg("--markdown-playground-url").arg("https://play.rust-lang.org/") .arg("-o").arg(&out) @@ -588,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); @@ -659,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"); } From 50c50e3a82e80dcc31f366b81c491fd0bf8ed5ac Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 25 Mar 2019 22:01:19 +0100 Subject: [PATCH 16/25] Handle RUSTDOC_RESOURCE_SUFFIX env variable for rustdoc build --- src/bootstrap/bin/rustdoc.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 085f243785cbe..1c9f6e1ab285c 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -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 { From d339b89644b6461636a8604849121bbc7824b859 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 26 Mar 2019 18:22:25 -0400 Subject: [PATCH 17/25] Use consistent phrasing for all macro summaries --- src/libcore/macros.rs | 45 ++++++++++++++++++++++--------------------- src/libstd/macros.rs | 45 ++++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index d77936c7ddd91..cd4e9243943ef 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -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; 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!`]. /// diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index d5dc5f7c4f0df..f618ba45582e3 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -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,9 @@ macro_rules! eprintln { }) } -/// A macro for quick and dirty debugging with which you can inspect -/// the value of a given expression. An example: +/// Prints the value of a given expression for quick and dirty debugging. +/// +/// An example: /// /// ```rust /// let a = 2; @@ -328,7 +329,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 +352,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 +424,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 +466,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 +518,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 +556,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 +582,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 +635,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 +660,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 +685,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 +709,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 +823,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 +845,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 +891,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 +945,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 From 5652dd677c63d0d1bc7d26f09baceaff7e7525b5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 26 Mar 2019 23:57:16 +0100 Subject: [PATCH 18/25] Fix error index CSS file name --- src/bootstrap/doc.rs | 1 + src/tools/error_index_generator/main.rs | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index cab6abf74b6bd..71708a0bdb1cf 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -889,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) diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index faeeea605a2b4..04986b59ea0f1 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -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>; } -struct HTMLFormatter(RefCell); +struct HTMLFormatter(RefCell, String); struct MarkdownFormatter; impl Formatter for HTMLFormatter { @@ -55,7 +56,7 @@ impl Formatter for HTMLFormatter { Rust Compiler Error Index - + -"##)?; +"##, suffix=self.1)?; Ok(()) } @@ -242,9 +243,12 @@ fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box (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"), From a68a0e33d1d6660ad594ae7be3c6c1cca7c1752c Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 01:22:23 -0400 Subject: [PATCH 19/25] Add documentation about `for` used as higher ranked trait bounds Resolves #55416 --- src/libstd/keyword_docs.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index bef6bc9266197..94751cec41618 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -286,11 +286,13 @@ 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). +/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic +/// uses. `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`. 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). /// /// ```rust /// for i in 0..5 { From 65b5e572266ace8d9dc817ab5f8c54b675614110 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 01:52:55 -0400 Subject: [PATCH 20/25] Make into itemized list and fix some wording --- src/libstd/keyword_docs.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 94751cec41618..3eec5468c7de4 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -286,13 +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. `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`. 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`. +/// +/// 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 { From 3e0db7cecd77dc7f780de0983beffd0d2f8caea7 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 27 Mar 2019 11:22:55 -0400 Subject: [PATCH 21/25] Clarify behavior of dbg macro --- src/libstd/macros.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index f618ba45582e3..d5afd069d7f29 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -210,7 +210,8 @@ macro_rules! eprintln { }) } -/// Prints the value of a given expression for quick and dirty debugging. +/// Prints and returns the value of a given expression for quick and dirty +/// debugging. /// /// An example: /// From f0a76107248ab2366ab5dd2d63cd0ec489e5d8b4 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 12:03:14 -0400 Subject: [PATCH 22/25] Add higher-ranked trait bounds link --- src/libstd/keyword_docs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 3eec5468c7de4..7223eb3bf0ead 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -352,6 +352,7 @@ 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 From 25452501ee53c60445b9774fa69e2dc2134ddc44 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 21:46:25 -0400 Subject: [PATCH 23/25] Move link to rust book to next line to pass 100 column limit --- src/libstd/keyword_docs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 7223eb3bf0ead..7b0d1549e061a 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -352,7 +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 +/// [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 From ffaa5c904e6de9cf15c44adfa43a56f046c28c42 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 22:11:13 -0400 Subject: [PATCH 24/25] Document that `std::io::BufReader` discards contents on drop Resolves #55546 --- src/libstd/io/buffered.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 4668e3ec7eabd..487706b05bb45 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -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`. /// +/// 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 From e1e0e53f1624489afd8f086017a599afbef21058 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 23:01:24 -0400 Subject: [PATCH 25/25] Fix link capitalization in documentation of std::io::BufWriter. --- src/libstd/io/buffered.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 4668e3ec7eabd..232afcd518c26 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -350,7 +350,7 @@ impl Seek for BufReader { /// /// 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 +401,7 @@ impl Seek for BufReader { /// 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")]