Skip to content

Commit

Permalink
Auto merge of rust-lang#92434 - matthiaskrgr:rollup-m8wuq0v, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang#91519 (ast: Avoid aborts on fatal errors thrown from mutable AST visitor)
 - rust-lang#92414 (Fix spacing of pretty printed const item without body)
 - rust-lang#92423 (Add UI test for rust-lang#92292)
 - rust-lang#92427 (Use `UnsafeCell::get_mut()` in `core::lazy::OnceCell::get_mut()`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 30, 2021
2 parents f8d4ee7 + c10fe04 commit b60e32c
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 37 deletions.
128 changes: 116 additions & 12 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ use crate::tokenstream::*;

use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Ident;
use rustc_span::Span;

use smallvec::{smallvec, Array, SmallVec};
use std::ops::DerefMut;
use std::{panic, process, ptr};
use std::{panic, ptr};

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

/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
/// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
/// method. Abort the program if the closure panics.
///
/// FIXME: Abort on panic means that any fatal error inside `visit_clobber` will abort the compiler.
/// Instead of aborting on catching a panic we need to reset the visited node to some valid but
/// possibly meaningless value and rethrow the panic.
/// method.
//
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_clobber<T, F>(t: &mut T, f: F)
where
F: FnOnce(T) -> T,
{
pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) {
unsafe {
// Safe because `t` is used in a read-only fashion by `read()` before
// being overwritten by `write()`.
let old_t = ptr::read(t);
let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t)))
.unwrap_or_else(|_| process::abort());
let new_t =
panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))).unwrap_or_else(|err| {
// Set `t` to some valid but possible meaningless value,
// and pass the fatal error further.
ptr::write(t, T::dummy());
panic::resume_unwind(err);
});
ptr::write(t, new_t);
}
}
Expand Down Expand Up @@ -1454,3 +1453,108 @@ pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
}
vis.visit_span(&mut visibility.span);
}

/// Some value for the AST node that is valid but possibly meaningless.
pub trait DummyAstNode {
fn dummy() -> Self;
}

impl<T> DummyAstNode for Option<T> {
fn dummy() -> Self {
Default::default()
}
}

impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
fn dummy() -> Self {
P(DummyAstNode::dummy())
}
}

impl<T> DummyAstNode for ThinVec<T> {
fn dummy() -> Self {
Default::default()
}
}

impl DummyAstNode for Item {
fn dummy() -> Self {
Item {
attrs: Default::default(),
id: DUMMY_NODE_ID,
span: Default::default(),
vis: Visibility {
kind: VisibilityKind::Public,
span: Default::default(),
tokens: Default::default(),
},
ident: Ident::empty(),
kind: ItemKind::ExternCrate(None),
tokens: Default::default(),
}
}
}

impl DummyAstNode for Expr {
fn dummy() -> Self {
Expr {
id: DUMMY_NODE_ID,
kind: ExprKind::Err,
span: Default::default(),
attrs: Default::default(),
tokens: Default::default(),
}
}
}

impl DummyAstNode for Ty {
fn dummy() -> Self {
Ty {
id: DUMMY_NODE_ID,
kind: TyKind::Err,
span: Default::default(),
tokens: Default::default(),
}
}
}

impl DummyAstNode for Pat {
fn dummy() -> Self {
Pat {
id: DUMMY_NODE_ID,
kind: PatKind::Wild,
span: Default::default(),
tokens: Default::default(),
}
}
}

impl DummyAstNode for Stmt {
fn dummy() -> Self {
Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
}
}

impl DummyAstNode for Block {
fn dummy() -> Self {
Block {
stmts: Default::default(),
id: DUMMY_NODE_ID,
rules: BlockCheckMode::Default,
span: Default::default(),
tokens: Default::default(),
could_be_bare_literal: Default::default(),
}
}
}

impl DummyAstNode for Crate {
fn dummy() -> Self {
Crate {
attrs: Default::default(),
items: Default::default(),
span: Default::default(),
is_placeholder: Default::default(),
}
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,9 @@ impl<'a> State<'a> {
self.print_ident(ident);
self.word_space(":");
self.print_type(ty);
self.space();
if body.is_some() {
self.space();
}
self.end(); // end the head-ibox
if let Some(body) = body {
self.word_space("=");
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,13 +1160,18 @@ macro_rules! assign_id {

impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
fn visit_crate(&mut self, krate: &mut ast::Crate) {
let span = krate.span;
let empty_crate =
|| ast::Crate { attrs: Vec::new(), items: Vec::new(), span, is_placeholder: None };
let mut fold_crate = |krate: ast::Crate| {
visit_clobber(krate, |krate| {
let span = krate.span;
let mut krate = match self.configure(krate) {
Some(krate) => krate,
None => return empty_crate(),
None => {
return ast::Crate {
attrs: Vec::new(),
items: Vec::new(),
span,
is_placeholder: None,
};
}
};

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

noop_visit_crate(&mut krate, self);
krate
};

// Cannot use `visit_clobber` here, see the FIXME on it.
*krate = fold_crate(mem::replace(krate, empty_crate()));
})
}

fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ impl<T> OnceCell<T> {
/// Returns `None` if the cell is empty.
#[unstable(feature = "once_cell", issue = "74465")]
pub fn get_mut(&mut self) -> Option<&mut T> {
// SAFETY: Safe because we have unique access
unsafe { &mut *self.inner.get() }.as_mut()
self.inner.get_mut().as_mut()
}

/// Sets the contents of the cell to `value`.
Expand Down
20 changes: 10 additions & 10 deletions src/test/pretty/nested-item-vis-defaultness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,42 @@ fn main() {}

#[cfg(FALSE)]
extern "C" {
static X: u8 ;
static X: u8;
type X;
fn foo();
pub static X: u8 ;
pub static X: u8;
pub type X;
pub fn foo();
}

#[cfg(FALSE)]
trait T {
const X: u8 ;
const X: u8;
type X;
fn foo();
default const X: u8 ;
default const X: u8;
default type X;
default fn foo();
pub const X: u8 ;
pub const X: u8;
pub type X;
pub fn foo();
pub default const X: u8 ;
pub default const X: u8;
pub default type X;
pub default fn foo();
}

#[cfg(FALSE)]
impl T for S {
const X: u8 ;
const X: u8;
type X;
fn foo();
default const X: u8 ;
default const X: u8;
default type X;
default fn foo();
pub const X: u8 ;
pub const X: u8;
pub type X;
pub fn foo();
pub default const X: u8 ;
pub default const X: u8;
pub default type X;
pub default fn foo();
}
6 changes: 3 additions & 3 deletions src/test/ui/macros/stringify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,13 @@ fn test_item() {
stringify_item!(
static S: ();
),
"static S: () ;", // FIXME
"static S: ();",
);
assert_eq!(
stringify_item!(
static mut S: ();
),
"static mut S: () ;",
"static mut S: ();",
);

// ItemKind::Const
Expand All @@ -402,7 +402,7 @@ fn test_item() {
stringify_item!(
const S: ();
),
"const S: () ;", // FIXME
"const S: ();",
);

// ItemKind::Fn
Expand Down
32 changes: 32 additions & 0 deletions src/test/ui/traits/issue-92292.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// check-pass

use std::marker::PhantomData;

pub struct MyGenericType<T> {
_marker: PhantomData<*const T>,
}

pub struct MyNonGenericType;

impl<T> From<MyGenericType<T>> for MyNonGenericType {
fn from(_: MyGenericType<T>) -> Self {
todo!()
}
}

pub trait MyTrait {
const MY_CONSTANT: i32;
}

impl<T> MyTrait for MyGenericType<T>
where
Self: Into<MyNonGenericType>,
{
const MY_CONSTANT: i32 = 1;
}

impl<T> MyGenericType<T> {
const MY_OTHER_CONSTANT: i32 = <MyGenericType<T> as MyTrait>::MY_CONSTANT;
}

fn main() {}

0 comments on commit b60e32c

Please sign in to comment.