Skip to content

Rename begin_panic to panic_with_payload #144902

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ Compatibility Notes
```
thread 'main' panicked at 'hello world', map-panic.rs:2:50
stack backtrace:
0: std::panicking::begin_panic
0: std::panicking::panic_with_payload
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:616:12
1: map_panic::main::{{closure}}
at ./map-panic.rs:2:50
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,11 +827,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

// At this point, we are calling a function, `callee`, whose `DefId` is known...

// `begin_panic` and `#[rustc_const_panic_str]` functions accept generic
// `panic_with_payload` and `#[rustc_const_panic_str]` functions accept generic
// types other than str. Check to enforce that only str can be used in
// const-eval.

// const-eval of the `begin_panic` fn assumes the argument is `&str`
// const-eval of the `panic_with_payload` fn assumes the argument is `&str`
if tcx.is_lang_item(callee, LangItem::BeginPanic) {
Copy link
Member

Choose a reason for hiding this comment

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

I think the lang item should be renamed too to match the new function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

does it needs FCP?

Copy link
Member

Choose a reason for hiding this comment

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

No, that is not necessary. Lang items are purely internal implementation details. They change all the time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Could you take a look and resolve it if so

match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
ty::Ref(_, ty, _) if ty.is_str() => {}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ language_item_table! {
PanicAsyncGenFnResumedDrop, sym::panic_const_async_gen_fn_resumed_drop, panic_const_async_gen_fn_resumed_drop, Target::Fn, GenericRequirement::None;
PanicGenFnNoneDrop, sym::panic_const_gen_fn_none_drop, panic_const_gen_fn_none_drop, Target::Fn, GenericRequirement::None;
/// libstd panic entry point. Necessary for const eval to be able to catch it
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
BeginPanic, sym::panic_with_payload, begin_panic_fn, Target::Fn, GenericRequirement::None;

// Lang items needed for `format_args!()`.
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,6 @@ symbols! {
avx512f,
await_macro,
bang,
begin_panic,
bench,
bevy_ecs,
bikeshed_guaranteed_no_drop,
Expand Down Expand Up @@ -1593,6 +1592,7 @@ symbols! {
panic_runtime,
panic_str_2015,
panic_unwind,
panic_with_payload,
panicking,
param_attrs,
parent_label,
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,10 @@ impl fmt::Display for PanicHookInfo<'_> {
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2015 {
() => ({
$crate::rt::begin_panic("explicit panic")
$crate::rt::panic_with_payload("explicit panic")
}),
($msg:expr $(,)?) => ({
$crate::rt::begin_panic($msg);
$crate::rt::panic_with_payload($msg);
}),
// Special-case the single-argument case for const_panic.
("{}", $arg:expr $(,)?) => ({
Expand Down Expand Up @@ -257,7 +257,7 @@ pub use crate::panicking::{set_hook, take_hook};
#[track_caller]
#[cfg_attr(not(test), rustc_diagnostic_item = "panic_any")]
pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
crate::panicking::begin_panic(msg);
crate::panicking::panic_with_payload(msg);
}

#[stable(feature = "catch_unwind", since = "1.9.0")]
Expand Down
10 changes: 5 additions & 5 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{fmt, intrinsics, process, thread};

// This forces codegen of the function called by panic!() inside the std crate, rather than in
// downstream crates. Primarily this is useful for rustc's codegen tests, which rely on noticing
// complete removal of panic from generated IR. Since begin_panic is inline(never), it's only
// complete removal of panic from generated IR. Since panic_with_payload is inline(never), it's only
// codegen'd once per crate-graph so this pushes that to std rather than our codegen test crates.
//
// (See https://github.com/rust-lang/rust/pull/123244 for more info on why).
Expand All @@ -41,7 +41,7 @@ use crate::{fmt, intrinsics, process, thread};
#[allow(dead_code)]
#[used(compiler)]
pub static EMPTY_PANIC: fn(&'static str) -> ! =
begin_panic::<&'static str> as fn(&'static str) -> !;
panic_with_payload::<&'static str> as fn(&'static str) -> !;

// Binary interface to the panic runtime that the standard library depends on.
//
Expand Down Expand Up @@ -650,7 +650,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
fn take_box(&mut self) -> *mut (dyn Any + Send) {
// We do two allocations here, unfortunately. But (a) they're required with the current
// scheme, and (b) we don't handle panic + OOM properly anyway (see comment in
// begin_panic below).
// panic_with_payload below).
let contents = mem::take(self.fill());
Box::into_raw(Box::new(contents))
}
Expand Down Expand Up @@ -717,15 +717,15 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
/// panic!() and assert!(). In particular, this is the only entry point that supports
/// arbitrary payloads, not just format strings.
#[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")]
#[cfg_attr(not(any(test, doctest)), lang = "begin_panic")]
#[cfg_attr(not(any(test, doctest)), lang = "panic_with_payload")]
// lang item for CTFE panic support
// never inline unless panic_immediate_abort to avoid code
// bloat at the call sites as much as possible
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
#[cfg_attr(feature = "panic_immediate_abort", inline)]
#[track_caller]
#[rustc_do_not_const_check] // hooked by const-eval
pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
pub const fn panic_with_payload<M: Any + Send>(msg: M) -> ! {
if cfg!(feature = "panic_immediate_abort") {
intrinsics::abort()
}
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#![allow(unused_macros)]

#[rustfmt::skip]
pub use crate::panicking::{begin_panic, panic_count};
pub use crate::panicking::{panic_with_payload, panic_count};
pub use core::panicking::{panic_display, panic_fmt};

#[rustfmt::skip]
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/compiler-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ stack backtrace:
2: std::panicking::default_hook::{{closure}}
3: std::panicking::default_hook
4: std::panicking::rust_panic_with_hook
5: std::panicking::begin_panic
5: std::panicking::panic_with_payload
(~~~~ LINES REMOVED BY ME FOR BREVITY ~~~~)
32: rustc_typeck::check_crate
33: <std::thread::local::LocalKey<T>>::with
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Sp
{
let impl_item_def_id = impl_item.def_id.expect_local();

// check the body for `begin_panic` or `unwrap`
// check the body for `panic_with_payload` or `unwrap`
let body = cx.tcx.hir_body_owned_by(impl_item_def_id);
let mut fpu = FindPanicUnwrap {
lcx: cx,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/rust-analyzer/bench_data/numerous_macro_rules
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ macro_rules! __ra_macro_fixture437 {($t : ty , $pmap : expr , $smap : expr )=
macro_rules! __ra_macro_fixture438 {()=>{# [ inline ] fn is_ascii (& self )-> bool { self . is_ascii ()}# [ inline ] fn to_ascii_uppercase (& self )-> Self :: Owned { self . to_ascii_uppercase ()}# [ inline ] fn to_ascii_lowercase (& self )-> Self :: Owned { self . to_ascii_lowercase ()}# [ inline ] fn eq_ignore_ascii_case (& self , o : & Self )-> bool { self . eq_ignore_ascii_case ( o )}# [ inline ] fn make_ascii_uppercase (& mut self ){ self . make_ascii_uppercase (); }# [ inline ] fn make_ascii_lowercase (& mut self ){ self . make_ascii_lowercase (); }}; }
macro_rules! __ra_macro_fixture439 {()=>($crate :: vec :: Vec :: new ()); ($elem : expr ; $n : expr )=>($crate :: vec :: from_elem ($elem , $n )); ($($x : expr ),+ $(,)?)=>(< [_]>:: into_vec ( box [$($x ),+])); }
macro_rules! __ra_macro_fixture440 {($left : expr , $right : expr $(,)?)=>({ match (&$left , &$right ){( left_val , right_val )=>{ if ! (* left_val == * right_val ){ panic ! ( r#"assertion failed: `(left == right)`\n left: `{:?}`,\n right: `{:?}`"# , &* left_val , &* right_val )}}}}); ($left : expr , $right : expr , $($arg : tt )+)=>({ match (& ($left ), & ($right )){( left_val , right_val )=>{ if ! (* left_val == * right_val ){ panic ! ( r#"assertion failed: `(left == right)`\n left: `{:?}`,\n right: `{:?}`: {}"# , &* left_val , &* right_val , $crate :: format_args ! ($($arg )+))}}}}); }
macro_rules! __ra_macro_fixture441 {()=>({$crate :: panic ! ( "explicit panic" )}); ($msg : expr $(,)?)=>({$crate :: rt :: begin_panic ($msg )}); ($fmt : expr , $($arg : tt )+)=>({$crate :: rt :: begin_panic_fmt (&$crate :: format_args ! ($fmt , $($arg )+))}); }
macro_rules! __ra_macro_fixture441 {()=>({$crate :: panic ! ( "explicit panic" )}); ($msg : expr $(,)?)=>({$crate :: rt :: panic_with_payload ($msg )}); ($fmt : expr , $($arg : tt )+)=>({$crate :: rt :: begin_panic_fmt (&$crate :: format_args ! ($fmt , $($arg )+))}); }
macro_rules! __ra_macro_fixture442 {($expression : expr , $($pattern : pat )|+ $(if $guard : expr )? $(,)?)=>{ match $expression {$($pattern )|+ $(if $guard )? => true , _ => false }}}
macro_rules! __ra_macro_fixture443 {()=>{# [ inline ] fn load_consume (& self )-> Self :: Val { self . load ( Ordering :: Acquire )}}; }
macro_rules! __ra_macro_fixture444 {($($tt : tt )*)=>{$($tt )* }}
Expand Down
20 changes: 14 additions & 6 deletions src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
//! This attribute to tell the compiler about semi built-in std library
//! features, such as Fn family of traits.
use hir_expand::name::Name;
use intern::{Symbol, sym};
use intern::{sym, Symbol};
use rustc_hash::FxHashMap;
use triomphe::Arc;

use crate::{
AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId,
StaticId, StructId, TraitId, TypeAliasId, UnionId,
db::DefDatabase,
expr_store::path::Path,
nameres::{assoc::TraitItems, crate_def_map},
AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId,
StaticId, StructId, TraitId, TypeAliasId, UnionId,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -153,7 +153,11 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt
}
}

if lang_items.items.is_empty() { None } else { Some(Box::new(lang_items)) }
if lang_items.items.is_empty() {
None
} else {
Some(Box::new(lang_items))
}
}

/// Salsa query. Look for a lang item, starting from the specified crate and recursively
Expand Down Expand Up @@ -226,7 +230,11 @@ pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option
}
}

if traits.is_empty() { None } else { Some(traits.into_iter().collect()) }
if traits.is_empty() {
None
} else {
Some(traits.into_iter().collect())
}
}

pub enum GenericRequirement {
Expand Down Expand Up @@ -416,7 +424,7 @@ language_item_table! {
PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, Target::Fn, GenericRequirement::Exact(0);
PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None;
/// libstd panic entry point. Necessary for const eval to be able to catch it
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
BeginPanic, sym::panic_with_payload, begin_panic_fn, Target::Fn, GenericRequirement::None;

// Lang items needed for `format_args!()`.
FormatAlignment, sym::format_alignment, format_alignment, Target::Enum, GenericRequirement::None;
Expand Down
12 changes: 6 additions & 6 deletions src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ use std::cmp::{self, Ordering};

use chalk_ir::TyKind;
use hir_def::{
CrateRootModuleId,
builtin_type::{BuiltinInt, BuiltinUint},
resolver::HasResolver,
CrateRootModuleId,
};
use hir_expand::name::Name;
use intern::{Symbol, sym};
use intern::{sym, Symbol};
use stdx::never;

use crate::{
DropGlue,
display::DisplayTarget,
error_lifetime,
mir::eval::{
Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay,
pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay,
InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId,
LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution,
Ty, TyBuilder, TyExt, pad16,
Ty, TyBuilder, TyExt,
},
DropGlue,
};

mod simd;
Expand Down Expand Up @@ -295,7 +295,7 @@ impl Evaluator<'_> {
let attrs = self.db.attrs(def.into());

if attrs.by_key(sym::rustc_const_panic_str).exists() {
// `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE.
// `#[rustc_const_panic_str]` is treated like `lang = "panic_with_payload"` by rustc CTFE.
return Some(LangItem::BeginPanic);
}

Expand Down
4 changes: 2 additions & 2 deletions src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::hash::{BuildHasher, BuildHasherDefault};
use dashmap::{DashMap, SharedValue};
use rustc_hash::FxHasher;

use crate::{Symbol, symbol::TaggedArcPtr};
use crate::{symbol::TaggedArcPtr, Symbol};

macro_rules! define_symbols {
(@WITH_NAME: $($alias:ident = $value:literal,)* @PLAIN: $($name:ident,)*) => {
Expand Down Expand Up @@ -127,7 +127,7 @@ define_symbols! {
asm,
assert,
attributes,
begin_panic,
panic_with_payload,
bench,
bitand_assign,
bitand,
Expand Down
2 changes: 1 addition & 1 deletion tests/mir-opt/building/issue_101867.main.built.after.mir
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn main() -> () {
bb1: {
StorageLive(_3);
StorageLive(_4);
_4 = begin_panic::<&str>(const "explicit panic") -> bb8;
_4 = panic_with_payload::<&str>(const "explicit panic") -> bb8;
}

bb2: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}

bb1: {
_2 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
_2 = panic_with_payload::<&str>(const "explicit panic") -> unwind unreachable;
}

bb2: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}

bb1: {
_2 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
_2 = panic_with_payload::<&str>(const "explicit panic") -> unwind continue;
}

bb2: {
Expand Down
2 changes: 1 addition & 1 deletion tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

bb2: {
StorageLive(_6);
_6 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
_6 = panic_with_payload::<&str>(const "explicit panic") -> unwind unreachable;
}

bb3: {
Expand Down
2 changes: 1 addition & 1 deletion tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

bb2: {
StorageLive(_6);
_6 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
_6 = panic_with_payload::<&str>(const "explicit panic") -> unwind continue;
}

bb3: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
StorageLive(_6);
- _6 = panic() -> unwind unreachable;
+ StorageLive(_7);
+ _7 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
+ _7 = panic_with_payload::<&str>(const "explicit panic") -> unwind unreachable;
}
+ }
+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
StorageLive(_6);
- _6 = panic() -> unwind continue;
+ StorageLive(_7);
+ _7 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
+ _7 = panic_with_payload::<&str>(const "explicit panic") -> unwind continue;
}
+ }
+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn unwrap(_1: Option<T>) -> T {

bb2: {
StorageLive(_4);
_4 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
_4 = panic_with_payload::<&str>(const "explicit panic") -> unwind unreachable;
}

bb3: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn unwrap(_1: Option<T>) -> T {

bb2: {
StorageLive(_4);
_4 = begin_panic::<&str>(const "explicit panic") -> bb4;
_4 = panic_with_payload::<&str>(const "explicit panic") -> bb4;
}

bb3: {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-16966.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | panic!(std::default::Default::default());
| required by a bound introduced by this call
|
= note: cannot satisfy `_: Any`
note: required by a bound in `begin_panic`
note: required by a bound in `panic_with_payload`
--> $SRC_DIR/std/src/panicking.rs:LL:COL

error: aborting due to 1 previous error
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/panics/issue-47429-short-backtraces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

// This is needed to avoid test output differences across std being built with v0 symbols vs legacy
// symbols.
//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic"
//@ normalize-stderr: "panic_with_payload::<&str>" -> "panic_with_payload"
// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997)
//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic"
//@ normalize-stderr: " panic_with_payload<&str>" -> " std::panicking::panic_with_payload"
// And this is for differences between std with and without debuginfo.
//@ normalize-stderr: "\n +at [^\n]+" -> ""

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/panics/issue-47429-short-backtraces.run.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:24:5:
explicit panic
stack backtrace:
0: std::panicking::begin_panic
0: std::panicking::panic_with_payload
1: issue_47429_short_backtraces::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:48:5
stack backtrace:
0: std::panicking::begin_panic
0: std::panicking::panic_with_payload
1: d
2: c
3: b
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/panics/runtime-switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

// This is needed to avoid test output differences across std being built with v0 symbols vs legacy
// symbols.
//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic"
//@ normalize-stderr: "panic_with_payload::<&str>" -> "panic_with_payload"
// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997)
//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic"
//@ normalize-stderr: " panic_with_payload<&str>" -> " std::panicking::panic_with_payload"
// And this is for differences between std with and without debuginfo.
//@ normalize-stderr: "\n +at [^\n]+" -> ""

Expand Down
Loading
Loading