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

PoC: implement core::panic::panic_error #1

Closed
wants to merge 1 commit into from

Conversation

yaahc
Copy link
Owner

@yaahc yaahc commented Jan 6, 2022

This is a proof of concept for integrating the new core::error::Error trait into the panic runtime. This will eventually evolve into a full proposal and possibly RFC, but for now it is quick and dirty just to test the core concepts and the shape of the API so I can share it with other project members and discuss the design prior to refinement.

PayloadKind::Any(payload) => payload.downcast_ref(),
#[cfg(not(bootstrap))]
PayloadKind::Error(_) => None,
// PayloadKind::Error(error) => error.downcast_ref(),
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda wanted to let this downcast for either but there isn't any reason to do so. I'd likely have to internally reimplement the downcast_ref logic to avoid needing to add T: Error.

#[inline]
#[cfg(not(bootstrap))]
pub fn error_constructor(
// message: Option<&'a fmt::Arguments<'a>>,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will likely need a message as well, so that unwrap and expect can provide their message when panicking as an error. My plan is to change the error() method on PanicInfo to be called source, and to treat the message like the outermost error in the chain of errors.

match self.payload {
PayloadKind::Any(payload) => payload,
#[cfg(not(bootstrap))]
PayloadKind::Error(_) => &HackerVoice, // I'm in
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will not apologize

@@ -196,6 +196,8 @@ fn default_hook(info: &PanicInfo<'_>) {
Some(s) => *s,
None => match info.payload().downcast_ref::<String>() {
Some(s) => &s[..],
#[cfg(not(bootstrap))]
None if info.error().is_some() => "non-recoverable runtime Error",
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once std::error::Report is merged this will be updated to actually report the source error when one exists, rather than requiring the user installs a custom hook that actually prints the error.

Comment on lines +564 to +578
let loc = info.location().unwrap(); // The current implementation always returns Some
if let Some(error) = info.error() {
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
rust_panic_error_with_hook(error, loc);
})
} else {
let msg = info.message().unwrap(); // The current implementation always returns Some
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
if let Some(msg) = msg.as_str() {
rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc);
} else {
rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
}
})
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is to help make the types for the msg more uniform so we can downcast to them more consistently, but I really do not like that this is creating a new PanicInfo when we already have one...

}
}

rust_panic(&mut ErrorPanicPayload)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally it should be possible to panic with no payload at all. My intuition is that propagating the error with an unwinding panic to be caught and potentially reacted to is an anti-pattern, since converting a dyn Error to a panic semantically represents promoting a recoverable error to a non-recoverable error. I'm interested in hearing real world usecases of propagating and handling payloads via panics and am open to the possibility that I'm making the wrong call here, but my expectation is that if you need to react to an error in a panic it should never have been a panic in the first place.

For now we make a dummy payload that shouldn't need to allocate and which only indicates that the current panic started as a dyn Error.

@yaahc yaahc mentioned this pull request Feb 9, 2022
4 tasks
yaahc pushed a commit that referenced this pull request May 17, 2022
author Preston From <[email protected]> 1645164142 -0600
committer Preston From <[email protected]> 1650005351 -0600
@yaahc yaahc closed this Jul 18, 2022
yaahc pushed a commit that referenced this pull request Jul 31, 2024
…res, r=oli-obk

Tell users not to file a bug when using internal library features

Actually fixes rust-lang#97501. I don't think we should suppress the suggestion to add `#![feature(..)]`, though I guess I could be convinced otherwise.

r? `@Nilstrieb` cc `@RalfJung`

Didn't add a test b/c I don't think we test this for lang features either, but I can confirm it does work.

```
warning: the feature `core_intrinsics` is internal to the compiler or standard library
 --> /home/michael/test.rs:1:12
  |
1 | #![feature(core_intrinsics)]
  |            ^^^^^^^^^^^^^^^
  |
  = note: using it is strongly discouraged
  = note: `#[warn(internal_features)]` on by default

thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:94:25:
broken MIR in Item(DefId(0:6 ~ test[42db]::{impl#0}::add)) (after phase change to runtime-optimized) at bb0[0]:
Cannot perform arithmetic Add on type WrapInt8
stack backtrace:
   0: begin_panic_handler
             at ./library/std/src/panicking.rs:665:5
   1: panic_fmt
             at ./library/core/src/panicking.rs:74:14
   2: fail<alloc::string::String>
             at ./compiler/rustc_mir_transform/src/validate.rs:146:9
   3: run_pass
             at ./compiler/rustc_mir_transform/src/validate.rs:94:13
   4: validate_body
             at ./compiler/rustc_mir_transform/src/pass_manager.rs:193:5
   5: run_passes_inner
             at ./compiler/rustc_mir_transform/src/pass_manager.rs:176:13
   6: rustc_mir_transform::pass_manager::run_passes
             at ./compiler/rustc_mir_transform/src/pass_manager.rs:87:5
   7: run_optimization_passes
             at ./compiler/rustc_mir_transform/src/lib.rs:561:5
   8: inner_optimized_mir
             at ./compiler/rustc_mir_transform/src/lib.rs:667:5
   9: optimized_mir
             at ./compiler/rustc_mir_transform/src/lib.rs:630:21
  10: {closure#0}
             at ./compiler/rustc_query_impl/src/plumbing.rs:285:13
      [... omitted 22 frames ...]
  11: query_get_at<rustc_query_system::query::caches::DefIdCache<rustc_middle::query::erase::Erased<[u8; 8]>>>
             at ./compiler/rustc_middle/src/query/plumbing.rs:145:17
  12: instance_mir
  13: collect_items_of_instance
             at ./compiler/rustc_monomorphize/src/collector.rs:1203:16
  14: {closure#0}
             at ./compiler/rustc_monomorphize/src/collector.rs:447:17
  15: maybe_grow<(), rustc_monomorphize::collector::collect_items_rec::{closure_env#0}>
             at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9
  16: ensure_sufficient_stack<(), rustc_monomorphize::collector::collect_items_rec::{closure_env#0}>
             at ./compiler/rustc_data_structures/src/stack.rs:17:5
  17: collect_items_rec
             at ./compiler/rustc_monomorphize/src/collector.rs:446:13
  18: collect_items_rec
             at ./compiler/rustc_monomorphize/src/collector.rs:526:13
  19: {closure#0}
             at ./compiler/rustc_monomorphize/src/collector.rs:1597:17
  20: {closure#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>
             at ./compiler/rustc_data_structures/src/sync/parallel.rs:182:34
  21: call_once<(), rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure#0}::{closure_env#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>
             at ./library/core/src/panic/unwind_safe.rs:272:9
  22: do_call<core::panic::unwind_safe::AssertUnwindSafe<rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure#0}::{closure_env#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>, ()>
             at ./library/std/src/panicking.rs:557:40
  23: try<(), core::panic::unwind_safe::AssertUnwindSafe<rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure#0}::{closure_env#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>>
             at ./library/std/src/panicking.rs:521:19
  24: run<(), rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure#1}::{closure_env#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>
             at ./compiler/rustc_data_structures/src/sync/parallel.rs:28:9
  25: {closure#1}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>
             at ./compiler/rustc_data_structures/src/sync/parallel.rs:186:21
  26: {closure#0}<rustc_middle::mir::mono::MonoItem, rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure_env#1}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>
             at ./library/core/src/iter/traits/iterator.rs:815:29
  27: fold<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global, (), core::iter::traits::iterator::Iterator::for_each::call::{closure_env#0}<rustc_middle::mir::mono::MonoItem, rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure_env#1}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>>
             at ./library/alloc/src/vec/into_iter.rs:317:25
  28: for_each<alloc::vec::into_iter::IntoIter<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure_env#1}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>
             at ./library/core/src/iter/traits/iterator.rs:818:9
  29: {closure#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>
             at ./compiler/rustc_data_structures/src/sync/parallel.rs:185:17
  30: parallel_guard<(), rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure_env#0}<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>>
             at ./compiler/rustc_data_structures/src/sync/parallel.rs:44:15
  31: par_for_each_in<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem, alloc::alloc::Global>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure_env#0}>
             at ./compiler/rustc_data_structures/src/sync/parallel.rs:178:9
  32: {closure#1}
             at ./compiler/rustc_monomorphize/src/collector.rs:1595:13
  33: run<(), rustc_monomorphize::collector::collect_crate_mono_items::{closure_env#1}>
             at ./compiler/rustc_data_structures/src/profiling.rs:754:9
  34: time<(), rustc_monomorphize::collector::collect_crate_mono_items::{closure_env#1}>
             at ./compiler/rustc_session/src/utils.rs:16:9
  35: collect_crate_mono_items
             at ./compiler/rustc_monomorphize/src/collector.rs:1594:9
  36: collect_and_partition_mono_items
             at ./compiler/rustc_monomorphize/src/partitioning.rs:1124:30
  37: {closure#0}
             at ./compiler/rustc_query_impl/src/plumbing.rs:281:9
      [... omitted 22 frames ...]
  38: query_get_at<rustc_query_system::query::caches::SingleCache<rustc_middle::query::erase::Erased<[u8; 24]>>>
             at ./compiler/rustc_middle/src/query/plumbing.rs:145:17
  39: collect_and_partition_mono_items
             at ./compiler/rustc_middle/src/query/plumbing.rs:423:31
  40: collect_and_partition_mono_items
             at ./compiler/rustc_middle/src/query/plumbing.rs:414:17
  41: codegen_crate<rustc_codegen_llvm::LlvmCodegenBackend>
             at ./compiler/rustc_codegen_ssa/src/base.rs:596:25
  42: codegen_crate
             at ./compiler/rustc_codegen_llvm/src/lib.rs:361:18
  43: {closure#0}
             at ./compiler/rustc_interface/src/passes.rs:1027:9
  44: run<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
             at ./compiler/rustc_data_structures/src/profiling.rs:754:9
  45: time<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
             at ./compiler/rustc_session/src/utils.rs:16:9
  46: start_codegen
             at ./compiler/rustc_interface/src/passes.rs:1026:19
  47: codegen_and_build_linker
             at ./compiler/rustc_interface/src/queries.rs:128:31
  48: {closure#6}
             at ./compiler/rustc_driver_impl/src/lib.rs:451:25
  49: {closure#1}<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure_env#6}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_middle/src/ty/context.rs:1336:37
  50: {closure#0}<rustc_middle::ty::context::{impl#19}::enter::{closure_env#1}<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure_env#6}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_middle/src/ty/context/tls.rs:82:9
  51: try_with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#19}::enter::{closure_env#1}<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure_env#6}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./library/std/src/thread/local.rs:283:12
  52: with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#19}::enter::{closure_env#1}<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure_env#6}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./library/std/src/thread/local.rs:260:9
  53: enter_context<rustc_middle::ty::context::{impl#19}::enter::{closure_env#1}<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure_env#6}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_middle/src/ty/context/tls.rs:79:5
  54: enter<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure_env#6}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_middle/src/ty/context.rs:1336:9
  55: <rustc_interface::queries::QueryResult<&rustc_middle::ty::context::GlobalCtxt>>::enter::<core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure#6}>
             at ./compiler/rustc_interface/src/queries.rs:64:9
  56: {closure#1}
             at ./compiler/rustc_driver_impl/src/lib.rs:450:13
  57: enter<rustc_driver_impl::run_compiler::{closure#0}::{closure_env#1}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_interface/src/queries.rs:209:19
  58: {closure#0}
             at ./compiler/rustc_driver_impl/src/lib.rs:388:22
  59: {closure#1}<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure_env#0}>
             at ./compiler/rustc_interface/src/interface.rs:502:27
  60: {closure#0}<rustc_interface::interface::run_compiler::{closure_env#1}<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_interface/src/util.rs:154:13
  61: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_interface/src/util.rs:106:21
  62: set<rustc_span::SessionGlobals, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>
             at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  63: create_session_globals_then<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>>
             at ./compiler/rustc_span/src/lib.rs:134:5
  64: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>
             at ./compiler/rustc_interface/src/util.rs:105:17
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: the compiler unexpectedly panicked. this is a bug.

note: using internal features is not supported and expected to cause internal compiler errors when used incorrectly

note: rustc 1.82.0-dev running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [optimized_mir] optimizing MIR for `<impl at /home/michael/test.rs:9:1: 9:32>::add`
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant