Skip to content

Commit 905d5a3

Browse files
committed
Auto merge of rust-lang#111287 - matthiaskrgr:rollup-9lzax2c, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#110577 (Use fulfillment to check `Drop` impl compatibility) - rust-lang#110610 (Add Terminator conversion from MIR to SMIR, part #1) - rust-lang#110985 (Fix spans in LLVM-generated inline asm errors) - rust-lang#110989 (Make the BUG_REPORT_URL configurable by tools ) - rust-lang#111167 (debuginfo: split method declaration and definition) - rust-lang#111230 (add hint for =< as <=) - rust-lang#111279 (More robust debug assertions for `Instance::resolve` on built-in traits with non-standard trait items) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 333b920 + 3cb1a46 commit 905d5a3

File tree

42 files changed

+1067
-413
lines changed

Some content is hidden

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

42 files changed

+1067
-413
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4093,6 +4093,7 @@ dependencies = [
40934093
name = "rustc_smir"
40944094
version = "0.0.0"
40954095
dependencies = [
4096+
"rustc_hir",
40964097
"rustc_middle",
40974098
"rustc_span",
40984099
"tracing",

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+51-34
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
322322
let tcx = self.tcx;
323323

324324
let def_id = instance.def_id();
325-
let containing_scope = get_containing_scope(self, instance);
325+
let (containing_scope, is_method) = get_containing_scope(self, instance);
326326
let span = tcx.def_span(def_id);
327327
let loc = self.lookup_debug_loc(span.lo());
328328
let file_metadata = file_metadata(self, &loc.file);
@@ -378,8 +378,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
378378
}
379379
}
380380

381-
unsafe {
382-
return llvm::LLVMRustDIBuilderCreateFunction(
381+
// When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because
382+
// LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
383+
// When we use this `decl` below, the subprogram definition gets created at the CU level
384+
// with a DW_AT_specification pointing back to the type's declaration.
385+
let decl = is_method.then(|| unsafe {
386+
llvm::LLVMRustDIBuilderCreateMethod(
387+
DIB(self),
388+
containing_scope,
389+
name.as_ptr().cast(),
390+
name.len(),
391+
linkage_name.as_ptr().cast(),
392+
linkage_name.len(),
393+
file_metadata,
394+
loc.line,
395+
function_type_metadata,
396+
flags,
397+
spflags & !DISPFlags::SPFlagDefinition,
398+
template_parameters,
399+
)
400+
});
401+
402+
return unsafe {
403+
llvm::LLVMRustDIBuilderCreateFunction(
383404
DIB(self),
384405
containing_scope,
385406
name.as_ptr().cast(),
@@ -394,9 +415,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
394415
spflags,
395416
maybe_definition_llfn,
396417
template_parameters,
397-
None,
398-
);
399-
}
418+
decl,
419+
)
420+
};
400421

401422
fn get_function_signature<'ll, 'tcx>(
402423
cx: &CodegenCx<'ll, 'tcx>,
@@ -493,14 +514,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
493514
names
494515
}
495516

517+
/// Returns a scope, plus `true` if that's a type scope for "class" methods,
518+
/// otherwise `false` for plain namespace scopes.
496519
fn get_containing_scope<'ll, 'tcx>(
497520
cx: &CodegenCx<'ll, 'tcx>,
498521
instance: Instance<'tcx>,
499-
) -> &'ll DIScope {
522+
) -> (&'ll DIScope, bool) {
500523
// First, let's see if this is a method within an inherent impl. Because
501524
// if yes, we want to make the result subroutine DIE a child of the
502525
// subroutine's self-type.
503-
let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| {
526+
if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
504527
// If the method does *not* belong to a trait, proceed
505528
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
506529
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
@@ -511,39 +534,33 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
511534

512535
// Only "class" methods are generally understood by LLVM,
513536
// so avoid methods on other types (e.g., `<*mut T>::null`).
514-
match impl_self_ty.kind() {
515-
ty::Adt(def, ..) if !def.is_box() => {
516-
// Again, only create type information if full debuginfo is enabled
517-
if cx.sess().opts.debuginfo == DebugInfo::Full
518-
&& !impl_self_ty.has_param()
519-
{
520-
Some(type_di_node(cx, impl_self_ty))
521-
} else {
522-
Some(namespace::item_namespace(cx, def.did()))
523-
}
537+
if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() {
538+
// Again, only create type information if full debuginfo is enabled
539+
if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param()
540+
{
541+
return (type_di_node(cx, impl_self_ty), true);
542+
} else {
543+
return (namespace::item_namespace(cx, def.did()), false);
524544
}
525-
_ => None,
526545
}
527546
} else {
528547
// For trait method impls we still use the "parallel namespace"
529548
// strategy
530-
None
531549
}
532-
});
550+
}
533551

534-
self_type.unwrap_or_else(|| {
535-
namespace::item_namespace(
536-
cx,
537-
DefId {
538-
krate: instance.def_id().krate,
539-
index: cx
540-
.tcx
541-
.def_key(instance.def_id())
542-
.parent
543-
.expect("get_containing_scope: missing parent?"),
544-
},
545-
)
546-
})
552+
let scope = namespace::item_namespace(
553+
cx,
554+
DefId {
555+
krate: instance.def_id().krate,
556+
index: cx
557+
.tcx
558+
.def_key(instance.def_id())
559+
.parent
560+
.expect("get_containing_scope: missing parent?"),
561+
},
562+
);
563+
(scope, false)
547564
}
548565
}
549566

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1987,6 +1987,21 @@ extern "C" {
19871987
Decl: Option<&'a DIDescriptor>,
19881988
) -> &'a DISubprogram;
19891989

1990+
pub fn LLVMRustDIBuilderCreateMethod<'a>(
1991+
Builder: &DIBuilder<'a>,
1992+
Scope: &'a DIDescriptor,
1993+
Name: *const c_char,
1994+
NameLen: size_t,
1995+
LinkageName: *const c_char,
1996+
LinkageNameLen: size_t,
1997+
File: &'a DIFile,
1998+
LineNo: c_uint,
1999+
Ty: &'a DIType,
2000+
Flags: DIFlags,
2001+
SPFlags: DISPFlags,
2002+
TParam: &'a DIArray,
2003+
) -> &'a DISubprogram;
2004+
19902005
pub fn LLVMRustDIBuilderCreateBasicType<'a>(
19912006
Builder: &DIBuilder<'a>,
19922007
Name: *const c_char,

compiler/rustc_codegen_ssa/src/back/write.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1821,9 +1821,15 @@ impl SharedEmitterMain {
18211821
let source = sess
18221822
.source_map()
18231823
.new_source_file(FileName::inline_asm_source_code(&buffer), buffer);
1824-
let source_span = Span::with_root_ctxt(source.start_pos, source.end_pos);
1825-
let spans: Vec<_> =
1826-
spans.iter().map(|sp| source_span.from_inner(*sp)).collect();
1824+
let spans: Vec<_> = spans
1825+
.iter()
1826+
.map(|sp| {
1827+
Span::with_root_ctxt(
1828+
source.normalized_byte_pos(sp.start as u32),
1829+
source.normalized_byte_pos(sp.end as u32),
1830+
)
1831+
})
1832+
.collect();
18271833
err.span_note(spans, "instantiated into assembly here");
18281834
}
18291835

compiler/rustc_driver_impl/src/lib.rs

+57-46
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_data_structures::profiling::{
2525
use rustc_data_structures::sync::SeqCst;
2626
use rustc_errors::registry::{InvalidErrorCode, Registry};
2727
use rustc_errors::{
28-
DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl,
28+
DiagnosticMessage, ErrorGuaranteed, Handler, PResult, SubdiagnosticMessage, TerminalUrl,
2929
};
3030
use rustc_feature::find_gated_cfg;
3131
use rustc_fluent_macro::fluent_messages;
@@ -55,7 +55,7 @@ use std::panic::{self, catch_unwind};
5555
use std::path::PathBuf;
5656
use std::process::{self, Command, Stdio};
5757
use std::str;
58-
use std::sync::LazyLock;
58+
use std::sync::OnceLock;
5959
use std::time::Instant;
6060

6161
// This import blocks the use of panicking `print` and `println` in all the code
@@ -119,7 +119,7 @@ pub const EXIT_SUCCESS: i32 = 0;
119119
/// Exit status code used for compilation failures and invalid flags.
120120
pub const EXIT_FAILURE: i32 = 1;
121121

122-
const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\
122+
pub const DEFAULT_BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\
123123
?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md";
124124

125125
const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
@@ -1196,43 +1196,66 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
11961196
}
11971197
}
11981198

1199-
static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
1200-
LazyLock::new(|| {
1201-
let hook = panic::take_hook();
1202-
panic::set_hook(Box::new(|info| {
1203-
// If the error was caused by a broken pipe then this is not a bug.
1204-
// Write the error and return immediately. See #98700.
1205-
#[cfg(windows)]
1206-
if let Some(msg) = info.payload().downcast_ref::<String>() {
1207-
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)")
1208-
{
1209-
early_error_no_abort(ErrorOutputType::default(), &msg);
1210-
return;
1211-
}
1212-
};
1199+
/// Stores the default panic hook, from before [`install_ice_hook`] was called.
1200+
static DEFAULT_HOOK: OnceLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
1201+
OnceLock::new();
1202+
1203+
/// Installs a panic hook that will print the ICE message on unexpected panics.
1204+
///
1205+
/// The hook is intended to be useable even by external tools. You can pass a custom
1206+
/// `bug_report_url`, or report arbitrary info in `extra_info`. Note that `extra_info` is called in
1207+
/// a context where *the thread is currently panicking*, so it must not panic or the process will
1208+
/// abort.
1209+
///
1210+
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
1211+
/// extra_info.
1212+
///
1213+
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
1214+
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) {
1215+
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
1216+
// full backtraces. When a compiler ICE happens, we want to gather
1217+
// as much information as possible to present in the issue opened
1218+
// by the user. Compiler developers and other rustc users can
1219+
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
1220+
// (e.g. `RUST_BACKTRACE=1`)
1221+
if std::env::var("RUST_BACKTRACE").is_err() {
1222+
std::env::set_var("RUST_BACKTRACE", "full");
1223+
}
12131224

1214-
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
1215-
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
1216-
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
1217-
(*DEFAULT_HOOK)(info);
1225+
let default_hook = DEFAULT_HOOK.get_or_init(panic::take_hook);
12181226

1219-
// Separate the output with an empty line
1220-
eprintln!();
1227+
panic::set_hook(Box::new(move |info| {
1228+
// If the error was caused by a broken pipe then this is not a bug.
1229+
// Write the error and return immediately. See #98700.
1230+
#[cfg(windows)]
1231+
if let Some(msg) = info.payload().downcast_ref::<String>() {
1232+
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") {
1233+
early_error_no_abort(ErrorOutputType::default(), &msg);
1234+
return;
12211235
}
1236+
};
12221237

1223-
// Print the ICE message
1224-
report_ice(info, BUG_REPORT_URL);
1225-
}));
1226-
hook
1227-
});
1238+
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
1239+
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
1240+
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
1241+
(*default_hook)(info);
1242+
1243+
// Separate the output with an empty line
1244+
eprintln!();
1245+
}
1246+
1247+
// Print the ICE message
1248+
report_ice(info, bug_report_url, extra_info);
1249+
}));
1250+
}
12281251

12291252
/// Prints the ICE message, including query stack, but without backtrace.
12301253
///
12311254
/// The message will point the user at `bug_report_url` to report the ICE.
12321255
///
12331256
/// When `install_ice_hook` is called, this function will be called as the panic
12341257
/// hook.
1235-
pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
1258+
pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) {
12361259
let fallback_bundle =
12371260
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
12381261
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
@@ -1277,29 +1300,17 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
12771300

12781301
interface::try_print_query_stack(&handler, num_frames);
12791302

1303+
// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
1304+
// printed all the relevant info.
1305+
extra_info(&handler);
1306+
12801307
#[cfg(windows)]
12811308
if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
12821309
// Trigger a debugger if we crashed during bootstrap
12831310
unsafe { windows::Win32::System::Diagnostics::Debug::DebugBreak() };
12841311
}
12851312
}
12861313

1287-
/// Installs a panic hook that will print the ICE message on unexpected panics.
1288-
///
1289-
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
1290-
pub fn install_ice_hook() {
1291-
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
1292-
// full backtraces. When a compiler ICE happens, we want to gather
1293-
// as much information as possible to present in the issue opened
1294-
// by the user. Compiler developers and other rustc users can
1295-
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
1296-
// (e.g. `RUST_BACKTRACE=1`)
1297-
if std::env::var("RUST_BACKTRACE").is_err() {
1298-
std::env::set_var("RUST_BACKTRACE", "full");
1299-
}
1300-
LazyLock::force(&DEFAULT_HOOK);
1301-
}
1302-
13031314
/// This allows tools to enable rust logging without having to magically match rustc's
13041315
/// tracing crate version.
13051316
pub fn init_rustc_env_logger() {
@@ -1370,7 +1381,7 @@ pub fn main() -> ! {
13701381
init_rustc_env_logger();
13711382
signal_handler::install();
13721383
let mut callbacks = TimePassesCallbacks::default();
1373-
install_ice_hook();
1384+
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
13741385
let exit_code = catch_with_exit_code(|| {
13751386
let args = env::args_os()
13761387
.enumerate()

0 commit comments

Comments
 (0)