Skip to content

Commit

Permalink
Auto merge of rust-lang#72794 - RalfJung:rollup-gzs4nl4, r=RalfJung
Browse files Browse the repository at this point in the history
Rollup of 13 pull requests

Successful merges:

 - rust-lang#72543 (Account for missing lifetime in opaque and trait object return types)
 - rust-lang#72625 (Improve inline asm error diagnostics)
 - rust-lang#72637 (expand `env!` with def-site context)
 - rust-lang#72650 (Sort sidebar elements)
 - rust-lang#72657 (Allow types (with lifetimes/generics) in impl_lint_pass)
 - rust-lang#72666 (Add -Z profile-emit=<path> for Gcov gcda output.)
 - rust-lang#72668 (Fix missing parentheses Fn notation error)
 - rust-lang#72669 (rustc_session: Cleanup session creation)
 - rust-lang#72728 (Make bootstrap aware of relative libdir in stage0 compiler)
 - rust-lang#72757 (rustc_lexer: Optimize shebang detection slightly)
 - rust-lang#72772 (miri validation: clarify valid values of 'char')
 - rust-lang#72773 (Fix is_char_boundary documentation)
 - rust-lang#72777 (rustdoc: remove calls to `local_def_id_from_node_id`)

Failed merges:

r? @ghost
  • Loading branch information
bors committed May 30, 2020
2 parents 74e8046 + 581eafc commit 8c5402e
Show file tree
Hide file tree
Showing 111 changed files with 1,467 additions and 850 deletions.
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ impl<'a> Builder<'a> {
pub fn sysroot_libdir_relative(&self, compiler: Compiler) -> &Path {
match self.config.libdir_relative() {
Some(relative_libdir) if compiler.stage >= 1 => relative_libdir,
_ if compiler.stage == 0 => &self.build.initial_libdir,
_ => Path::new("lib"),
}
}
Expand Down
36 changes: 29 additions & 7 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ pub struct Build {
initial_rustc: PathBuf,
initial_cargo: PathBuf,
initial_lld: PathBuf,
initial_libdir: PathBuf,

// Runtime state filled in later on
// C/C++ compilers and archiver for all targets
Expand Down Expand Up @@ -344,18 +345,39 @@ impl Build {
// we always try to use git for LLVM builds
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));

let initial_sysroot = config.initial_rustc.parent().unwrap().parent().unwrap();
let initial_lld = initial_sysroot
.join("lib")
.join("rustlib")
.join(config.build)
.join("bin")
.join("rust-lld");
let initial_target_libdir_str = if config.dry_run {
"/dummy/lib/path/to/lib/".to_string()
} else {
output(
Command::new(&config.initial_rustc)
.arg("--target")
.arg(config.build)
.arg("--print")
.arg("target-libdir"),
)
};
let initial_target_dir = Path::new(&initial_target_libdir_str).parent().unwrap();
let initial_lld = initial_target_dir.join("bin").join("rust-lld");

let initial_sysroot = if config.dry_run {
"/dummy".to_string()
} else {
output(Command::new(&config.initial_rustc).arg("--print").arg("sysroot"))
};
let initial_libdir = initial_target_dir
.parent()
.unwrap()
.parent()
.unwrap()
.strip_prefix(initial_sysroot.trim())
.unwrap()
.to_path_buf();

let mut build = Build {
initial_rustc: config.initial_rustc.clone(),
initial_cargo: config.initial_cargo.clone(),
initial_lld,
initial_libdir,
local_rebuild: config.local_rebuild,
fail_fast: config.cmd.fail_fast(),
doc_tests: config.cmd.doc_tests(),
Expand Down
7 changes: 3 additions & 4 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2270,12 +2270,11 @@ impl str {
self.len() == 0
}

/// Checks that `index`-th byte lies at the start and/or end of a
/// UTF-8 code point sequence.
/// Checks that `index`-th byte is the first byte in a UTF-8 code point
/// sequence or the end of the string.
///
/// The start and end of the string (when `index == self.len()`) are
/// considered to be
/// boundaries.
/// considered to be boundaries.
///
/// Returns `false` if `index` is greater than `self.len()`.
///
Expand Down
24 changes: 23 additions & 1 deletion src/libfmt_macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ pub struct Parser<'a> {
append_newline: bool,
/// Whether this formatting string is a literal or it comes from a macro.
is_literal: bool,
/// Start position of the current line.
cur_line_start: usize,
/// Start and end byte offset of every line of the format string. Excludes
/// newline characters and leading whitespace.
pub line_spans: Vec<InnerSpan>,
}

impl<'a> Iterator for Parser<'a> {
Expand Down Expand Up @@ -235,10 +240,15 @@ impl<'a> Iterator for Parser<'a> {
None
}
}
'\n' => Some(String(self.string(pos))),
_ => Some(String(self.string(pos))),
}
} else {
if self.is_literal && self.cur_line_start != self.input.len() {
let start = self.to_span_index(self.cur_line_start);
let end = self.to_span_index(self.input.len());
self.line_spans.push(start.to(end));
self.cur_line_start = self.input.len();
}
None
}
}
Expand Down Expand Up @@ -266,6 +276,8 @@ impl<'a> Parser<'a> {
last_opening_brace: None,
append_newline,
is_literal,
cur_line_start: 0,
line_spans: vec![],
}
}

Expand Down Expand Up @@ -433,7 +445,17 @@ impl<'a> Parser<'a> {
'{' | '}' => {
return &self.input[start..pos];
}
'\n' if self.is_literal => {
let start = self.to_span_index(self.cur_line_start);
let end = self.to_span_index(pos);
self.line_spans.push(start.to(end));
self.cur_line_start = pos + 1;
self.cur.next();
}
_ => {
if self.is_literal && pos == self.cur_line_start && c.is_whitespace() {
self.cur_line_start = pos + c.len_utf8();
}
self.cur.next();
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ pub enum ExprKind {
Ret(Option<P<Expr>>),

/// Output of the `asm!()` macro.
InlineAsm(InlineAsm),
InlineAsm(P<InlineAsm>),
/// Output of the `llvm_asm!()` macro.
LlvmInlineAsm(P<LlvmInlineAsm>),

Expand Down Expand Up @@ -1971,6 +1971,7 @@ pub struct InlineAsm {
pub template: Vec<InlineAsmTemplatePiece>,
pub operands: Vec<(InlineAsmOperand, Span)>,
pub options: InlineAsmOptions,
pub line_spans: Vec<Span>,
}

/// Inline assembly dialect.
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_ast_lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,8 @@ impl<'hir> LoweringContext<'_, 'hir> {

let operands = self.arena.alloc_from_iter(operands);
let template = self.arena.alloc_from_iter(asm.template.iter().cloned());
let hir_asm = hir::InlineAsm { template, operands, options: asm.options };
let line_spans = self.arena.alloc_slice(&asm.line_spans[..]);
let hir_asm = hir::InlineAsm { template, operands, options: asm.options, line_spans };
hir::ExprKind::InlineAsm(self.arena.alloc(hir_asm))
}

Expand Down
10 changes: 8 additions & 2 deletions src/librustc_builtin_macros/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,16 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
}
}

let inline_asm = ast::InlineAsm { template, operands, options: args.options };
let line_spans = if parser.line_spans.is_empty() {
vec![template_sp]
} else {
parser.line_spans.iter().map(|span| template_span.from_inner(*span)).collect()
};

let inline_asm = ast::InlineAsm { template, operands, options: args.options, line_spans };
P(ast::Expr {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::InlineAsm(inline_asm),
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
span: sp,
attrs: ast::AttrVec::new(),
tokens: None,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_builtin_macros/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub fn expand_env<'cx>(
return DummyResult::any(sp);
}

let sp = cx.with_def_site_ctxt(sp);
let e = match env::var(&*var.as_str()) {
Err(_) => {
cx.span_err(sp, &msg.as_str());
Expand Down
32 changes: 24 additions & 8 deletions src/librustc_codegen_llvm/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_span::Span;
use rustc_span::{Pos, Span};
use rustc_target::abi::*;
use rustc_target::asm::*;

Expand Down Expand Up @@ -97,7 +97,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
ia.volatile,
ia.alignstack,
ia.dialect,
span,
&[span],
);
if r.is_none() {
return false;
Expand All @@ -119,7 +119,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
template: &[InlineAsmTemplatePiece],
operands: &[InlineAsmOperandRef<'tcx, Self>],
options: InlineAsmOptions,
span: Span,
line_spans: &[Span],
) {
let asm_arch = self.tcx.sess.asm_arch.unwrap();

Expand Down Expand Up @@ -287,9 +287,9 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
volatile,
alignstack,
dialect,
span,
line_spans,
)
.unwrap_or_else(|| span_bug!(span, "LLVM asm constraint validation failed"));
.unwrap_or_else(|| span_bug!(line_spans[0], "LLVM asm constraint validation failed"));

if options.contains(InlineAsmOptions::PURE) {
if options.contains(InlineAsmOptions::NOMEM) {
Expand Down Expand Up @@ -341,7 +341,7 @@ fn inline_asm_call(
volatile: bool,
alignstack: bool,
dia: LlvmAsmDialect,
span: Span,
line_spans: &[Span],
) -> Option<&'ll Value> {
let volatile = if volatile { llvm::True } else { llvm::False };
let alignstack = if alignstack { llvm::True } else { llvm::False };
Expand Down Expand Up @@ -382,8 +382,24 @@ fn inline_asm_call(
key.len() as c_uint,
);

let val: &'ll Value = bx.const_i32(span.ctxt().outer_expn().as_u32() as i32);
llvm::LLVMSetMetadata(call, kind, llvm::LLVMMDNodeInContext(bx.llcx, &val, 1));
// srcloc contains one integer for each line of assembly code.
// Unfortunately this isn't enough to encode a full span so instead
// we just encode the start position of each line.
// FIXME: Figure out a way to pass the entire line spans.
let mut srcloc = vec![];
if dia == LlvmAsmDialect::Intel && line_spans.len() > 1 {
// LLVM inserts an extra line to add the ".intel_syntax", so add
// a dummy srcloc entry for it.
//
// Don't do this if we only have 1 line span since that may be
// due to the asm template string coming from a macro. LLVM will
// default to the first srcloc for lines that don't have an
// associated srcloc.
srcloc.push(bx.const_i32(0));
}
srcloc.extend(line_spans.iter().map(|span| bx.const_i32(span.lo().to_u32() as i32)));
let md = llvm::LLVMMDNodeInContext(bx.llcx, srcloc.as_ptr(), srcloc.len() as u32);
llvm::LLVMSetMetadata(call, kind, md);

Some(call)
} else {
Expand Down
51 changes: 43 additions & 8 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, Lto, OutputType, Passes, Sanitizer, SwitchWithOptPath};
use rustc_session::Session;
use rustc_span::InnerSpan;
use rustc_target::spec::{CodeModel, RelocModel};

use libc::{c_char, c_int, c_uint, c_void, size_t};
Expand Down Expand Up @@ -238,12 +239,19 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
}
}

unsafe extern "C" fn report_inline_asm(
fn report_inline_asm(
cgcx: &CodegenContext<LlvmCodegenBackend>,
msg: &str,
cookie: c_uint,
msg: String,
mut cookie: c_uint,
source: Option<(String, Vec<InnerSpan>)>,
) {
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
// In LTO build we may get srcloc values from other crates which are invalid
// since they use a different source map. To be safe we just suppress these
// in LTO builds.
if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
cookie = 0;
}
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, source);
}

unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) {
Expand All @@ -252,10 +260,37 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
}
let (cgcx, _) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));

let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
.expect("non-UTF8 SMDiagnostic");
// Recover the post-substitution assembly code from LLVM for better
// diagnostics.
let mut have_source = false;
let mut buffer = String::new();
let mut loc = 0;
let mut ranges = [0; 8];
let mut num_ranges = ranges.len() / 2;
let msg = llvm::build_string(|msg| {
buffer = llvm::build_string(|buffer| {
have_source = llvm::LLVMRustUnpackSMDiagnostic(
diag,
msg,
buffer,
&mut loc,
ranges.as_mut_ptr(),
&mut num_ranges,
);
})
.expect("non-UTF8 inline asm");
})
.expect("non-UTF8 SMDiagnostic");

let source = have_source.then(|| {
let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
for i in 0..num_ranges {
spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
}
(buffer, spans)
});

report_inline_asm(cgcx, &msg, cookie);
report_inline_asm(cgcx, msg, cookie, source);
}

unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
Expand All @@ -266,7 +301,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void

match llvm::diagnostic::Diagnostic::unpack(info) {
llvm::diagnostic::InlineAsm(inline) => {
report_inline_asm(cgcx, &llvm::twine_to_string(inline.message), inline.cookie);
report_inline_asm(cgcx, llvm::twine_to_string(inline.message), inline.cookie, None);
}

llvm::diagnostic::Optimization(opt) => {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,16 +959,16 @@ pub fn compile_unit_metadata(
if tcx.sess.opts.debugging_opts.profile {
let cu_desc_metadata =
llvm::LLVMRustMetadataAsValue(debug_context.llcontext, unit_metadata);
let default_gcda_path = &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda");
let gcda_path =
tcx.sess.opts.debugging_opts.profile_emit.as_ref().unwrap_or(default_gcda_path);

let gcov_cu_info = [
path_to_mdstring(
debug_context.llcontext,
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcno"),
),
path_to_mdstring(
debug_context.llcontext,
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcda"),
),
path_to_mdstring(debug_context.llcontext, &gcda_path),
cu_desc_metadata,
];
let gcov_metadata = llvm::LLVMMDNodeInContext(
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2070,7 +2070,14 @@ extern "C" {
);

#[allow(improper_ctypes)]
pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString);
pub fn LLVMRustUnpackSMDiagnostic(
d: &SMDiagnostic,
message_out: &RustString,
buffer_out: &RustString,
loc_out: &mut c_uint,
ranges_out: *mut c_uint,
num_ranges: &mut usize,
) -> bool;

pub fn LLVMRustWriteArchive(
Dst: *const c_char,
Expand Down
Loading

0 comments on commit 8c5402e

Please sign in to comment.