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 #111287

Merged
merged 19 commits into from
May 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f0be145
drive-by cleanup of rustdoc comment
jyn514 Apr 29, 2023
2469afe
Make the BUG_REPORT_URL configurable by tools
jyn514 Apr 29, 2023
7dd59fc
Add Drop terminator to SMIR
spastorino Apr 20, 2023
10b69dd
debuginfo: split method declaration and definition
cuviper May 3, 2023
964fb67
Use fulfillment to check Drop impl compatibility
compiler-errors Apr 20, 2023
9d44f9b
Add test for #110557
compiler-errors Apr 20, 2023
2e346b6
Even more tests
compiler-errors Apr 21, 2023
4b85bea
Add Assert terminator to SMIR
spastorino Apr 24, 2023
698acc6
Add GeneratorDrop terminator to SMIR
spastorino Apr 24, 2023
a183ac6
add hint for =< as <=
zacklukem May 5, 2023
2a1ef34
More robust debug assertions for `Instance::resolve` on built-in trai…
compiler-errors May 6, 2023
bba2a1e
Fix spans in LLVM-generated inline asm errors
Amanieu Apr 29, 2023
bcc9aa0
Rollup merge of #110577 - compiler-errors:drop-impl-fulfill, r=lcnr
matthiaskrgr May 6, 2023
77004ea
Rollup merge of #110610 - spastorino:smir-terminator, r=oli-obk
matthiaskrgr May 6, 2023
8172ada
Rollup merge of #110985 - Amanieu:normalize_asm_spans, r=b-naber
matthiaskrgr May 6, 2023
8ec84dd
Rollup merge of #110989 - jyn514:bug-report-url, r=WaffleLapkin
matthiaskrgr May 6, 2023
f440999
Rollup merge of #111167 - cuviper:type-decl-disubprogram, r=michaelwo…
matthiaskrgr May 6, 2023
83b29ec
Rollup merge of #111230 - zacklukem:eq-less-to-less-eq, r=compiler-er…
matthiaskrgr May 6, 2023
3cb1a46
Rollup merge of #111279 - compiler-errors:core-item-resolve, r=cjgillot
matthiaskrgr May 6, 2023
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4093,6 +4093,7 @@ dependencies = [
name = "rustc_smir"
version = "0.0.0"
dependencies = [
"rustc_hir",
"rustc_middle",
"rustc_span",
"tracing",
Expand Down
85 changes: 51 additions & 34 deletions compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let tcx = self.tcx;

let def_id = instance.def_id();
let containing_scope = get_containing_scope(self, instance);
let (containing_scope, is_method) = get_containing_scope(self, instance);
let span = tcx.def_span(def_id);
let loc = self.lookup_debug_loc(span.lo());
let file_metadata = file_metadata(self, &loc.file);
Expand Down Expand Up @@ -378,8 +378,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}

unsafe {
return llvm::LLVMRustDIBuilderCreateFunction(
// When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because
// LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
// When we use this `decl` below, the subprogram definition gets created at the CU level
// with a DW_AT_specification pointing back to the type's declaration.
let decl = is_method.then(|| unsafe {
llvm::LLVMRustDIBuilderCreateMethod(
DIB(self),
containing_scope,
name.as_ptr().cast(),
name.len(),
linkage_name.as_ptr().cast(),
linkage_name.len(),
file_metadata,
loc.line,
function_type_metadata,
flags,
spflags & !DISPFlags::SPFlagDefinition,
template_parameters,
)
});

return unsafe {
llvm::LLVMRustDIBuilderCreateFunction(
DIB(self),
containing_scope,
name.as_ptr().cast(),
Expand All @@ -394,9 +415,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
spflags,
maybe_definition_llfn,
template_parameters,
None,
);
}
decl,
)
};

fn get_function_signature<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
Expand Down Expand Up @@ -493,14 +514,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
names
}

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

// Only "class" methods are generally understood by LLVM,
// so avoid methods on other types (e.g., `<*mut T>::null`).
match impl_self_ty.kind() {
ty::Adt(def, ..) if !def.is_box() => {
// Again, only create type information if full debuginfo is enabled
if cx.sess().opts.debuginfo == DebugInfo::Full
&& !impl_self_ty.has_param()
{
Some(type_di_node(cx, impl_self_ty))
} else {
Some(namespace::item_namespace(cx, def.did()))
}
if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() {
// Again, only create type information if full debuginfo is enabled
if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param()
{
return (type_di_node(cx, impl_self_ty), true);
} else {
return (namespace::item_namespace(cx, def.did()), false);
}
_ => None,
}
} else {
// For trait method impls we still use the "parallel namespace"
// strategy
None
}
});
}

self_type.unwrap_or_else(|| {
namespace::item_namespace(
cx,
DefId {
krate: instance.def_id().krate,
index: cx
.tcx
.def_key(instance.def_id())
.parent
.expect("get_containing_scope: missing parent?"),
},
)
})
let scope = namespace::item_namespace(
cx,
DefId {
krate: instance.def_id().krate,
index: cx
.tcx
.def_key(instance.def_id())
.parent
.expect("get_containing_scope: missing parent?"),
},
);
(scope, false)
}
}

Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,21 @@ extern "C" {
Decl: Option<&'a DIDescriptor>,
) -> &'a DISubprogram;

pub fn LLVMRustDIBuilderCreateMethod<'a>(
Builder: &DIBuilder<'a>,
Scope: &'a DIDescriptor,
Name: *const c_char,
NameLen: size_t,
LinkageName: *const c_char,
LinkageNameLen: size_t,
File: &'a DIFile,
LineNo: c_uint,
Ty: &'a DIType,
Flags: DIFlags,
SPFlags: DISPFlags,
TParam: &'a DIArray,
) -> &'a DISubprogram;

pub fn LLVMRustDIBuilderCreateBasicType<'a>(
Builder: &DIBuilder<'a>,
Name: *const c_char,
Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1821,9 +1821,15 @@ impl SharedEmitterMain {
let source = sess
.source_map()
.new_source_file(FileName::inline_asm_source_code(&buffer), buffer);
let source_span = Span::with_root_ctxt(source.start_pos, source.end_pos);
let spans: Vec<_> =
spans.iter().map(|sp| source_span.from_inner(*sp)).collect();
let spans: Vec<_> = spans
.iter()
.map(|sp| {
Span::with_root_ctxt(
source.normalized_byte_pos(sp.start as u32),
source.normalized_byte_pos(sp.end as u32),
)
})
.collect();
err.span_note(spans, "instantiated into assembly here");
}

Expand Down
103 changes: 57 additions & 46 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_data_structures::profiling::{
use rustc_data_structures::sync::SeqCst;
use rustc_errors::registry::{InvalidErrorCode, Registry};
use rustc_errors::{
DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl,
DiagnosticMessage, ErrorGuaranteed, Handler, PResult, SubdiagnosticMessage, TerminalUrl,
};
use rustc_feature::find_gated_cfg;
use rustc_fluent_macro::fluent_messages;
Expand Down Expand Up @@ -55,7 +55,7 @@ use std::panic::{self, catch_unwind};
use std::path::PathBuf;
use std::process::{self, Command, Stdio};
use std::str;
use std::sync::LazyLock;
use std::sync::OnceLock;
use std::time::Instant;

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

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

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

static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
LazyLock::new(|| {
let hook = panic::take_hook();
panic::set_hook(Box::new(|info| {
// If the error was caused by a broken pipe then this is not a bug.
// Write the error and return immediately. See #98700.
#[cfg(windows)]
if let Some(msg) = info.payload().downcast_ref::<String>() {
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)")
{
early_error_no_abort(ErrorOutputType::default(), &msg);
return;
}
};
/// Stores the default panic hook, from before [`install_ice_hook`] was called.
static DEFAULT_HOOK: OnceLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
OnceLock::new();

/// Installs a panic hook that will print the ICE message on unexpected panics.
///
/// The hook is intended to be useable even by external tools. You can pass a custom
/// `bug_report_url`, or report arbitrary info in `extra_info`. Note that `extra_info` is called in
/// a context where *the thread is currently panicking*, so it must not panic or the process will
/// abort.
///
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
/// extra_info.
///
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) {
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
// full backtraces. When a compiler ICE happens, we want to gather
// as much information as possible to present in the issue opened
// by the user. Compiler developers and other rustc users can
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
// (e.g. `RUST_BACKTRACE=1`)
if std::env::var("RUST_BACKTRACE").is_err() {
std::env::set_var("RUST_BACKTRACE", "full");
}

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

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

// Print the ICE message
report_ice(info, BUG_REPORT_URL);
}));
hook
});
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
(*default_hook)(info);

// Separate the output with an empty line
eprintln!();
}

// Print the ICE message
report_ice(info, bug_report_url, extra_info);
}));
}

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

interface::try_print_query_stack(&handler, num_frames);

// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
// printed all the relevant info.
extra_info(&handler);

#[cfg(windows)]
if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
// Trigger a debugger if we crashed during bootstrap
unsafe { windows::Win32::System::Diagnostics::Debug::DebugBreak() };
}
}

/// Installs a panic hook that will print the ICE message on unexpected panics.
///
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
pub fn install_ice_hook() {
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
// full backtraces. When a compiler ICE happens, we want to gather
// as much information as possible to present in the issue opened
// by the user. Compiler developers and other rustc users can
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
// (e.g. `RUST_BACKTRACE=1`)
if std::env::var("RUST_BACKTRACE").is_err() {
std::env::set_var("RUST_BACKTRACE", "full");
}
LazyLock::force(&DEFAULT_HOOK);
}

/// This allows tools to enable rust logging without having to magically match rustc's
/// tracing crate version.
pub fn init_rustc_env_logger() {
Expand Down Expand Up @@ -1370,7 +1381,7 @@ pub fn main() -> ! {
init_rustc_env_logger();
signal_handler::install();
let mut callbacks = TimePassesCallbacks::default();
install_ice_hook();
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
let exit_code = catch_with_exit_code(|| {
let args = env::args_os()
.enumerate()
Expand Down
Loading