diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 326fefa59ab05..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-backends=".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(); } } 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")), // ------------------------------------------------------------------------- diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 14442806fc0b7..c4c1ec8ce4e0a 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -23,15 +23,12 @@ 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, - compress: Some(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), }; @@ -52,17 +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 -} - -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>, + std::mem::take(&mut cx.out) } struct BinderLevel { @@ -81,9 +68,15 @@ struct BinderLevel { struct SymbolMangler<'tcx> { tcx: TyCtxt<'tcx>, - compress: Option>>, 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> { @@ -160,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)?; @@ -175,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.compress.as_ref().unwrap().start_offset) as u64); + 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>, { @@ -218,7 +211,7 @@ impl SymbolMangler<'tcx> { } } -impl Printer<'tcx> for SymbolMangler<'tcx> { +impl Printer<'tcx> for &mut SymbolMangler<'tcx> { type Error = !; type Path = 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.as_ref().and_then(|c| c.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,9 +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()) { - if let Some(c) = &mut self.compress { - c.paths.insert((def_id, substs), start); - } + self.paths.insert((def_id, substs), start); } Ok(self) } @@ -312,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_`. @@ -367,7 +358,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.types.get(&ty) { return self.print_backref(i); } let start = self.out.len(); @@ -476,9 +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() { - if let Some(c) = &mut self.compress { - c.types.insert(ty, start); - } + self.types.insert(ty, start); } Ok(self) } @@ -545,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.as_ref().and_then(|c| c.consts.get(&ct)) { + if let Some(&i) = self.consts.get(&ct) { return self.print_backref(i); } let start = self.out.len(); @@ -583,14 +572,12 @@ 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.consts.insert(ct, start); } 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()); diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 6c76a8960bbe1..1d7852d964c1d 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -267,12 +267,21 @@ 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; } - _ => {} + 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/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 bc5ab3637ae6c..5411316f55af0 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] 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 { 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 })) } } 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 } } 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 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/closures/2229_closure_analysis/issue-87426.rs b/src/test/ui/closures/2229_closure_analysis/issue-87426.rs new file mode 100644 index 0000000000000..74506979a28c5 --- /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(); +} 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..fd01337296fb7 --- /dev/null +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -0,0 +1,49 @@ +// 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 + +// 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 + +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..799a8b30e997b --- /dev/null +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr @@ -0,0 +1,9 @@ +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.