Skip to content

Commit 8c5402e

Browse files
committed
Auto merge of rust-lang#72794 - RalfJung:rollup-gzs4nl4, r=RalfJung
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
2 parents 74e8046 + 581eafc commit 8c5402e

File tree

111 files changed

+1467
-850
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1467
-850
lines changed

src/bootstrap/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ impl<'a> Builder<'a> {
648648
pub fn sysroot_libdir_relative(&self, compiler: Compiler) -> &Path {
649649
match self.config.libdir_relative() {
650650
Some(relative_libdir) if compiler.stage >= 1 => relative_libdir,
651+
_ if compiler.stage == 0 => &self.build.initial_libdir,
651652
_ => Path::new("lib"),
652653
}
653654
}

src/bootstrap/lib.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ pub struct Build {
243243
initial_rustc: PathBuf,
244244
initial_cargo: PathBuf,
245245
initial_lld: PathBuf,
246+
initial_libdir: PathBuf,
246247

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

347-
let initial_sysroot = config.initial_rustc.parent().unwrap().parent().unwrap();
348-
let initial_lld = initial_sysroot
349-
.join("lib")
350-
.join("rustlib")
351-
.join(config.build)
352-
.join("bin")
353-
.join("rust-lld");
348+
let initial_target_libdir_str = if config.dry_run {
349+
"/dummy/lib/path/to/lib/".to_string()
350+
} else {
351+
output(
352+
Command::new(&config.initial_rustc)
353+
.arg("--target")
354+
.arg(config.build)
355+
.arg("--print")
356+
.arg("target-libdir"),
357+
)
358+
};
359+
let initial_target_dir = Path::new(&initial_target_libdir_str).parent().unwrap();
360+
let initial_lld = initial_target_dir.join("bin").join("rust-lld");
361+
362+
let initial_sysroot = if config.dry_run {
363+
"/dummy".to_string()
364+
} else {
365+
output(Command::new(&config.initial_rustc).arg("--print").arg("sysroot"))
366+
};
367+
let initial_libdir = initial_target_dir
368+
.parent()
369+
.unwrap()
370+
.parent()
371+
.unwrap()
372+
.strip_prefix(initial_sysroot.trim())
373+
.unwrap()
374+
.to_path_buf();
354375

355376
let mut build = Build {
356377
initial_rustc: config.initial_rustc.clone(),
357378
initial_cargo: config.initial_cargo.clone(),
358379
initial_lld,
380+
initial_libdir,
359381
local_rebuild: config.local_rebuild,
360382
fail_fast: config.cmd.fail_fast(),
361383
doc_tests: config.cmd.doc_tests(),

src/libcore/str/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -2270,12 +2270,11 @@ impl str {
22702270
self.len() == 0
22712271
}
22722272

2273-
/// Checks that `index`-th byte lies at the start and/or end of a
2274-
/// UTF-8 code point sequence.
2273+
/// Checks that `index`-th byte is the first byte in a UTF-8 code point
2274+
/// sequence or the end of the string.
22752275
///
22762276
/// The start and end of the string (when `index == self.len()`) are
2277-
/// considered to be
2278-
/// boundaries.
2277+
/// considered to be boundaries.
22792278
///
22802279
/// Returns `false` if `index` is greater than `self.len()`.
22812280
///

src/libfmt_macros/lib.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ pub struct Parser<'a> {
191191
append_newline: bool,
192192
/// Whether this formatting string is a literal or it comes from a macro.
193193
is_literal: bool,
194+
/// Start position of the current line.
195+
cur_line_start: usize,
196+
/// Start and end byte offset of every line of the format string. Excludes
197+
/// newline characters and leading whitespace.
198+
pub line_spans: Vec<InnerSpan>,
194199
}
195200

196201
impl<'a> Iterator for Parser<'a> {
@@ -235,10 +240,15 @@ impl<'a> Iterator for Parser<'a> {
235240
None
236241
}
237242
}
238-
'\n' => Some(String(self.string(pos))),
239243
_ => Some(String(self.string(pos))),
240244
}
241245
} else {
246+
if self.is_literal && self.cur_line_start != self.input.len() {
247+
let start = self.to_span_index(self.cur_line_start);
248+
let end = self.to_span_index(self.input.len());
249+
self.line_spans.push(start.to(end));
250+
self.cur_line_start = self.input.len();
251+
}
242252
None
243253
}
244254
}
@@ -266,6 +276,8 @@ impl<'a> Parser<'a> {
266276
last_opening_brace: None,
267277
append_newline,
268278
is_literal,
279+
cur_line_start: 0,
280+
line_spans: vec![],
269281
}
270282
}
271283

@@ -433,7 +445,17 @@ impl<'a> Parser<'a> {
433445
'{' | '}' => {
434446
return &self.input[start..pos];
435447
}
448+
'\n' if self.is_literal => {
449+
let start = self.to_span_index(self.cur_line_start);
450+
let end = self.to_span_index(pos);
451+
self.line_spans.push(start.to(end));
452+
self.cur_line_start = pos + 1;
453+
self.cur.next();
454+
}
436455
_ => {
456+
if self.is_literal && pos == self.cur_line_start && c.is_whitespace() {
457+
self.cur_line_start = pos + c.len_utf8();
458+
}
437459
self.cur.next();
438460
}
439461
}

src/librustc_ast/ast.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ pub enum ExprKind {
12521252
Ret(Option<P<Expr>>),
12531253

12541254
/// Output of the `asm!()` macro.
1255-
InlineAsm(InlineAsm),
1255+
InlineAsm(P<InlineAsm>),
12561256
/// Output of the `llvm_asm!()` macro.
12571257
LlvmInlineAsm(P<LlvmInlineAsm>),
12581258

@@ -1971,6 +1971,7 @@ pub struct InlineAsm {
19711971
pub template: Vec<InlineAsmTemplatePiece>,
19721972
pub operands: Vec<(InlineAsmOperand, Span)>,
19731973
pub options: InlineAsmOptions,
1974+
pub line_spans: Vec<Span>,
19741975
}
19751976

19761977
/// Inline assembly dialect.

src/librustc_ast_lowering/expr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
12671267

12681268
let operands = self.arena.alloc_from_iter(operands);
12691269
let template = self.arena.alloc_from_iter(asm.template.iter().cloned());
1270-
let hir_asm = hir::InlineAsm { template, operands, options: asm.options };
1270+
let line_spans = self.arena.alloc_slice(&asm.line_spans[..]);
1271+
let hir_asm = hir::InlineAsm { template, operands, options: asm.options, line_spans };
12711272
hir::ExprKind::InlineAsm(self.arena.alloc(hir_asm))
12721273
}
12731274

src/librustc_builtin_macros/asm.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -513,10 +513,16 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
513513
}
514514
}
515515

516-
let inline_asm = ast::InlineAsm { template, operands, options: args.options };
516+
let line_spans = if parser.line_spans.is_empty() {
517+
vec![template_sp]
518+
} else {
519+
parser.line_spans.iter().map(|span| template_span.from_inner(*span)).collect()
520+
};
521+
522+
let inline_asm = ast::InlineAsm { template, operands, options: args.options, line_spans };
517523
P(ast::Expr {
518524
id: ast::DUMMY_NODE_ID,
519-
kind: ast::ExprKind::InlineAsm(inline_asm),
525+
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
520526
span: sp,
521527
attrs: ast::AttrVec::new(),
522528
tokens: None,

src/librustc_builtin_macros/env.rs

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pub fn expand_env<'cx>(
7777
return DummyResult::any(sp);
7878
}
7979

80+
let sp = cx.with_def_site_ctxt(sp);
8081
let e = match env::var(&*var.as_str()) {
8182
Err(_) => {
8283
cx.span_err(sp, &msg.as_str());

src/librustc_codegen_llvm/asm.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashMap;
1414
use rustc_hir as hir;
1515
use rustc_middle::span_bug;
1616
use rustc_middle::ty::layout::TyAndLayout;
17-
use rustc_span::Span;
17+
use rustc_span::{Pos, Span};
1818
use rustc_target::abi::*;
1919
use rustc_target::asm::*;
2020

@@ -97,7 +97,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
9797
ia.volatile,
9898
ia.alignstack,
9999
ia.dialect,
100-
span,
100+
&[span],
101101
);
102102
if r.is_none() {
103103
return false;
@@ -119,7 +119,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
119119
template: &[InlineAsmTemplatePiece],
120120
operands: &[InlineAsmOperandRef<'tcx, Self>],
121121
options: InlineAsmOptions,
122-
span: Span,
122+
line_spans: &[Span],
123123
) {
124124
let asm_arch = self.tcx.sess.asm_arch.unwrap();
125125

@@ -287,9 +287,9 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
287287
volatile,
288288
alignstack,
289289
dialect,
290-
span,
290+
line_spans,
291291
)
292-
.unwrap_or_else(|| span_bug!(span, "LLVM asm constraint validation failed"));
292+
.unwrap_or_else(|| span_bug!(line_spans[0], "LLVM asm constraint validation failed"));
293293

294294
if options.contains(InlineAsmOptions::PURE) {
295295
if options.contains(InlineAsmOptions::NOMEM) {
@@ -341,7 +341,7 @@ fn inline_asm_call(
341341
volatile: bool,
342342
alignstack: bool,
343343
dia: LlvmAsmDialect,
344-
span: Span,
344+
line_spans: &[Span],
345345
) -> Option<&'ll Value> {
346346
let volatile = if volatile { llvm::True } else { llvm::False };
347347
let alignstack = if alignstack { llvm::True } else { llvm::False };
@@ -382,8 +382,24 @@ fn inline_asm_call(
382382
key.len() as c_uint,
383383
);
384384

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

388404
Some(call)
389405
} else {

src/librustc_codegen_llvm/back/write.rs

+43-8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_middle::bug;
2323
use rustc_middle::ty::TyCtxt;
2424
use rustc_session::config::{self, Lto, OutputType, Passes, Sanitizer, SwitchWithOptPath};
2525
use rustc_session::Session;
26+
use rustc_span::InnerSpan;
2627
use rustc_target::spec::{CodeModel, RelocModel};
2728

2829
use libc::{c_char, c_int, c_uint, c_void, size_t};
@@ -238,12 +239,19 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
238239
}
239240
}
240241

241-
unsafe extern "C" fn report_inline_asm(
242+
fn report_inline_asm(
242243
cgcx: &CodegenContext<LlvmCodegenBackend>,
243-
msg: &str,
244-
cookie: c_uint,
244+
msg: String,
245+
mut cookie: c_uint,
246+
source: Option<(String, Vec<InnerSpan>)>,
245247
) {
246-
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
248+
// In LTO build we may get srcloc values from other crates which are invalid
249+
// since they use a different source map. To be safe we just suppress these
250+
// in LTO builds.
251+
if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
252+
cookie = 0;
253+
}
254+
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, source);
247255
}
248256

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

255-
let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
256-
.expect("non-UTF8 SMDiagnostic");
263+
// Recover the post-substitution assembly code from LLVM for better
264+
// diagnostics.
265+
let mut have_source = false;
266+
let mut buffer = String::new();
267+
let mut loc = 0;
268+
let mut ranges = [0; 8];
269+
let mut num_ranges = ranges.len() / 2;
270+
let msg = llvm::build_string(|msg| {
271+
buffer = llvm::build_string(|buffer| {
272+
have_source = llvm::LLVMRustUnpackSMDiagnostic(
273+
diag,
274+
msg,
275+
buffer,
276+
&mut loc,
277+
ranges.as_mut_ptr(),
278+
&mut num_ranges,
279+
);
280+
})
281+
.expect("non-UTF8 inline asm");
282+
})
283+
.expect("non-UTF8 SMDiagnostic");
284+
285+
let source = have_source.then(|| {
286+
let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
287+
for i in 0..num_ranges {
288+
spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
289+
}
290+
(buffer, spans)
291+
});
257292

258-
report_inline_asm(cgcx, &msg, cookie);
293+
report_inline_asm(cgcx, msg, cookie, source);
259294
}
260295

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

267302
match llvm::diagnostic::Diagnostic::unpack(info) {
268303
llvm::diagnostic::InlineAsm(inline) => {
269-
report_inline_asm(cgcx, &llvm::twine_to_string(inline.message), inline.cookie);
304+
report_inline_asm(cgcx, llvm::twine_to_string(inline.message), inline.cookie, None);
270305
}
271306

272307
llvm::diagnostic::Optimization(opt) => {

src/librustc_codegen_llvm/debuginfo/metadata.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -959,16 +959,16 @@ pub fn compile_unit_metadata(
959959
if tcx.sess.opts.debugging_opts.profile {
960960
let cu_desc_metadata =
961961
llvm::LLVMRustMetadataAsValue(debug_context.llcontext, unit_metadata);
962+
let default_gcda_path = &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda");
963+
let gcda_path =
964+
tcx.sess.opts.debugging_opts.profile_emit.as_ref().unwrap_or(default_gcda_path);
962965

963966
let gcov_cu_info = [
964967
path_to_mdstring(
965968
debug_context.llcontext,
966969
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcno"),
967970
),
968-
path_to_mdstring(
969-
debug_context.llcontext,
970-
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcda"),
971-
),
971+
path_to_mdstring(debug_context.llcontext, &gcda_path),
972972
cu_desc_metadata,
973973
];
974974
let gcov_metadata = llvm::LLVMMDNodeInContext(

src/librustc_codegen_llvm/llvm/ffi.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -2070,7 +2070,14 @@ extern "C" {
20702070
);
20712071

20722072
#[allow(improper_ctypes)]
2073-
pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString);
2073+
pub fn LLVMRustUnpackSMDiagnostic(
2074+
d: &SMDiagnostic,
2075+
message_out: &RustString,
2076+
buffer_out: &RustString,
2077+
loc_out: &mut c_uint,
2078+
ranges_out: *mut c_uint,
2079+
num_ranges: &mut usize,
2080+
) -> bool;
20742081

20752082
pub fn LLVMRustWriteArchive(
20762083
Dst: *const c_char,

0 commit comments

Comments
 (0)