Skip to content

Rollup of 7 pull requests #89172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,20 @@ fn fat_lto(
drop(linker);
save_temp_bitcode(&cgcx, &module, "lto.input");

// Fat LTO also suffers from the invalid DWARF issue similar to Thin LTO.
// Here we rewrite all `DICompileUnit` pointers if there is only one `DICompileUnit`.
// This only works around the problem when codegen-units = 1.
// Refer to the comments in the `optimize_thin_module` function for more details.
let mut cu1 = ptr::null_mut();
let mut cu2 = ptr::null_mut();
unsafe { llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2) };
if !cu2.is_null() {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_fat_lto_patch_debuginfo", &*module.name);
unsafe { llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1) };
save_temp_bitcode(cgcx, &module, "fat-lto-after-patch");
}

// Internalize everything below threshold to help strip out more modules and such.
unsafe {
let ptr = symbols_below_threshold.as_ptr();
Expand Down Expand Up @@ -748,7 +762,7 @@ pub unsafe fn optimize_thin_module(
// an error.
let mut cu1 = ptr::null_mut();
let mut cu2 = ptr::null_mut();
llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
if !cu2.is_null() {
let msg = "multiple source DICompileUnits found";
return Err(write::llvm_err(&diag_handler, msg));
Expand Down Expand Up @@ -847,7 +861,7 @@ pub unsafe fn optimize_thin_module(
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1);
save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
}

Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2377,12 +2377,8 @@ extern "C" {
len: usize,
out_len: &mut usize,
) -> *const u8;
pub fn LLVMRustThinLTOGetDICompileUnit(
M: &Module,
CU1: &mut *mut c_void,
CU2: &mut *mut c_void,
);
pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
pub fn LLVMRustLTOGetDICompileUnit(M: &Module, CU1: &mut *mut c_void, CU2: &mut *mut c_void);
pub fn LLVMRustLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);

pub fn LLVMRustLinkerNew(M: &'a Module) -> &'a mut Linker<'a>;
pub fn LLVMRustLinkerAdd(
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#[macro_use]
extern crate rustc_macros;

#[macro_use]
extern crate tracing;

pub use emitter::ColorConfig;

use tracing::debug;
use Level::*;

use emitter::{is_case_difference, Emitter, EmitterWriter};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,7 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
// the comment in `back/lto.rs` for why this exists.
extern "C" void
LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod,
DICompileUnit **A,
DICompileUnit **B) {
Module *M = unwrap(Mod);
Expand All @@ -1765,7 +1765,7 @@ LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
// the comment in `back/lto.rs` for why this exists.
extern "C" void
LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
LLVMRustLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
Module *M = unwrap(Mod);

// If the original source module didn't have a `DICompileUnit` then try to
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#![feature(box_patterns)]
#![recursion_limit = "256"]

#[macro_use]
extern crate tracing;

use rustc_ast as ast;
use rustc_ast::token::{self, Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{self, AttributesData, CanSynthesizeMissingTokens, LazyTokenStream};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,7 @@ impl<'a> Parser<'a> {

/// If we encounter a parser state that looks like the user has written a `struct` literal with
/// parentheses instead of braces, recover the parser state and provide suggestions.
#[instrument(skip(self, seq, snapshot), level = "trace")]
fn maybe_recover_struct_lit_bad_delims(
&mut self,
lo: Span,
Expand Down
32 changes: 26 additions & 6 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#[macro_use]
extern crate rustc_macros;

#[macro_use]
extern crate tracing;

use rustc_data_structures::AtomicRef;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
Expand Down Expand Up @@ -782,13 +785,30 @@ impl Span {
/// ^^^^^^^^^^^^^^^^^
/// ```
pub fn until(self, end: Span) -> Span {
let span = self.data();
let end = end.data();
// Most of this function's body is copied from `to`.
// We can't just do `self.to(end.shrink_to_lo())`,
// because to also does some magic where it uses min/max so
// it can handle overlapping spans. Some advanced mis-use of
// `until` with different ctxts makes this visible.
let span_data = self.data();
let end_data = end.data();
// FIXME(jseyfried): `self.ctxt` should always equal `end.ctxt` here (cf. issue #23480).
// Return the macro span on its own to avoid weird diagnostic output. It is preferable to
// have an incomplete span than a completely nonsensical one.
if span_data.ctxt != end_data.ctxt {
if span_data.ctxt == SyntaxContext::root() {
return end;
} else if end_data.ctxt == SyntaxContext::root() {
return self;
}
// Both spans fall within a macro.
// FIXME(estebank): check if it is the *same* macro.
}
Span::new(
span.lo,
end.lo,
if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
if span.parent == end.parent { span.parent } else { None },
span_data.lo,
end_data.lo,
if end_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
if span_data.parent == end_data.parent { span_data.parent } else { None },
)
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,12 @@ impl SourceMap {
f.lookup_line(sp.lo()) != f.lookup_line(sp.hi())
}

#[instrument(skip(self), level = "trace")]
pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> {
let lo = self.lookup_char_pos(sp.lo());
debug!("span_to_lines: lo={:?}", lo);
trace!(?lo);
let hi = self.lookup_char_pos(sp.hi());
debug!("span_to_lines: hi={:?}", hi);
trace!(?hi);
if lo.file.start_pos != hi.file.start_pos {
return Err(SpanLinesError::DistinctSources(DistinctSources {
begin: (lo.file.name.clone(), lo.file.start_pos),
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Box<T> {
/// Creates a `Box<T>`, with the `Default` value for T.
Expand Down Expand Up @@ -1394,6 +1395,7 @@ impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_array", since = "1.45.0")]
impl<T, const N: usize> From<[T; N]> for Box<[T]> {
/// Converts a `[T; N]` into a `Box<[T]>`
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2841,6 +2841,7 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_from_array", since = "1.44.0")]
impl<T, const N: usize> From<[T; N]> for Vec<T> {
#[cfg(not(test))]
Expand Down
16 changes: 8 additions & 8 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,7 @@ unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize

/// Padding after the end of something. Returned by `Formatter::padding`.
#[must_use = "don't forget to write the post padding"]
struct PostPadding {
pub(crate) struct PostPadding {
fill: char,
padding: usize,
}
Expand All @@ -1200,9 +1200,9 @@ impl PostPadding {
}

/// Write this post padding.
fn write(self, buf: &mut dyn Write) -> Result {
pub(crate) fn write(self, f: &mut Formatter<'_>) -> Result {
for _ in 0..self.padding {
buf.write_char(self.fill)?;
f.buf.write_char(self.fill)?;
}
Ok(())
}
Expand Down Expand Up @@ -1325,7 +1325,7 @@ impl<'a> Formatter<'a> {
write_prefix(self, sign, prefix)?;
let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?;
self.buf.write_str(buf)?;
post_padding.write(self.buf)?;
post_padding.write(self)?;
self.fill = old_fill;
self.align = old_align;
Ok(())
Expand All @@ -1335,7 +1335,7 @@ impl<'a> Formatter<'a> {
let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?;
write_prefix(self, sign, prefix)?;
self.buf.write_str(buf)?;
post_padding.write(self.buf)
post_padding.write(self)
}
}
}
Expand Down Expand Up @@ -1410,7 +1410,7 @@ impl<'a> Formatter<'a> {
let align = rt::v1::Alignment::Left;
let post_padding = self.padding(width - chars_count, align)?;
self.buf.write_str(s)?;
post_padding.write(self.buf)
post_padding.write(self)
}
}
}
Expand All @@ -1419,7 +1419,7 @@ impl<'a> Formatter<'a> {
/// Write the pre-padding and return the unwritten post-padding. Callers are
/// responsible for ensuring post-padding is written after the thing that is
/// being padded.
fn padding(
pub(crate) fn padding(
&mut self,
padding: usize,
default: rt::v1::Alignment,
Expand Down Expand Up @@ -1474,7 +1474,7 @@ impl<'a> Formatter<'a> {
} else {
let post_padding = self.padding(width - len, align)?;
self.write_formatted_parts(&formatted)?;
post_padding.write(self.buf)
post_padding.write(self)
};
self.fill = old_fill;
self.align = old_align;
Expand Down
92 changes: 70 additions & 22 deletions library/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1049,11 +1049,16 @@ impl fmt::Debug for Duration {
/// `divisor` must not be above 100_000_000. It also should be a power
/// of 10, everything else doesn't make sense. `fractional_part` has
/// to be less than `10 * divisor`!
///
/// A prefix and postfix may be added. The whole thing is padded
/// to the formatter's `width`, if specified.
fn fmt_decimal(
f: &mut fmt::Formatter<'_>,
mut integer_part: u64,
mut fractional_part: u32,
mut divisor: u32,
prefix: &str,
postfix: &str,
) -> fmt::Result {
// Encode the fractional part into a temporary buffer. The buffer
// only need to hold 9 elements, because `fractional_part` has to
Expand Down Expand Up @@ -1114,48 +1119,91 @@ impl fmt::Debug for Duration {
// set, we only use all digits up to the last non-zero one.
let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);

// If we haven't emitted a single fractional digit and the precision
// wasn't set to a non-zero value, we don't print the decimal point.
if end == 0 {
write!(f, "{}", integer_part)
} else {
// SAFETY: We are only writing ASCII digits into the buffer and it was
// initialized with '0's, so it contains valid UTF8.
let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
// This closure emits the formatted duration without emitting any
// padding (padding is calculated below).
let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
write!(f, "{}{}", prefix, integer_part)?;

// Write the decimal point and the fractional part (if any).
if end > 0 {
// SAFETY: We are only writing ASCII digits into the buffer and
// it was initialized with '0's, so it contains valid UTF8.
let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };

// If the user request a precision > 9, we pad '0's at the end.
let w = f.precision().unwrap_or(pos);
write!(f, ".{:0<width$}", s, width = w)?;
}

// If the user request a precision > 9, we pad '0's at the end.
let w = f.precision().unwrap_or(pos);
write!(f, "{}.{:0<width$}", integer_part, s, width = w)
write!(f, "{}", postfix)
};

match f.width() {
None => {
// No `width` specified. There's no need to calculate the
// length of the output in this case, just emit it.
emit_without_padding(f)
}
Some(requested_w) => {
// A `width` was specified. Calculate the actual width of
// the output in order to calculate the required padding.
// It consists of 4 parts:
// 1. The prefix: is either "+" or "", so we can just use len().
// 2. The postfix: can be "µs" so we have to count UTF8 characters.
let mut actual_w = prefix.len() + postfix.chars().count();
// 3. The integer part:
if let Some(log) = integer_part.checked_log10() {
// integer_part is > 0, so has length log10(x)+1
actual_w += 1 + log as usize;
} else {
// integer_part is 0, so has length 1.
actual_w += 1;
}
// 4. The fractional part (if any):
if end > 0 {
let frac_part_w = f.precision().unwrap_or(pos);
actual_w += 1 + frac_part_w;
}

if requested_w <= actual_w {
// Output is already longer than `width`, so don't pad.
emit_without_padding(f)
} else {
// We need to add padding. Use the `Formatter::padding` helper function.
let default_align = crate::fmt::rt::v1::Alignment::Left;
let post_padding = f.padding(requested_w - actual_w, default_align)?;
emit_without_padding(f)?;
post_padding.write(f)
}
}
}
}

// Print leading '+' sign if requested
if f.sign_plus() {
write!(f, "+")?;
}
let prefix = if f.sign_plus() { "+" } else { "" };

if self.secs > 0 {
fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10)?;
f.write_str("s")
fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10, prefix, "s")
} else if self.nanos >= NANOS_PER_MILLI {
fmt_decimal(
f,
(self.nanos / NANOS_PER_MILLI) as u64,
self.nanos % NANOS_PER_MILLI,
NANOS_PER_MILLI / 10,
)?;
f.write_str("ms")
prefix,
"ms",
)
} else if self.nanos >= NANOS_PER_MICRO {
fmt_decimal(
f,
(self.nanos / NANOS_PER_MICRO) as u64,
self.nanos % NANOS_PER_MICRO,
NANOS_PER_MICRO / 10,
)?;
f.write_str("µs")
prefix,
"µs",
)
} else {
fmt_decimal(f, self.nanos as u64, 0, 1)?;
f.write_str("ns")
fmt_decimal(f, self.nanos as u64, 0, 1, prefix, "ns")
}
}
}
Expand Down
Loading