Merge pull request #4 from rust-lang/master
update from origin 2020-06-18
This commit is contained in:
commit
7ef9eb321a
37 changed files with 223 additions and 133 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -244,6 +244,16 @@ pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, 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)]
|
||||
|
|
|
|||
|
|
@ -149,7 +149,12 @@ To learn more about a subcommand, run `./x.py <subcommand> -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(
|
||||
"",
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
self.align(align);
|
||||
|
||||
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<T>(&self, object: T) -> &mut T {
|
||||
assert!(!mem::needs_drop::<T>());
|
||||
|
||||
let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
|
||||
let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
|
||||
|
||||
unsafe {
|
||||
// Write into uninitialized memory.
|
||||
|
|
@ -418,13 +431,11 @@ impl DroplessArena {
|
|||
assert!(mem::size_of::<T>() != 0);
|
||||
assert!(!slice.is_empty());
|
||||
|
||||
let mem = self.alloc_raw(slice.len() * mem::size_of::<T>(), mem::align_of::<T>()) as *mut _
|
||||
as *mut T;
|
||||
let mem = self.alloc_raw(slice.len() * mem::size_of::<T>(), mem::align_of::<T>()) 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::<T>()).unwrap();
|
||||
let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T;
|
||||
let mem = self.alloc_raw(size, mem::align_of::<T>()) 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::<T>(), mem::align_of::<T>())
|
||||
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<T>(&self, object: T) -> &mut T {
|
||||
let mem =
|
||||
self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
|
||||
let mem = self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) 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::<T>()).unwrap(), mem::align_of::<T>())
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Obligation<'tcx, O>>;
|
||||
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
||||
|
|
|
|||
|
|
@ -142,10 +142,12 @@ fn predicate_obligation<'tcx>(
|
|||
predicate: ty::Predicate<'tcx>,
|
||||
span: Option<Span>,
|
||||
) -> 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 }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)+))
|
||||
});
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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<Rc<ObligationCauseData<'tcx>>>,
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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<Self::Lifted> {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl<T: Copy> List<T> {
|
|||
.dropless
|
||||
.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
|
||||
unsafe {
|
||||
let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
|
||||
let result = &mut *(mem as *mut List<T>);
|
||||
// Write the length
|
||||
result.len = slice.len();
|
||||
|
||||
|
|
|
|||
|
|
@ -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::<Span> inside the bug!() macro definition
|
||||
opt_span_bug_fmt(file, line, None::<Span>, args);
|
||||
opt_span_bug_fmt(None::<Span>, args, Location::caller());
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
pub fn span_bug_fmt<S: Into<MultiSpan>>(
|
||||
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<S: Into<MultiSpan>>(span: S, args: fmt::Arguments<'_>) -> ! {
|
||||
opt_span_bug_fmt(Some(span), args, Location::caller());
|
||||
}
|
||||
|
||||
fn opt_span_bug_fmt<S: Into<MultiSpan>>(
|
||||
file: &'static str,
|
||||
line: u32,
|
||||
span: Option<S>,
|
||||
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),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */ }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<yield_ty, return_ty>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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("<a class=\"sidebar-title\" href=\"#implementors\">Implementors</a>");
|
||||
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, "<div class=\"block items\">{}</div>", sidebar)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 02e0d7fa5547f2b270b8b57cf4f4f8e177153c8d
|
||||
Subproject commit 0ddefeca92b2e1835c80e9b01d9ecc7efc906b1c
|
||||
14
src/test/ui/tls.rs
Normal file
14
src/test/ui/tls.rs
Normal file
|
|
@ -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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue