Skip to content
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

Rollup of 7 pull requests #89172

Closed
wants to merge 18 commits into from
Closed
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
@@ -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();
@@ -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));
@@ -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");
}

8 changes: 2 additions & 6 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -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(
4 changes: 3 additions & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};
4 changes: 2 additions & 2 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
@@ -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);
@@ -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
3 changes: 3 additions & 0 deletions compiler/rustc_parse/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};
1 change: 1 addition & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -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,
32 changes: 26 additions & 6 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};
@@ -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 },
)
}

5 changes: 3 additions & 2 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
@@ -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),
2 changes: 2 additions & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
@@ -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.
@@ -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]>`
1 change: 1 addition & 0 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -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))]
16 changes: 8 additions & 8 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
}
@@ -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(())
}
@@ -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(())
@@ -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)
}
}
}
@@ -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)
}
}
}
@@ -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,
@@ -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;
92 changes: 70 additions & 22 deletions library/core/src/time.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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")
}
}
}
Loading