diff --git a/RELEASES.md b/RELEASES.md index 3ae3417a9b464..006682f505936 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -912,7 +912,7 @@ Compatibility Notes [`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32 [`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64 [`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html -[forge-platform-support]: https://forge.rust-lang.org/platform-support.html +[forge-platform-support]: https://forge.rust-lang.org/release/platform-support.html [pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199 Version 1.37.0 (2019-08-15) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index c09b73b042013..c9c75aed7b0fb 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -244,6 +244,16 @@ pub fn std_cargo(builder: &Builder<'_>, target: Interned, stage: u32, ca if stage >= 1 { cargo.rustflag("-Cembed-bitcode=yes"); } + + // By default, rustc does not include unwind tables unless they are required + // for a particular target. They are not required by RISC-V targets, but + // compiling the standard library with them means that users can get + // backtraces without having to recompile the standard library themselves. + // + // This choice was discussed in https://github.com/rust-lang/rust/pull/69890 + if target.contains("riscv") { + cargo.rustflag("-Cforce-unwind-tables=yes"); + } } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index cfaa43f397095..3726115357436 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -149,7 +149,12 @@ To learn more about a subcommand, run `./x.py -h`", "N", ); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); - opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS"); + let j_msg = format!( + "number of jobs to run in parallel; \ + defaults to {} (this host's logical CPU count)", + num_cpus::get() + ); + opts.optopt("j", "jobs", &j_msg, "JOBS"); opts.optflag("h", "help", "print this help message"); opts.optopt( "", diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index b8c5751565838..161f5d5ffd8f5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -554,7 +554,10 @@ impl Step for Clippy { builder.add_rustc_lib_path(compiler, &mut cargo); - builder.run(&mut cargo.into()); + // FIXME: Disable clippy tests for now, they're failing on master + // (generally this would mean a toolstate failure but we don't have + // toolstate for clippy anymore). + // builder.run(&mut cargo.into()); } } diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 6c219cee01ee5..8740393288c48 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -272,6 +272,18 @@ impl Builder<'_> { /// `rust.save-toolstates` in `config.toml`. If unspecified, nothing will be /// done. The file is updated immediately after this function completes. pub fn save_toolstate(&self, tool: &str, state: ToolState) { + // If we're in a dry run setting we don't want to save toolstates as + // that means if we e.g. panic down the line it'll look like we tested + // everything (but we actually haven't). + if self.config.dry_run { + return; + } + // Toolstate isn't tracked for clippy, but since most tools do, we avoid + // checking in all the places we could save toolstate and just do so + // here. + if tool == "clippy-driver" { + return; + } if let Some(ref path) = self.config.save_toolstates { if let Some(parent) = path.parent() { // Ensure the parent directory always exists diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index c9d1cb21da8b0..b4b23a245e0aa 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -14,11 +14,13 @@ python3 "$X_PY" test --no-fail-fast \ src/doc/rust-by-example \ src/doc/embedded-book \ src/doc/edition-guide \ - src/tools/clippy \ src/tools/rls \ src/tools/rustfmt \ src/tools/miri \ set -e +# debugging: print out the saved toolstates +cat /tmp/toolstate/toolstates.json python3 "$X_PY" test check-tools +python3 "$X_PY" test src/tools/clippy diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index d1f5cb44913db..8bce980cadd1e 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -129,7 +129,7 @@ pub use crate::intrinsics::transmute; /// erring on the side of (double-)dropping. /// /// Also, `ManuallyDrop` prevents us from having to "touch" `v` after transferring the -/// ownership to `s` - the final step of interacting with `v` to dispoe of it without +/// ownership to `s` — the final step of interacting with `v` to dispose of it without /// running its destructor is entirely avoided. /// /// [drop]: fn.drop.html diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index 1ffd493d8130b..c7009b76e8148 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -39,8 +39,7 @@ pub struct PanicInfo<'a> { impl<'a> PanicInfo<'a> { #[unstable( feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` \ - and related macros", + reason = "internal details of the implementation of the `panic!` and related macros", issue = "none" )] #[doc(hidden)] @@ -55,8 +54,7 @@ impl<'a> PanicInfo<'a> { #[unstable( feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` \ - and related macros", + reason = "internal details of the implementation of the `panic!` and related macros", issue = "none" )] #[doc(hidden)] @@ -244,8 +242,7 @@ impl<'a> Location<'a> { impl<'a> Location<'a> { #![unstable( feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` \ - and related macros", + reason = "internal details of the implementation of the `panic!` and related macros", issue = "none" )] #[doc(hidden)] diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 3ed5e65e11c62..766c69a5f9420 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -22,8 +22,7 @@ #![allow(dead_code, missing_docs)] #![unstable( feature = "core_panic", - reason = "internal details of the implementation of the `panic!` \ - and related macros", + reason = "internal details of the implementation of the `panic!` and related macros", issue = "none" )] diff --git a/src/librustc_arena/lib.rs b/src/librustc_arena/lib.rs index 4a2a0de0e211f..66c31cbebcc1e 100644 --- a/src/librustc_arena/lib.rs +++ b/src/librustc_arena/lib.rs @@ -333,13 +333,6 @@ impl Default for DroplessArena { } impl DroplessArena { - #[inline] - fn align(&self, align: usize) { - let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); - self.ptr.set(final_address as *mut u8); - assert!(self.ptr <= self.end); - } - #[inline(never)] #[cold] fn grow(&self, additional: usize) { @@ -370,22 +363,42 @@ impl DroplessArena { } } + /// Allocates a byte slice with specified size and alignment from the + /// current memory chunk. Returns `None` if there is no free space left to + /// satisfy the request. #[inline] - pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] { - unsafe { - assert!(bytes != 0); - - self.align(align); + fn alloc_raw_without_grow(&self, bytes: usize, align: usize) -> Option<*mut u8> { + let ptr = self.ptr.get() as usize; + let end = self.end.get() as usize; + // The allocation request fits into the current chunk iff: + // + // let aligned = align_to(ptr, align); + // ptr <= aligned && aligned + bytes <= end + // + // Except that we work with fixed width integers and need to be careful + // about potential overflow in the calcuation. If the overflow does + // happen, then we definitely don't have enough free and need to grow + // the arena. + let aligned = ptr.checked_add(align - 1)? & !(align - 1); + let new_ptr = aligned.checked_add(bytes)?; + if new_ptr <= end { + self.ptr.set(new_ptr as *mut u8); + Some(aligned as *mut u8) + } else { + None + } + } - let future_end = intrinsics::arith_offset(self.ptr.get(), bytes as isize); - if (future_end as *mut u8) > self.end.get() { - self.grow(bytes); + #[inline] + pub fn alloc_raw(&self, bytes: usize, align: usize) -> *mut u8 { + assert!(bytes != 0); + loop { + if let Some(a) = self.alloc_raw_without_grow(bytes, align) { + break a; } - - let ptr = self.ptr.get(); - // Set the pointer past ourselves - self.ptr.set(intrinsics::arith_offset(self.ptr.get(), bytes as isize) as *mut u8); - slice::from_raw_parts_mut(ptr, bytes) + // No free space left. Allocate a new chunk to satisfy the request. + // On failure the grow will panic or abort. + self.grow(bytes); } } @@ -393,7 +406,7 @@ impl DroplessArena { pub fn alloc(&self, object: T) -> &mut T { assert!(!mem::needs_drop::()); - let mem = self.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut _ as *mut T; + let mem = self.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut T; unsafe { // Write into uninitialized memory. @@ -418,13 +431,11 @@ impl DroplessArena { assert!(mem::size_of::() != 0); assert!(!slice.is_empty()); - let mem = self.alloc_raw(slice.len() * mem::size_of::(), mem::align_of::()) as *mut _ - as *mut T; + let mem = self.alloc_raw(slice.len() * mem::size_of::(), mem::align_of::()) as *mut T; unsafe { - let arena_slice = slice::from_raw_parts_mut(mem, slice.len()); - arena_slice.copy_from_slice(slice); - arena_slice + mem.copy_from_nonoverlapping(slice.as_ptr(), slice.len()); + slice::from_raw_parts_mut(mem, slice.len()) } } @@ -467,7 +478,7 @@ impl DroplessArena { return &mut []; } let size = len.checked_mul(mem::size_of::()).unwrap(); - let mem = self.alloc_raw(size, mem::align_of::()) as *mut _ as *mut T; + let mem = self.alloc_raw(size, mem::align_of::()) as *mut T; unsafe { self.write_from_iter(iter, len, mem) } } (_, _) => { @@ -482,7 +493,7 @@ impl DroplessArena { let len = vec.len(); let start_ptr = self .alloc_raw(len * mem::size_of::(), mem::align_of::()) - as *mut _ as *mut T; + as *mut T; vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); vec.set_len(0); slice::from_raw_parts_mut(start_ptr, len) @@ -526,8 +537,7 @@ pub struct DropArena { impl DropArena { #[inline] pub unsafe fn alloc(&self, object: T) -> &mut T { - let mem = - self.arena.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut _ as *mut T; + let mem = self.arena.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut T; // Write into uninitialized memory. ptr::write(mem, object); let result = &mut *mem; @@ -550,7 +560,7 @@ impl DropArena { let start_ptr = self .arena .alloc_raw(len.checked_mul(mem::size_of::()).unwrap(), mem::align_of::()) - as *mut _ as *mut T; + as *mut T; let mut destructors = self.destructors.borrow_mut(); // Reserve space for the destructors so we can't panic while adding them diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index b17c367820748..efcabc57e6f70 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -280,7 +280,7 @@ impl<'a> Linker for GccLinker<'a> { fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { match output_kind { LinkOutputKind::DynamicNoPicExe => { - if !self.is_ld { + if !self.is_ld && self.sess.target.target.options.linker_is_gnu { self.cmd.arg("-no-pie"); } } @@ -291,7 +291,7 @@ impl<'a> Linker for GccLinker<'a> { LinkOutputKind::StaticNoPicExe => { // `-static` works for both gcc wrapper and ld. self.cmd.arg("-static"); - if !self.is_ld { + if !self.is_ld && self.sess.target.target.options.linker_is_gnu { self.cmd.arg("-no-pie"); } } diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs index c4f1fa2cb26b3..a15ac819be966 100644 --- a/src/librustc_infer/traits/mod.rs +++ b/src/librustc_infer/traits/mod.rs @@ -59,7 +59,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -static_assert_size!(PredicateObligation<'_>, 88); +static_assert_size!(PredicateObligation<'_>, 48); pub type Obligations<'tcx, O> = Vec>; pub type PredicateObligations<'tcx> = Vec>; diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs index 8081cac0067f1..ee9846c64b67c 100644 --- a/src/librustc_infer/traits/util.rs +++ b/src/librustc_infer/traits/util.rs @@ -142,10 +142,12 @@ fn predicate_obligation<'tcx>( predicate: ty::Predicate<'tcx>, span: Option, ) -> PredicateObligation<'tcx> { - let mut cause = ObligationCause::dummy(); - if let Some(span) = span { - cause.span = span; - } + let cause = if let Some(span) = span { + ObligationCause::dummy_with_span(span) + } else { + ObligationCause::dummy() + }; + Obligation { cause, param_env: ty::ParamEnv::empty(), recursion_depth: 0, predicate } } diff --git a/src/librustc_middle/macros.rs b/src/librustc_middle/macros.rs index 88ddd96eec8f5..a5482b7bdcfeb 100644 --- a/src/librustc_middle/macros.rs +++ b/src/librustc_middle/macros.rs @@ -1,16 +1,20 @@ #[macro_export] macro_rules! bug { - () => ( bug!("impossible case reached") ); - ($($message:tt)*) => ({ - $crate::util::bug::bug_fmt(file!(), line!(), format_args!($($message)*)) - }) + () => ( $crate::bug!("impossible case reached") ); + ($msg:expr) => ({ $crate::util::bug::bug_fmt(::std::format_args!($msg)) }); + ($msg:expr,) => ({ $crate::bug!($msg) }); + ($fmt:expr, $($arg:tt)+) => ({ + $crate::util::bug::bug_fmt(::std::format_args!($fmt, $($arg)+)) + }); } #[macro_export] macro_rules! span_bug { - ($span:expr, $($message:tt)*) => ({ - $crate::util::bug::span_bug_fmt(file!(), line!(), $span, format_args!($($message)*)) - }) + ($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) }); + ($span:expr, $msg:expr,) => ({ $crate::span_bug!($span, $msg) }); + ($span:expr, $fmt:expr, $($arg:tt)+) => ({ + $crate::util::bug::span_bug_fmt($span, ::std::format_args!($fmt, $($arg)+)) + }); } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index 56787304d4e7e..17ea84836bf0a 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -20,7 +20,8 @@ use rustc_span::{Span, DUMMY_SP}; use smallvec::SmallVec; use std::borrow::Cow; -use std::fmt::Debug; +use std::fmt; +use std::ops::Deref; use std::rc::Rc; pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; @@ -80,8 +81,39 @@ pub enum Reveal { } /// The reason why we incurred this obligation; used for error reporting. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +/// +/// As the happy path does not care about this struct, storing this on the heap +/// ends up increasing performance. +/// +/// We do not want to intern this as there are a lot of obligation causes which +/// only live for a short period of time. +#[derive(Clone, PartialEq, Eq, Hash)] pub struct ObligationCause<'tcx> { + /// `None` for `ObligationCause::dummy`, `Some` otherwise. + data: Option>>, +} + +const DUMMY_OBLIGATION_CAUSE_DATA: ObligationCauseData<'static> = + ObligationCauseData { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation }; + +// Correctly format `ObligationCause::dummy`. +impl<'tcx> fmt::Debug for ObligationCause<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ObligationCauseData::fmt(self, f) + } +} + +impl Deref for ObligationCause<'tcx> { + type Target = ObligationCauseData<'tcx>; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + self.data.as_deref().unwrap_or(&DUMMY_OBLIGATION_CAUSE_DATA) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ObligationCauseData<'tcx> { pub span: Span, /// The ID of the fn body that triggered this obligation. This is @@ -102,15 +134,24 @@ impl<'tcx> ObligationCause<'tcx> { body_id: hir::HirId, code: ObligationCauseCode<'tcx>, ) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code } + ObligationCause { data: Some(Rc::new(ObligationCauseData { span, body_id, code })) } } pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code: MiscObligation } + ObligationCause::new(span, body_id, MiscObligation) } + pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> { + ObligationCause::new(span, hir::CRATE_HIR_ID, MiscObligation) + } + + #[inline(always)] pub fn dummy() -> ObligationCause<'tcx> { - ObligationCause { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation } + ObligationCause { data: None } + } + + pub fn make_mut(&mut self) -> &mut ObligationCauseData<'tcx> { + Rc::make_mut(self.data.get_or_insert_with(|| Rc::new(DUMMY_OBLIGATION_CAUSE_DATA))) } pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span { diff --git a/src/librustc_middle/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs index 218bb144469b4..faaa576f17903 100644 --- a/src/librustc_middle/traits/structural_impls.rs +++ b/src/librustc_middle/traits/structural_impls.rs @@ -232,11 +232,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> { type Lifted = traits::ObligationCause<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.code).map(|code| traits::ObligationCause { - span: self.span, - body_id: self.body_id, - code, - }) + tcx.lift(&self.code).map(|code| traits::ObligationCause::new(self.span, self.body_id, code)) } } diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d5be3508d2d80..de2e1046f1cbb 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -189,8 +189,7 @@ fn validate_hir_id_for_typeck_tables( if hir_id.owner != hir_owner { ty::tls::with(|tcx| { bug!( - "node {} with HirId::owner {:?} cannot be placed in \ - TypeckTables with hir_owner {:?}", + "node {} with HirId::owner {:?} cannot be placed in TypeckTables with hir_owner {:?}", tcx.hir().node_to_string(hir_id), hir_id.owner, hir_owner diff --git a/src/librustc_middle/ty/list.rs b/src/librustc_middle/ty/list.rs index 161783bb370d4..76c72e4c2603d 100644 --- a/src/librustc_middle/ty/list.rs +++ b/src/librustc_middle/ty/list.rs @@ -55,7 +55,7 @@ impl List { .dropless .alloc_raw(size, cmp::max(mem::align_of::(), mem::align_of::())); unsafe { - let result = &mut *(mem.as_mut_ptr() as *mut List); + let result = &mut *(mem as *mut List); // Write the length result.len = slice.len(); diff --git a/src/librustc_middle/util/bug.rs b/src/librustc_middle/util/bug.rs index 54cd8a29f9474..9c3a97d8332f1 100644 --- a/src/librustc_middle/util/bug.rs +++ b/src/librustc_middle/util/bug.rs @@ -3,34 +3,31 @@ use crate::ty::{tls, TyCtxt}; use rustc_span::{MultiSpan, Span}; use std::fmt; +use std::panic::Location; #[cold] #[inline(never)] -pub fn bug_fmt(file: &'static str, line: u32, args: fmt::Arguments<'_>) -> ! { +#[track_caller] +pub fn bug_fmt(args: fmt::Arguments<'_>) -> ! { // this wrapper mostly exists so I don't have to write a fully // qualified path of None:: inside the bug!() macro definition - opt_span_bug_fmt(file, line, None::, args); + opt_span_bug_fmt(None::, args, Location::caller()); } #[cold] #[inline(never)] -pub fn span_bug_fmt>( - file: &'static str, - line: u32, - span: S, - args: fmt::Arguments<'_>, -) -> ! { - opt_span_bug_fmt(file, line, Some(span), args); +#[track_caller] +pub fn span_bug_fmt>(span: S, args: fmt::Arguments<'_>) -> ! { + opt_span_bug_fmt(Some(span), args, Location::caller()); } fn opt_span_bug_fmt>( - file: &'static str, - line: u32, span: Option, args: fmt::Arguments<'_>, + location: &Location<'_>, ) -> ! { tls::with_opt(move |tcx| { - let msg = format!("{}:{}: {}", file, line, args); + let msg = format!("{}: {}", location, args); match (tcx, span) { (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 168612f9beec0..7cf4fdfcf3c5b 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -1250,7 +1250,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { |infcx| { let mut obligations = ObligationAccumulator::default(); - let dummy_body_id = ObligationCause::dummy().body_id; + let dummy_body_id = hir::CRATE_HIR_ID; let (output_ty, opaque_type_map) = obligations.add(infcx.instantiate_opaque_types( anon_owner_def_id, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 994d1e69f2e3e..fc17aa9c31c59 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -586,6 +586,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.output.push(create_fn_mono_item(instance)); } } + mir::Rvalue::ThreadLocalRef(def_id) => { + assert!(self.tcx.is_thread_local_static(def_id)); + let instance = Instance::mono(self.tcx, def_id); + if should_monomorphize_locally(self.tcx, &instance) { + trace!("collecting thread-local static {:?}", def_id); + self.output.push(MonoItem::Static(def_id)); + } + } _ => { /* not interesting */ } } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 25b6a51d91b97..acadb5385c9cf 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -1222,7 +1222,11 @@ impl<'tcx> MirPass<'tcx> for StateTransform { movability == hir::Movability::Movable, ) } - _ => bug!(), + _ => { + tcx.sess + .delay_span_bug(body.span, &format!("unexpected generator type {}", gen_ty)); + return; + } }; // Compute GeneratorState diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs index aade1e708232e..d7b3e7e15307a 100644 --- a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs @@ -25,7 +25,6 @@ pub fn target() -> TargetResult { relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false, abi_blacklist: super::riscv_base::abi_blacklist(), - eliminate_frame_pointer: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs index e2990eeb826f7..b93b6fcf8002a 100644 --- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs @@ -25,7 +25,6 @@ pub fn target() -> TargetResult { relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false, abi_blacklist: super::riscv_base::abi_blacklist(), - eliminate_frame_pointer: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs index 55a4d58dfccca..a16e7e31c6619 100644 --- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs @@ -25,7 +25,6 @@ pub fn target() -> TargetResult { relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false, abi_blacklist: super::riscv_base::abi_blacklist(), - eliminate_frame_pointer: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs index 7376a14e951f5..e5147a12ed320 100644 --- a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs @@ -26,7 +26,6 @@ pub fn target() -> TargetResult { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, abi_blacklist: super::riscv_base::abi_blacklist(), - eliminate_frame_pointer: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs index a3b0eb5334f40..dc056b55b3868 100644 --- a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs @@ -26,7 +26,6 @@ pub fn target() -> TargetResult { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, abi_blacklist: super::riscv_base::abi_blacklist(), - eliminate_frame_pointer: false, ..Default::default() }, }) diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 4a08a3426c136..106753ed809a5 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -84,7 +84,7 @@ pub struct PendingPredicateObligation<'tcx> { // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -static_assert_size!(PendingPredicateObligation<'_>, 112); +static_assert_size!(PendingPredicateObligation<'_>, 72); impl<'a, 'tcx> FulfillmentContext<'tcx> { /// Creates a new fulfillment context. diff --git a/src/librustc_trait_selection/traits/misc.rs b/src/librustc_trait_selection/traits/misc.rs index 7403b936391cc..61567aeb57cb0 100644 --- a/src/librustc_trait_selection/traits/misc.rs +++ b/src/librustc_trait_selection/traits/misc.rs @@ -48,7 +48,7 @@ pub fn can_type_implement_copy( continue; } let span = tcx.def_span(field.did); - let cause = ObligationCause { span, ..ObligationCause::dummy() }; + let cause = ObligationCause::dummy_with_span(span); let ctx = traits::FulfillmentContext::new(); match traits::fully_normalize(&infcx, ctx, cause, param_env, &ty) { Ok(ty) => { diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs index 5024392a0f98d..90a9b876d8ddf 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/src/librustc_trait_selection/traits/wf.rs @@ -205,7 +205,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( if let Some(impl_item_span) = items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span) { - cause.span = impl_item_span; + cause.make_mut().span = impl_item_span; } } } @@ -222,7 +222,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( items.iter().find(|i| i.ident == trait_assoc_item.ident).map(fix_span) }) { - cause.span = impl_item_span; + cause.make_mut().span = impl_item_span; } } } @@ -273,7 +273,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { parent_trait_ref, parent_code: Rc::new(obligation.cause.code.clone()), }; - cause.code = traits::ObligationCauseCode::DerivedObligation(derived_cause); + cause.make_mut().code = + traits::ObligationCauseCode::DerivedObligation(derived_cause); } extend_cause_with_original_assoc_item_obligation( tcx, diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 5f8fcaadfdb0b..b39cfcb377595 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -78,15 +78,16 @@ fn compare_predicate_entailment<'tcx>( // `regionck_item` expects. let impl_m_hir_id = tcx.hir().as_local_hir_id(impl_m.def_id.expect_local()); - let cause = ObligationCause { - span: impl_m_span, - body_id: impl_m_hir_id, - code: ObligationCauseCode::CompareImplMethodObligation { + // We sometimes modify the span further down. + let mut cause = ObligationCause::new( + impl_m_span, + impl_m_hir_id, + ObligationCauseCode::CompareImplMethodObligation { item_name: impl_m.ident.name, impl_item_def_id: impl_m.def_id, trait_item_def_id: trait_m.def_id, }, - }; + ); // This code is best explained by example. Consider a trait: // @@ -280,7 +281,7 @@ fn compare_predicate_entailment<'tcx>( &infcx, param_env, &terr, &cause, impl_m, impl_sig, trait_m, trait_sig, ); - let cause = ObligationCause { span: impl_err_span, ..cause }; + cause.make_mut().span = impl_err_span; let mut diag = struct_span_err!( tcx.sess, @@ -965,8 +966,11 @@ crate fn compare_const_impl<'tcx>( // Compute placeholder form of impl and trait const tys. let impl_ty = tcx.type_of(impl_c.def_id); let trait_ty = tcx.type_of(trait_c.def_id).subst(tcx, trait_to_impl_substs); - let mut cause = ObligationCause::misc(impl_c_span, impl_c_hir_id); - cause.code = ObligationCauseCode::CompareImplConstObligation; + let mut cause = ObligationCause::new( + impl_c_span, + impl_c_hir_id, + ObligationCauseCode::CompareImplConstObligation, + ); // There is no "body" here, so just pass dummy id. let impl_ty = @@ -992,7 +996,7 @@ crate fn compare_const_impl<'tcx>( // Locate the Span containing just the type of the offending impl match tcx.hir().expect_impl_item(impl_c_hir_id).kind { - ImplItemKind::Const(ref ty, _) => cause.span = ty.span, + ImplItemKind::Const(ref ty, _) => cause.make_mut().span = ty.span, _ => bug!("{:?} is not a impl const", impl_c), } @@ -1095,15 +1099,15 @@ fn compare_type_predicate_entailment( // `ObligationCause` (and the `FnCtxt`). This is what // `regionck_item` expects. let impl_ty_hir_id = tcx.hir().as_local_hir_id(impl_ty.def_id.expect_local()); - let cause = ObligationCause { - span: impl_ty_span, - body_id: impl_ty_hir_id, - code: ObligationCauseCode::CompareImplTypeObligation { + let cause = ObligationCause::new( + impl_ty_span, + impl_ty_hir_id, + ObligationCauseCode::CompareImplTypeObligation { item_name: impl_ty.ident.name, impl_item_def_id: impl_ty.def_id, trait_item_def_id: trait_ty.def_id, }, - }; + ); debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a409e20953da1..c26acd7a47703 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4218,7 +4218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) { // We make sure that only *one* argument matches the obligation failure // and we assign the obligation's span to its expression's. - error.obligation.cause.span = args[ref_in].span; + error.obligation.cause.make_mut().span = args[ref_in].span; error.points_at_arg_span = true; } } @@ -4261,7 +4261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = AstConv::ast_ty_to_ty(self, hir_ty); let ty = self.resolve_vars_if_possible(&ty); if ty == predicate.skip_binder().self_ty() { - error.obligation.cause.span = hir_ty.span; + error.obligation.cause.make_mut().span = hir_ty.span; } } } @@ -5689,7 +5689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // This makes the error point at the bound, but we want to point at the argument if let Some(span) = spans.get(i) { - obligation.cause.code = traits::BindingObligation(def_id, *span); + obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span); } self.register_predicate(obligation); } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 07631093edda4..1681b73d0c257 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4338,6 +4338,8 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) { } } + sidebar.push_str(&sidebar_assoc_items(it)); + sidebar.push_str("Implementors"); if t.auto { sidebar.push_str( @@ -4346,8 +4348,6 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) { ); } - sidebar.push_str(&sidebar_assoc_items(it)); - write!(buf, "
{}
", sidebar) } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 6a120f930ab15..d22ac1d538584 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -201,8 +201,7 @@ fn default_hook(info: &PanicInfo<'_>) { if FIRST_PANIC.swap(false, Ordering::SeqCst) { let _ = writeln!( err, - "note: run with `RUST_BACKTRACE=1` \ - environment variable to display a backtrace" + "note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace" ); } } @@ -454,10 +453,7 @@ fn rust_panic_with_hook( // process real quickly as we don't want to try calling it again as it'll // probably just panic again. if panics > 2 { - util::dumb_print(format_args!( - "thread panicked while processing \ - panic. aborting.\n" - )); + util::dumb_print(format_args!("thread panicked while processing panic. aborting.\n")); intrinsics::abort() } @@ -489,10 +485,7 @@ fn rust_panic_with_hook( // have limited options. Currently our preference is to // just abort. In the future we may consider resuming // unwinding or otherwise exiting the thread cleanly. - util::dumb_print(format_args!( - "thread panicked while panicking. \ - aborting.\n" - )); + util::dumb_print(format_args!("thread panicked while panicking. aborting.\n")); intrinsics::abort() } diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs index 9e588c4265ac2..8a788a9265f63 100644 --- a/src/libstd/sys/hermit/net.rs +++ b/src/libstd/sys/hermit/net.rs @@ -147,10 +147,7 @@ impl TcpStream { .map_err(|_| io::Error::new(ErrorKind::Other, "peer_addr failed"))?; let saddr = match ipaddr { - Ipv4(ref addr) => SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(addr.0[0], addr.0[1], addr.0[2], addr.0[3])), - port, - ), + Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port), Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port), _ => { return Err(io::Error::new(ErrorKind::Other, "peer_addr failed")); @@ -227,10 +224,7 @@ impl TcpListener { let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port()) .map_err(|_| io::Error::new(ErrorKind::Other, "accept failed"))?; let saddr = match ipaddr { - Ipv4(ref addr) => SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(addr.0[0], addr.0[1], addr.0[2], addr.0[3])), - port, - ), + Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port), Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port), _ => { return Err(io::Error::new(ErrorKind::Other, "accept failed")); diff --git a/src/llvm-project b/src/llvm-project index 02e0d7fa5547f..0ddefeca92b2e 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 02e0d7fa5547f2b270b8b57cf4f4f8e177153c8d +Subproject commit 0ddefeca92b2e1835c80e9b01d9ecc7efc906b1c diff --git a/src/test/ui/tls.rs b/src/test/ui/tls.rs new file mode 100644 index 0000000000000..fbd3413885f8f --- /dev/null +++ b/src/test/ui/tls.rs @@ -0,0 +1,14 @@ +// run-pass +// ignore-emscripten no threads support +// compile-flags: -O + +#![feature(thread_local)] + +#[thread_local] +static S: u32 = 222; + +fn main() { + let local = &S as *const u32 as usize; + let foreign = std::thread::spawn(|| &S as *const u32 as usize).join().unwrap(); + assert_ne!(local, foreign); +}