Skip to content

Commit b60e32c

Browse files
committed
Auto merge of #92434 - matthiaskrgr:rollup-m8wuq0v, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #91519 (ast: Avoid aborts on fatal errors thrown from mutable AST visitor) - #92414 (Fix spacing of pretty printed const item without body) - #92423 (Add UI test for #92292) - #92427 (Use `UnsafeCell::get_mut()` in `core::lazy::OnceCell::get_mut()`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents f8d4ee7 + c10fe04 commit b60e32c

File tree

7 files changed

+176
-37
lines changed

7 files changed

+176
-37
lines changed

Diff for: compiler/rustc_ast/src/mut_visit.rs

+116-12
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ use crate::tokenstream::*;
1414

1515
use rustc_data_structures::map_in_place::MapInPlace;
1616
use rustc_data_structures::sync::Lrc;
17+
use rustc_data_structures::thin_vec::ThinVec;
1718
use rustc_span::source_map::Spanned;
1819
use rustc_span::symbol::Ident;
1920
use rustc_span::Span;
2021

2122
use smallvec::{smallvec, Array, SmallVec};
2223
use std::ops::DerefMut;
23-
use std::{panic, process, ptr};
24+
use std::{panic, ptr};
2425

2526
pub trait ExpectOne<A: Array> {
2627
fn expect_one(self, err: &'static str) -> A::Item;
@@ -283,23 +284,21 @@ pub trait MutVisitor: Sized {
283284

284285
/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
285286
/// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
286-
/// method. Abort the program if the closure panics.
287-
///
288-
/// FIXME: Abort on panic means that any fatal error inside `visit_clobber` will abort the compiler.
289-
/// Instead of aborting on catching a panic we need to reset the visited node to some valid but
290-
/// possibly meaningless value and rethrow the panic.
287+
/// method.
291288
//
292289
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
293-
pub fn visit_clobber<T, F>(t: &mut T, f: F)
294-
where
295-
F: FnOnce(T) -> T,
296-
{
290+
pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) {
297291
unsafe {
298292
// Safe because `t` is used in a read-only fashion by `read()` before
299293
// being overwritten by `write()`.
300294
let old_t = ptr::read(t);
301-
let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t)))
302-
.unwrap_or_else(|_| process::abort());
295+
let new_t =
296+
panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))).unwrap_or_else(|err| {
297+
// Set `t` to some valid but possible meaningless value,
298+
// and pass the fatal error further.
299+
ptr::write(t, T::dummy());
300+
panic::resume_unwind(err);
301+
});
303302
ptr::write(t, new_t);
304303
}
305304
}
@@ -1454,3 +1453,108 @@ pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
14541453
}
14551454
vis.visit_span(&mut visibility.span);
14561455
}
1456+
1457+
/// Some value for the AST node that is valid but possibly meaningless.
1458+
pub trait DummyAstNode {
1459+
fn dummy() -> Self;
1460+
}
1461+
1462+
impl<T> DummyAstNode for Option<T> {
1463+
fn dummy() -> Self {
1464+
Default::default()
1465+
}
1466+
}
1467+
1468+
impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
1469+
fn dummy() -> Self {
1470+
P(DummyAstNode::dummy())
1471+
}
1472+
}
1473+
1474+
impl<T> DummyAstNode for ThinVec<T> {
1475+
fn dummy() -> Self {
1476+
Default::default()
1477+
}
1478+
}
1479+
1480+
impl DummyAstNode for Item {
1481+
fn dummy() -> Self {
1482+
Item {
1483+
attrs: Default::default(),
1484+
id: DUMMY_NODE_ID,
1485+
span: Default::default(),
1486+
vis: Visibility {
1487+
kind: VisibilityKind::Public,
1488+
span: Default::default(),
1489+
tokens: Default::default(),
1490+
},
1491+
ident: Ident::empty(),
1492+
kind: ItemKind::ExternCrate(None),
1493+
tokens: Default::default(),
1494+
}
1495+
}
1496+
}
1497+
1498+
impl DummyAstNode for Expr {
1499+
fn dummy() -> Self {
1500+
Expr {
1501+
id: DUMMY_NODE_ID,
1502+
kind: ExprKind::Err,
1503+
span: Default::default(),
1504+
attrs: Default::default(),
1505+
tokens: Default::default(),
1506+
}
1507+
}
1508+
}
1509+
1510+
impl DummyAstNode for Ty {
1511+
fn dummy() -> Self {
1512+
Ty {
1513+
id: DUMMY_NODE_ID,
1514+
kind: TyKind::Err,
1515+
span: Default::default(),
1516+
tokens: Default::default(),
1517+
}
1518+
}
1519+
}
1520+
1521+
impl DummyAstNode for Pat {
1522+
fn dummy() -> Self {
1523+
Pat {
1524+
id: DUMMY_NODE_ID,
1525+
kind: PatKind::Wild,
1526+
span: Default::default(),
1527+
tokens: Default::default(),
1528+
}
1529+
}
1530+
}
1531+
1532+
impl DummyAstNode for Stmt {
1533+
fn dummy() -> Self {
1534+
Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
1535+
}
1536+
}
1537+
1538+
impl DummyAstNode for Block {
1539+
fn dummy() -> Self {
1540+
Block {
1541+
stmts: Default::default(),
1542+
id: DUMMY_NODE_ID,
1543+
rules: BlockCheckMode::Default,
1544+
span: Default::default(),
1545+
tokens: Default::default(),
1546+
could_be_bare_literal: Default::default(),
1547+
}
1548+
}
1549+
}
1550+
1551+
impl DummyAstNode for Crate {
1552+
fn dummy() -> Self {
1553+
Crate {
1554+
attrs: Default::default(),
1555+
items: Default::default(),
1556+
span: Default::default(),
1557+
is_placeholder: Default::default(),
1558+
}
1559+
}
1560+
}

Diff for: compiler/rustc_ast_pretty/src/pprust/state.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,9 @@ impl<'a> State<'a> {
11161116
self.print_ident(ident);
11171117
self.word_space(":");
11181118
self.print_type(ty);
1119-
self.space();
1119+
if body.is_some() {
1120+
self.space();
1121+
}
11201122
self.end(); // end the head-ibox
11211123
if let Some(body) = body {
11221124
self.word_space("=");

Diff for: compiler/rustc_expand/src/expand.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1160,13 +1160,18 @@ macro_rules! assign_id {
11601160

11611161
impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11621162
fn visit_crate(&mut self, krate: &mut ast::Crate) {
1163-
let span = krate.span;
1164-
let empty_crate =
1165-
|| ast::Crate { attrs: Vec::new(), items: Vec::new(), span, is_placeholder: None };
1166-
let mut fold_crate = |krate: ast::Crate| {
1163+
visit_clobber(krate, |krate| {
1164+
let span = krate.span;
11671165
let mut krate = match self.configure(krate) {
11681166
Some(krate) => krate,
1169-
None => return empty_crate(),
1167+
None => {
1168+
return ast::Crate {
1169+
attrs: Vec::new(),
1170+
items: Vec::new(),
1171+
span,
1172+
is_placeholder: None,
1173+
};
1174+
}
11701175
};
11711176

11721177
if let Some(attr) = self.take_first_attr(&mut krate) {
@@ -1177,10 +1182,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
11771182

11781183
noop_visit_crate(&mut krate, self);
11791184
krate
1180-
};
1181-
1182-
// Cannot use `visit_clobber` here, see the FIXME on it.
1183-
*krate = fold_crate(mem::replace(krate, empty_crate()));
1185+
})
11841186
}
11851187

11861188
fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {

Diff for: library/core/src/lazy.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ impl<T> OnceCell<T> {
102102
/// Returns `None` if the cell is empty.
103103
#[unstable(feature = "once_cell", issue = "74465")]
104104
pub fn get_mut(&mut self) -> Option<&mut T> {
105-
// SAFETY: Safe because we have unique access
106-
unsafe { &mut *self.inner.get() }.as_mut()
105+
self.inner.get_mut().as_mut()
107106
}
108107

109108
/// Sets the contents of the cell to `value`.

Diff for: src/test/pretty/nested-item-vis-defaultness.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,42 @@ fn main() {}
66

77
#[cfg(FALSE)]
88
extern "C" {
9-
static X: u8 ;
9+
static X: u8;
1010
type X;
1111
fn foo();
12-
pub static X: u8 ;
12+
pub static X: u8;
1313
pub type X;
1414
pub fn foo();
1515
}
1616

1717
#[cfg(FALSE)]
1818
trait T {
19-
const X: u8 ;
19+
const X: u8;
2020
type X;
2121
fn foo();
22-
default const X: u8 ;
22+
default const X: u8;
2323
default type X;
2424
default fn foo();
25-
pub const X: u8 ;
25+
pub const X: u8;
2626
pub type X;
2727
pub fn foo();
28-
pub default const X: u8 ;
28+
pub default const X: u8;
2929
pub default type X;
3030
pub default fn foo();
3131
}
3232

3333
#[cfg(FALSE)]
3434
impl T for S {
35-
const X: u8 ;
35+
const X: u8;
3636
type X;
3737
fn foo();
38-
default const X: u8 ;
38+
default const X: u8;
3939
default type X;
4040
default fn foo();
41-
pub const X: u8 ;
41+
pub const X: u8;
4242
pub type X;
4343
pub fn foo();
44-
pub default const X: u8 ;
44+
pub default const X: u8;
4545
pub default type X;
4646
pub default fn foo();
4747
}

Diff for: src/test/ui/macros/stringify.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,13 @@ fn test_item() {
382382
stringify_item!(
383383
static S: ();
384384
),
385-
"static S: () ;", // FIXME
385+
"static S: ();",
386386
);
387387
assert_eq!(
388388
stringify_item!(
389389
static mut S: ();
390390
),
391-
"static mut S: () ;",
391+
"static mut S: ();",
392392
);
393393

394394
// ItemKind::Const
@@ -402,7 +402,7 @@ fn test_item() {
402402
stringify_item!(
403403
const S: ();
404404
),
405-
"const S: () ;", // FIXME
405+
"const S: ();",
406406
);
407407

408408
// ItemKind::Fn

Diff for: src/test/ui/traits/issue-92292.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// check-pass
2+
3+
use std::marker::PhantomData;
4+
5+
pub struct MyGenericType<T> {
6+
_marker: PhantomData<*const T>,
7+
}
8+
9+
pub struct MyNonGenericType;
10+
11+
impl<T> From<MyGenericType<T>> for MyNonGenericType {
12+
fn from(_: MyGenericType<T>) -> Self {
13+
todo!()
14+
}
15+
}
16+
17+
pub trait MyTrait {
18+
const MY_CONSTANT: i32;
19+
}
20+
21+
impl<T> MyTrait for MyGenericType<T>
22+
where
23+
Self: Into<MyNonGenericType>,
24+
{
25+
const MY_CONSTANT: i32 = 1;
26+
}
27+
28+
impl<T> MyGenericType<T> {
29+
const MY_OTHER_CONSTANT: i32 = <MyGenericType<T> as MyTrait>::MY_CONSTANT;
30+
}
31+
32+
fn main() {}

0 commit comments

Comments
 (0)