From 3e82dca65c226324580db910b2609e8dce1850ac Mon Sep 17 00:00:00 2001 From: phlopsi Date: Sun, 11 Jul 2021 06:41:43 +0200 Subject: [PATCH 01/15] Optimize fmt::PadAdapter::wrap --- library/core/src/fmt/builders.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index b660788c0515f..8e7b03d02f157 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -23,10 +23,7 @@ impl<'buf, 'state> PadAdapter<'buf, 'state> { slot: &'slot mut Option, state: &'state mut PadAdapterState, ) -> fmt::Formatter<'slot> { - fmt.wrap_buf(move |buf| { - *slot = Some(PadAdapter { buf, state }); - slot.as_mut().unwrap() - }) + fmt.wrap_buf(move |buf| slot.insert(PadAdapter { buf, state })) } } From b8eb1f167c6e3271df0797226048d85255434938 Mon Sep 17 00:00:00 2001 From: frogtd <31412003+frogtd@users.noreply.github.com> Date: Tue, 27 Jul 2021 16:02:35 -0400 Subject: [PATCH 02/15] Fix assert in diy_float The shifting should have gone the other way, the current incarnation is always true. --- library/core/src/num/diy_float.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/diy_float.rs b/library/core/src/num/diy_float.rs index 0a609417dcf4c..ce7f6475d0599 100644 --- a/library/core/src/num/diy_float.rs +++ b/library/core/src/num/diy_float.rs @@ -65,7 +65,7 @@ impl Fp { f <<= 1; e -= 1; } - debug_assert!(f >= (1 >> 63)); + debug_assert!(f >= (1 << 63)); Fp { f, e } } From cd6c0e4e3b71cffd6e577146cbf989ad6ba29c63 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 28 Jul 2021 16:35:57 +0200 Subject: [PATCH 03/15] Fix typo in rustc_driver::version This caused rustc -Zcodegen-backend=foo.so -vV to look for oo.so instead of foo.so --- compiler/rustc_driver/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 326fefa59ab05..50932d498b317 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -766,7 +766,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { let debug_flags = matches.opt_strs("Z"); let backend_name = debug_flags.iter().find_map(|x| { if x.starts_with("codegen-backend=") { - Some(&x["codegen-backends=".len()..]) + Some(&x["codegen-backend=".len()..]) } else { None } From 9829efb892f7c249f2c889722a098e6a9b34f3fb Mon Sep 17 00:00:00 2001 From: Roxane Date: Wed, 28 Jul 2021 10:35:48 -0400 Subject: [PATCH 04/15] Range PatKind implies discr should be read --- compiler/rustc_typeck/src/expr_use_visitor.rs | 9 ++++++--- .../closures/2229_closure_analysis/issue-87426.rs | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/closures/2229_closure_analysis/issue-87426.rs diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 6c76a8960bbe1..201804f9fc40b 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -267,12 +267,15 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } } - PatKind::Lit(_) => { - // If the PatKind is a Lit then we want + PatKind::Lit(_) | PatKind::Range(..) => { + // If the PatKind is a Lit or a Range then we want // to borrow discr. needs_to_be_read = true; } - _ => {} + _ => { + // If the PatKind is Or, Box, Slice or Ref, the decision is made later + // as these patterns contains subpatterns + } } })); } diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87426.rs b/src/test/ui/closures/2229_closure_analysis/issue-87426.rs new file mode 100644 index 0000000000000..4a6eb5154c136 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/issue-87426.rs @@ -0,0 +1,14 @@ +// run-pass +// edition:2021 + +pub fn foo() { + let ref_x_ck = 123; + let _y = || match ref_x_ck { + 2_000_000..=3_999_999 => { println!("A")} + _ => { println!("B")} + }; +} + +fn main() { + foo(); +} \ No newline at end of file From d380ed13043d52139b3c766a07edb93b891e2be6 Mon Sep 17 00:00:00 2001 From: Roxane Date: Wed, 28 Jul 2021 12:27:57 -0400 Subject: [PATCH 05/15] fix nit --- compiler/rustc_typeck/src/expr_use_visitor.rs | 8 +++++++- src/test/ui/closures/2229_closure_analysis/issue-87426.rs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 201804f9fc40b..1d7852d964c1d 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -272,9 +272,15 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // to borrow discr. needs_to_be_read = true; } - _ => { + PatKind::Or(_) + | PatKind::Box(_) + | PatKind::Slice(..) + | PatKind::Ref(..) + | PatKind::Wild => { // If the PatKind is Or, Box, Slice or Ref, the decision is made later // as these patterns contains subpatterns + // If the PatKind is Wild, the decision is made based on the other patterns being + // examined } } })); diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87426.rs b/src/test/ui/closures/2229_closure_analysis/issue-87426.rs index 4a6eb5154c136..74506979a28c5 100644 --- a/src/test/ui/closures/2229_closure_analysis/issue-87426.rs +++ b/src/test/ui/closures/2229_closure_analysis/issue-87426.rs @@ -11,4 +11,4 @@ pub fn foo() { fn main() { foo(); -} \ No newline at end of file +} From cf5e48d944fcc068c7d9b55399684f7e3437628a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 28 Jul 2021 17:04:45 -0300 Subject: [PATCH 06/15] min_type_alias_impl_trait is going to be removed in 1.56 --- compiler/rustc_feature/src/removed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 0aa7e82c20492..f63c207a540c2 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -153,7 +153,7 @@ declare_features! ( Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")), /// Allows the use of type alias impl trait in function return positions - (removed, min_type_alias_impl_trait, "1.55.0", Some(63063), None, + (removed, min_type_alias_impl_trait, "1.56.0", Some(63063), None, Some("removed in favor of full type_alias_impl_trait")), // ------------------------------------------------------------------------- From d4a60ab34f4f612365e353fafdfb4e28f1484e47 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 28 Jul 2021 16:35:59 -0700 Subject: [PATCH 07/15] Update the examples in `String` and `VecDeque::retain` The examples added in #60396 used a "clever" post-increment hack, unrelated to the actual point of the examples. That hack was found [confusing] in the users forum, and #81811 already changed the `Vec` example to use a more direct iterator. This commit changes `String` and `VecDeque` in the same way for consistency. [confusing]: https://users.rust-lang.org/t/help-understand-strange-expression/62858 --- library/alloc/src/collections/vec_deque/mod.rs | 7 ++++--- library/alloc/src/string.rs | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 386c7c2612d57..3cf6c56f43a57 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2107,7 +2107,8 @@ impl VecDeque { /// assert_eq!(buf, [2, 4]); /// ``` /// - /// The exact order may be useful for tracking external state, like an index. + /// Because the elements are visited exactly once in the original order, + /// external state may be used to decide which elements to keep. /// /// ``` /// use std::collections::VecDeque; @@ -2116,8 +2117,8 @@ impl VecDeque { /// buf.extend(1..6); /// /// let keep = [false, true, true, false, true]; - /// let mut i = 0; - /// buf.retain(|_| (keep[i], i += 1).0); + /// let mut iter = keep.iter(); + /// buf.retain(|_| *iter.next().unwrap()); /// assert_eq!(buf, [2, 3, 5]); /// ``` #[stable(feature = "vec_deque_retain", since = "1.4.0")] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 0d8678291bef7..6a02de7f9a24f 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1350,13 +1350,14 @@ impl String { /// assert_eq!(s, "foobar"); /// ``` /// - /// The exact order may be useful for tracking external state, like an index. + /// Because the elements are visited exactly once in the original order, + /// external state may be used to decide which elements to keep. /// /// ``` /// let mut s = String::from("abcde"); /// let keep = [false, true, true, false, true]; - /// let mut i = 0; - /// s.retain(|_| (keep[i], i += 1).0); + /// let mut iter = keep.iter(); + /// s.retain(|_| *iter.next().unwrap()); /// assert_eq!(s, "bce"); /// ``` #[inline] From 2f6662da85d47ebf89432c910a496812e9e2db12 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 29 Jul 2021 11:54:39 +0200 Subject: [PATCH 08/15] Use strip_prefix --- compiler/rustc_driver/src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 50932d498b317..84dd69ebd9634 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -764,13 +764,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { println!("release: {}", unw(util::release_str())); let debug_flags = matches.opt_strs("Z"); - let backend_name = debug_flags.iter().find_map(|x| { - if x.starts_with("codegen-backend=") { - Some(&x["codegen-backend=".len()..]) - } else { - None - } - }); + let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); get_codegen_backend(&None, backend_name).print_version(); } } From 8307072edf74f68f89e736d242d32b17eeb385d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 27 Jul 2021 00:00:00 +0000 Subject: [PATCH 09/15] Remove redundant option around compression caches Compression caches are always present. Remove unnecessary option. --- compiler/rustc_symbol_mangling/src/v0.rs | 26 +++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 14442806fc0b7..8359bba3079e5 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -25,13 +25,13 @@ pub(super) fn mangle( let prefix = "_R"; let mut cx = SymbolMangler { tcx, - compress: Some(Box::new(CompressionCaches { + compress: Box::new(CompressionCaches { start_offset: prefix.len(), paths: FxHashMap::default(), types: FxHashMap::default(), consts: FxHashMap::default(), - })), + }), binders: vec![], out: String::from(prefix), }; @@ -81,7 +81,7 @@ struct BinderLevel { struct SymbolMangler<'tcx> { tcx: TyCtxt<'tcx>, - compress: Option>>, + compress: Box>, binders: Vec, out: String, } @@ -177,7 +177,7 @@ impl SymbolMangler<'tcx> { fn print_backref(mut self, i: usize) -> Result { self.push("B"); - self.push_integer_62((i - self.compress.as_ref().unwrap().start_offset) as u64); + self.push_integer_62((i - self.compress.start_offset) as u64); Ok(self) } @@ -236,7 +236,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { def_id: DefId, substs: &'tcx [GenericArg<'tcx>], ) -> Result { - if let Some(&i) = self.compress.as_ref().and_then(|c| c.paths.get(&(def_id, substs))) { + if let Some(&i) = self.compress.paths.get(&(def_id, substs)) { return self.print_backref(i); } let start = self.out.len(); @@ -246,9 +246,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Only cache paths that do not refer to an enclosing // binder (which would change depending on context). if !substs.iter().any(|k| k.has_escaping_bound_vars()) { - if let Some(c) = &mut self.compress { - c.paths.insert((def_id, substs), start); - } + self.compress.paths.insert((def_id, substs), start); } Ok(self) } @@ -367,7 +365,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { return Ok(self); } - if let Some(&i) = self.compress.as_ref().and_then(|c| c.types.get(&ty)) { + if let Some(&i) = self.compress.types.get(&ty) { return self.print_backref(i); } let start = self.out.len(); @@ -476,9 +474,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Only cache types that do not refer to an enclosing // binder (which would change depending on context). if !ty.has_escaping_bound_vars() { - if let Some(c) = &mut self.compress { - c.types.insert(ty, start); - } + self.compress.types.insert(ty, start); } Ok(self) } @@ -545,7 +541,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { } fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result { - if let Some(&i) = self.compress.as_ref().and_then(|c| c.consts.get(&ct)) { + if let Some(&i) = self.compress.consts.get(&ct) { return self.print_backref(i); } let start = self.out.len(); @@ -583,9 +579,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Only cache consts that do not refer to an enclosing // binder (which would change depending on context). if !ct.has_escaping_bound_vars() { - if let Some(c) = &mut self.compress { - c.consts.insert(ct, start); - } + self.compress.consts.insert(ct, start); } Ok(self) } From 0ce8001a473e049a74f424d765b90f83f5dc76c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 29 Jul 2021 00:00:00 +0000 Subject: [PATCH 10/15] Flatten compression caches into symbol mangler The compression caches currently don't have any dedicated functionality that would benefit from being separated. Incorporating caches directly into the symbol manger also avoids dynamic memory allocation. The symbol mangler, which is often passed by value, is now slightly larger. This aspect will be addressed by a follow-up commit. --- compiler/rustc_symbol_mangling/src/v0.rs | 43 ++++++++++-------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 8359bba3079e5..6a1360da4ee9e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -25,13 +25,10 @@ pub(super) fn mangle( let prefix = "_R"; let mut cx = SymbolMangler { tcx, - compress: Box::new(CompressionCaches { - start_offset: prefix.len(), - - paths: FxHashMap::default(), - types: FxHashMap::default(), - consts: FxHashMap::default(), - }), + start_offset: prefix.len(), + paths: FxHashMap::default(), + types: FxHashMap::default(), + consts: FxHashMap::default(), binders: vec![], out: String::from(prefix), }; @@ -55,16 +52,6 @@ pub(super) fn mangle( cx.out } -struct CompressionCaches<'tcx> { - // The length of the prefix in `out` (e.g. 2 for `_R`). - start_offset: usize, - - // The values are start positions in `out`, in bytes. - paths: FxHashMap<(DefId, &'tcx [GenericArg<'tcx>]), usize>, - types: FxHashMap, usize>, - consts: FxHashMap<&'tcx ty::Const<'tcx>, usize>, -} - struct BinderLevel { /// The range of distances from the root of what's /// being printed, to the lifetimes in a binder. @@ -81,9 +68,15 @@ struct BinderLevel { struct SymbolMangler<'tcx> { tcx: TyCtxt<'tcx>, - compress: Box>, binders: Vec, out: String, + + /// The length of the prefix in `out` (e.g. 2 for `_R`). + start_offset: usize, + /// The values are start positions in `out`, in bytes. + paths: FxHashMap<(DefId, &'tcx [GenericArg<'tcx>]), usize>, + types: FxHashMap, usize>, + consts: FxHashMap<&'tcx ty::Const<'tcx>, usize>, } impl SymbolMangler<'tcx> { @@ -177,7 +170,7 @@ impl SymbolMangler<'tcx> { fn print_backref(mut self, i: usize) -> Result { self.push("B"); - self.push_integer_62((i - self.compress.start_offset) as u64); + self.push_integer_62((i - self.start_offset) as u64); Ok(self) } @@ -236,7 +229,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { def_id: DefId, substs: &'tcx [GenericArg<'tcx>], ) -> Result { - if let Some(&i) = self.compress.paths.get(&(def_id, substs)) { + if let Some(&i) = self.paths.get(&(def_id, substs)) { return self.print_backref(i); } let start = self.out.len(); @@ -246,7 +239,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Only cache paths that do not refer to an enclosing // binder (which would change depending on context). if !substs.iter().any(|k| k.has_escaping_bound_vars()) { - self.compress.paths.insert((def_id, substs), start); + self.paths.insert((def_id, substs), start); } Ok(self) } @@ -365,7 +358,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { return Ok(self); } - if let Some(&i) = self.compress.types.get(&ty) { + if let Some(&i) = self.types.get(&ty) { return self.print_backref(i); } let start = self.out.len(); @@ -474,7 +467,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Only cache types that do not refer to an enclosing // binder (which would change depending on context). if !ty.has_escaping_bound_vars() { - self.compress.types.insert(ty, start); + self.types.insert(ty, start); } Ok(self) } @@ -541,7 +534,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { } fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result { - if let Some(&i) = self.compress.consts.get(&ct) { + if let Some(&i) = self.consts.get(&ct) { return self.print_backref(i); } let start = self.out.len(); @@ -579,7 +572,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Only cache consts that do not refer to an enclosing // binder (which would change depending on context). if !ct.has_escaping_bound_vars() { - self.compress.consts.insert(ct, start); + self.consts.insert(ct, start); } Ok(self) } From 0eabbf84babbf9302285a4cb2ea54a9d67f13945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 29 Jul 2021 00:00:00 +0000 Subject: [PATCH 11/15] Implement `Printer` for `&mut SymbolMangler` to avoid passing the symbol mangler by value. --- compiler/rustc_symbol_mangling/src/v0.rs | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 6a1360da4ee9e..c4c1ec8ce4e0a 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -23,7 +23,7 @@ pub(super) fn mangle( let substs = tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.substs); let prefix = "_R"; - let mut cx = SymbolMangler { + let mut cx = &mut SymbolMangler { tcx, start_offset: prefix.len(), paths: FxHashMap::default(), @@ -49,7 +49,7 @@ pub(super) fn mangle( if let Some(instantiating_crate) = instantiating_crate { cx = cx.print_def_path(instantiating_crate.as_def_id(), &[]).unwrap(); } - cx.out + std::mem::take(&mut cx.out) } struct BinderLevel { @@ -153,13 +153,13 @@ impl SymbolMangler<'tcx> { self.push(ident); } - fn path_append_ns( - mut self, - print_prefix: impl FnOnce(Self) -> Result, + fn path_append_ns<'a>( + mut self: &'a mut Self, + print_prefix: impl FnOnce(&'a mut Self) -> Result<&'a mut Self, !>, ns: char, disambiguator: u64, name: &str, - ) -> Result { + ) -> Result<&'a mut Self, !> { self.push("N"); self.out.push(ns); self = print_prefix(self)?; @@ -168,17 +168,17 @@ impl SymbolMangler<'tcx> { Ok(self) } - fn print_backref(mut self, i: usize) -> Result { + fn print_backref(&mut self, i: usize) -> Result<&mut Self, !> { self.push("B"); self.push_integer_62((i - self.start_offset) as u64); Ok(self) } - fn in_binder( - mut self, + fn in_binder<'a, T>( + mut self: &'a mut Self, value: &ty::Binder<'tcx, T>, - print_value: impl FnOnce(Self, &T) -> Result, - ) -> Result + print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, !>, + ) -> Result<&'a mut Self, !> where T: TypeFoldable<'tcx>, { @@ -211,7 +211,7 @@ impl SymbolMangler<'tcx> { } } -impl Printer<'tcx> for SymbolMangler<'tcx> { +impl Printer<'tcx> for &mut SymbolMangler<'tcx> { type Error = !; type Path = Self; @@ -303,7 +303,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { Ok(self) } - fn print_region(mut self, region: ty::Region<'_>) -> Result { + fn print_region(self, region: ty::Region<'_>) -> Result { let i = match *region { // Erased lifetimes use the index 0, for a // shorter mangling of `L_`. @@ -577,7 +577,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { Ok(self) } - fn path_crate(mut self, cnum: CrateNum) -> Result { + fn path_crate(self, cnum: CrateNum) -> Result { self.push("C"); let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); self.push_disambiguator(stable_crate_id.to_u64()); From cf0f5021f48fdb3c44c83351e7abb128b4e0191e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 29 Jul 2021 14:13:41 +0200 Subject: [PATCH 12/15] Add missing links for core::char types --- library/core/src/char/decode.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs index 5e7784730e3c9..4784418f98c50 100644 --- a/library/core/src/char/decode.rs +++ b/library/core/src/char/decode.rs @@ -5,6 +5,11 @@ use crate::fmt; use super::from_u32_unchecked; /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s. +/// +/// This `struct` is created by the [`decode_utf16`] method on [`char`]. See its +/// documentation for more. +/// +/// [`decode_utf16`]: char::decode_utf16 #[stable(feature = "decode_utf16", since = "1.9.0")] #[derive(Clone, Debug)] pub struct DecodeUtf16 @@ -16,6 +21,8 @@ where } /// An error that can be returned when decoding UTF-16 code points. +/// +/// This `struct` is created when using the [`DecodeUtf16`] type. #[stable(feature = "decode_utf16", since = "1.9.0")] #[derive(Debug, Clone, Eq, PartialEq)] pub struct DecodeUtf16Error { From ce1bd70035d594755c109ebb313b51becca73213 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 29 Jul 2021 17:49:48 +0100 Subject: [PATCH 13/15] fs File get_path procfs usage for netbsd same as linux. --- library/std/src/sys/unix/fs.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 5c8c94971c33c..7f69ebbeb4de6 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -939,7 +939,7 @@ impl FromInner for File { impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "netbsd"))] fn get_path(fd: c_int) -> Option { let mut p = PathBuf::from("/proc/self/fd"); p.push(&fd.to_string()); @@ -976,7 +976,12 @@ impl fmt::Debug for File { Some(PathBuf::from(OsString::from_vec(buf))) } - #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "vxworks")))] + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "vxworks", + target_os = "netbsd" + )))] fn get_path(_fd: c_int) -> Option { // FIXME(#24570): implement this for other Unix platforms None From 3fda7086cc810ce3003b91f74eb1c17e9f016319 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 28 Jul 2021 11:40:53 -0400 Subject: [PATCH 14/15] Add regression test --- .../panic-short-backtrace-windows-x86_64.rs | 44 +++++++++++++++++++ ...-short-backtrace-windows-x86_64.run.stderr | 3 ++ 2 files changed, 47 insertions(+) create mode 100644 src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs create mode 100644 src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs new file mode 100644 index 0000000000000..eae3f861519a0 --- /dev/null +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -0,0 +1,44 @@ +// Regression test for #87481: short backtrace formatting cut off the entire stack trace. + +// Codegen-units is specified here so that we can replicate a typical rustc invocation which +// is not normally limited to 1 CGU. This is important so that the `__rust_begin_short_backtrace` +// and `__rust_end_short_backtrace` symbols are not marked internal to the CGU and thus will be +// named in the symbol table. +// compile-flags: -O -Ccodegen-units=8 + +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=1 + +// Backtraces are pretty broken in general on i686-pc-windows-msvc (#62897). +// only-x86_64-pc-windows-msvc + +fn main() { + a(); +} + +// Make these no_mangle so dbghelp.dll can figure out the symbol names. + +#[no_mangle] +#[inline(never)] +fn a() { + b(); +} + +#[no_mangle] +#[inline(never)] +fn b() { + c(); +} + +#[no_mangle] +#[inline(never)] +fn c() { + d(); +} + +#[no_mangle] +#[inline(never)] +fn d() { + panic!("d was called"); +} diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr new file mode 100644 index 0000000000000..f855346532fce --- /dev/null +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr @@ -0,0 +1,3 @@ +thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:43:5 +stack backtrace: +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. From 286cdc81a85e8490cdc8ff42ea5085ced0df09f4 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 29 Jul 2021 13:06:37 -0400 Subject: [PATCH 15/15] [backtraces]: look for the `begin` symbol only after seeing `end` On `x86_64-pc-windows-msvc`, we often get backtraces which look like this: ``` 10: 0x7ff77e0e9be5 - std::panicking::rust_panic_with_hook 11: 0x7ff77e0e11b4 - std::sys_common::backtrace::__rust_begin_short_backtrace::h5769736bdb11136c 12: 0x7ff77e0e116f - std::sys_common::backtrace::__rust_end_short_backtrace::h61c7ecb1b55338ae 13: 0x7ff77e0f89dd - std::panicking::begin_panic::h8e60ef9f82a41805 14: 0x7ff77e0e108c - d 15: 0x7ff77e0e1069 - c 16: 0x7ff77e0e1059 - b 17: 0x7ff77e0e1049 - a 18: 0x7ff77e0e1039 - core::ptr::drop_in_place::{{closure}}>::h1bfcd14d5e15ba81 19: 0x7ff77e0e1186 - std::sys_common::backtrace::__rust_begin_short_backtrace::h5769736bdb11136c 20: 0x7ff77e0e100c - std::rt::lang_start::{{closure}}::ha054184bbf9921e3 ``` Notice that `__rust_begin_short_backtrace` appears on frame 11 before `__rust_end_short_backtrace` on frame 12. This is because in typical release binaries without debug symbols, dbghelp.dll, which we use to walk and symbolize the stack, does not know where CGU internal functions start or end and so the closure invoked by `__rust_end_short_backtrace` is incorrectly described as `__rust_begin_short_backtrace` because it happens to be near that symbol. While that can obviously change, this has been happening quite consistently since #75048. Since this is a very small change to the std and the change makes sense by itself, I think this is worth doing. This doesn't completely resolve the situation for release binaries on Windows, since without debug symbols, the stack printed can still show incorrect symbol names (this is why the test uses `#[no_mangle]`) but it does slightly improve the situation in that you see the same backtrace you would see with `RUST_BACKTRACE=full` or in a debugger (without the uninteresting bits at the top and bottom). --- library/std/src/sys_common/backtrace.rs | 2 +- .../ui/panics/panic-short-backtrace-windows-x86_64.rs | 5 +++++ .../panic-short-backtrace-windows-x86_64.run.stderr | 8 +++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs index a549770d8b378..e6a099f0e81a0 100644 --- a/library/std/src/sys_common/backtrace.rs +++ b/library/std/src/sys_common/backtrace.rs @@ -75,7 +75,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: hit = true; if print_fmt == PrintFmt::Short { if let Some(sym) = symbol.name().and_then(|s| s.as_str()) { - if sym.contains("__rust_begin_short_backtrace") { + if start && sym.contains("__rust_begin_short_backtrace") { stop = true; return; } diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs index eae3f861519a0..fd01337296fb7 100644 --- a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -10,6 +10,11 @@ // check-run-results // exec-env:RUST_BACKTRACE=1 +// We need to normalize out frame 5 because without debug info, dbghelp.dll doesn't know where CGU +// internal functions like `main` start or end and so it will return whatever symbol happens +// to be located near the address. +// normalize-stderr-test: "5: .*" -> "5: some Rust fn" + // Backtraces are pretty broken in general on i686-pc-windows-msvc (#62897). // only-x86_64-pc-windows-msvc diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr index f855346532fce..799a8b30e997b 100644 --- a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr @@ -1,3 +1,9 @@ -thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:43:5 +thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:48:5 stack backtrace: + 0: std::panicking::begin_panic + 1: d + 2: c + 3: b + 4: a + 5: some Rust fn note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.