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

[WIP] Remove ids from ast::Stmt and hir::Stmt #87981

Closed
wants to merge 16 commits into from
19 changes: 14 additions & 5 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,18 +908,26 @@ impl UnOp {
/// A statement
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Stmt {
pub id: NodeId,
pub kind: StmtKind,
pub span: Span,
}

impl Stmt {
pub fn id(&self) -> NodeId {
match self.kind {
StmtKind::Local(ref local) => local.id,
StmtKind::Item(ref item) => item.id,
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.id,
StmtKind::Empty { id } => id,
StmtKind::MacCall(ref mac) => mac.id,
}
}
pub fn tokens(&self) -> Option<&LazyTokenStream> {
match self.kind {
StmtKind::Local(ref local) => local.tokens.as_ref(),
StmtKind::Item(ref item) => item.tokens.as_ref(),
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.tokens.as_ref(),
StmtKind::Empty => None,
StmtKind::Empty { id: _ } => None,
StmtKind::MacCall(ref mac) => mac.tokens.as_ref(),
}
}
Expand All @@ -943,8 +951,8 @@ impl Stmt {
self.kind = match self.kind {
StmtKind::Expr(expr) => StmtKind::Semi(expr),
StmtKind::MacCall(mac) => {
StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens, id }| {
MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens, id }
}))
}
kind => kind,
Expand Down Expand Up @@ -973,13 +981,14 @@ pub enum StmtKind {
/// Expr with a trailing semi-colon.
Semi(P<Expr>),
/// Just a trailing semi-colon.
Empty,
Empty { id: NodeId },
/// Macro.
MacCall(P<MacCallStmt>),
}

#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MacCallStmt {
pub id: NodeId,
pub mac: MacCall,
pub style: MacStmtStyle,
pub attrs: AttrVec,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/ast_like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl AstLike for StmtKind {
StmtKind::Local(local) => local.attrs(),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.attrs(),
StmtKind::Item(item) => item.attrs(),
StmtKind::Empty => &[],
StmtKind::Empty { id: _ } => &[],
StmtKind::MacCall(mac) => &mac.attrs,
}
}
Expand All @@ -116,7 +116,7 @@ impl AstLike for StmtKind {
StmtKind::Local(local) => local.visit_attrs(f),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
StmtKind::Item(item) => item.visit_attrs(f),
StmtKind::Empty => {}
StmtKind::Empty { id: _ } => {}
StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f),
}
}
Expand All @@ -125,7 +125,7 @@ impl AstLike for StmtKind {
StmtKind::Local(local) => &mut local.tokens,
StmtKind::Item(item) => &mut item.tokens,
StmtKind::Expr(expr) | StmtKind::Semi(expr) => &mut expr.tokens,
StmtKind::Empty => return None,
StmtKind::Empty { id: _ } => return None,
StmtKind::MacCall(mac) => &mut mac.tokens,
})
}
Expand Down
23 changes: 17 additions & 6 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1369,12 +1369,19 @@ pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Optio
}

pub fn noop_flat_map_stmt<T: MutVisitor>(
Stmt { kind, mut span, mut id }: Stmt,
Stmt { kind, span }: Stmt,
vis: &mut T,
) -> SmallVec<[Stmt; 1]> {
vis.visit_id(&mut id);
vis.visit_span(&mut span);
noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| Stmt { id, kind, span }).collect()
let res = noop_flat_map_stmt_kind(kind, vis)
.into_iter()
.map(|kind| {
let mut new_span = span;
vis.visit_span(&mut new_span);
Stmt { kind, span: new_span }
})
.collect();
tracing::info!("Made new statements: {:?}", res);
res
}

pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
Expand All @@ -1389,9 +1396,13 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(),
StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(),
StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(),
StmtKind::Empty => smallvec![StmtKind::Empty],
StmtKind::Empty { mut id } => {
vis.visit_id(&mut id);
smallvec![StmtKind::Empty { id }]
}
StmtKind::MacCall(mut mac) => {
let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
let MacCallStmt { mac: mac_, style: _, attrs, tokens, id } = mac.deref_mut();
vis.visit_id(id);
vis.visit_mac_call(mac_);
visit_thin_attrs(attrs, vis);
visit_lazy_tts(tokens, vis);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,9 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) {
StmtKind::Local(ref local) => visitor.visit_local(local),
StmtKind::Item(ref item) => visitor.visit_item(item),
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr),
StmtKind::Empty => {}
StmtKind::Empty { id: _ } => {}
StmtKind::MacCall(ref mac) => {
let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac;
let MacCallStmt { ref mac, style: _, ref attrs, tokens: _, id: _ } = **mac;
visitor.visit_mac_call(mac);
for attr in attrs.iter() {
visitor.visit_attribute(attr);
Expand Down
30 changes: 7 additions & 23 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2415,49 +2415,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}

fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
let (hir_id, kind) = match s.kind {
let kind = match s.kind {
StmtKind::Local(ref l) => {
let l = self.lower_local(l);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, l.hir_id);
return smallvec![hir::Stmt {
hir_id,
kind: hir::StmtKind::Local(self.arena.alloc(l)),
span: s.span,
}];
}
StmtKind::Item(ref it) => {
// Can only use the ID once.
let mut id = Some(s.id);
return self
.lower_item_id(it)
.into_iter()
.map(|item_id| {
let hir_id = id
.take()
.map(|id| self.lower_node_id(id))
.unwrap_or_else(|| self.next_id());

hir::Stmt { hir_id, kind: hir::StmtKind::Item(item_id), span: s.span }
})
.map(|item_id| hir::Stmt { kind: hir::StmtKind::Item(item_id), span: s.span })
.collect();
}
StmtKind::Expr(ref e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
(hir_id, hir::StmtKind::Expr(e))
hir::StmtKind::Expr(e)
}
StmtKind::Semi(ref e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
(hir_id, hir::StmtKind::Semi(e))
hir::StmtKind::Semi(e)
}
StmtKind::Empty => return smallvec![],
StmtKind::Empty { id: _ } => return smallvec![],
StmtKind::MacCall(..) => panic!("shouldn't exist here"),
};
smallvec![hir::Stmt { hir_id, kind, span: s.span }]
smallvec![hir::Stmt { kind, span: s.span }]
}

fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
Expand Down Expand Up @@ -2492,7 +2476,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Helper methods for building HIR.

fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
hir::Stmt { span, kind, hir_id: self.next_id() }
hir::Stmt { span, kind }
}

fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,7 @@ impl<'a> State<'a> {
self.print_expr_outer_attr_style(expr, false);
self.s.word(";");
}
ast::StmtKind::Empty => {
ast::StmtKind::Empty { id: _ } => {
self.space_if_not_bol();
self.s.word(";");
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,5 @@ fn stmt_let_underscore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<ast::Expr>) -> as
attrs: ast::AttrVec::new(),
tokens: None,
});
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp }
ast::Stmt { kind: ast::StmtKind::Local(local), span: sp }
}
1 change: 0 additions & 1 deletion compiler/rustc_builtin_macros/src/deriving/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ impl MultiItemModifier for BuiltinDerive {
// Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
// to the function
items.push(Annotatable::Stmt(P(ast::Stmt {
id: ast::DUMMY_NODE_ID,
kind: ast::StmtKind::Item(a.expect_item()),
span,
})));
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,7 @@ where
// Use a macro because forwarding to a simple function has type system issues
macro_rules! make_stmts_default {
($me:expr) => {
$me.make_expr().map(|e| {
smallvec![ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: e.span,
kind: ast::StmtKind::Expr(e),
}]
})
$me.make_expr().map(|e| smallvec![ast::Stmt { span: e.span, kind: ast::StmtKind::Expr(e) }])
};
}

Expand Down Expand Up @@ -581,7 +575,6 @@ impl MacResult for DummyResult {

fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
Some(smallvec![ast::Stmt {
id: ast::DUMMY_NODE_ID,
kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.is_error)),
span: self.span,
}])
Expand Down
17 changes: 5 additions & 12 deletions compiler/rustc_expand/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<'a> ExtCtxt<'a> {
}

pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
ast::Stmt { span: expr.span, kind: ast::StmtKind::Expr(expr) }
}

pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
Expand All @@ -159,7 +159,7 @@ impl<'a> ExtCtxt<'a> {
attrs: AttrVec::new(),
tokens: None,
});
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp }
ast::Stmt { kind: ast::StmtKind::Local(local), span: sp }
}

// Generates `let _: Type;`, which is usually used for type assertions.
Expand All @@ -173,22 +173,15 @@ impl<'a> ExtCtxt<'a> {
attrs: AttrVec::new(),
tokens: None,
});
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span }
ast::Stmt { kind: ast::StmtKind::Local(local), span }
}

pub fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp }
ast::Stmt { kind: ast::StmtKind::Item(item), span: sp }
}

pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
self.block(
expr.span,
vec![ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: expr.span,
kind: ast::StmtKind::Expr(expr),
}],
)
self.block(expr.span, vec![ast::Stmt { span: expr.span, kind: ast::StmtKind::Expr(expr) }])
}
pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> {
P(ast::Block {
Expand Down
25 changes: 24 additions & 1 deletion compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem
use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe};
use rustc_ast_pretty::pprust;
use rustc_attr::is_builtin_attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
Expand Down Expand Up @@ -50,6 +51,7 @@ macro_rules! ast_fragments {
) => {
/// A fragment of AST that can be produced by a single macro expansion.
/// Can also serve as an input and intermediate result for macro expansion operations.
#[derive(Debug)]
pub enum AstFragment {
OptExpr(Option<P<ast::Expr>>),
$($Kind($AstTy),)*
Expand Down Expand Up @@ -422,6 +424,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
};
self.cx.trace_macros_diag();
check_ast(&mut krate);
krate
}

Expand Down Expand Up @@ -528,6 +531,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {

let (fragment, collected_invocations) =
self.collect_invocations(fragment, &derive_placeholders);
tracing::info!("Collected invocations: {:?}", fragment);
// We choose to expand any derive invocations associated with this macro invocation
// *before* any macro invocations collected from the output fragment
derive_invocations.extend(collected_invocations);
Expand Down Expand Up @@ -1312,7 +1316,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
}

if let StmtKind::MacCall(mac) = stmt.kind {
let MacCallStmt { mac, style, attrs, tokens: _ } = mac.into_inner();
let MacCallStmt { mac, style, attrs, tokens: _, id: _ } = mac.into_inner();
self.check_attributes(&attrs, &mac);
let mut placeholder =
self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts();
Expand Down Expand Up @@ -1627,3 +1631,22 @@ impl<'feat> ExpansionConfig<'feat> {
self.features.map_or(false, |features| features.proc_macro_hygiene)
}
}

fn check_ast(krate: &mut ast::Crate) {
struct AstChecker {
ids: FxHashSet<ast::NodeId>,
}
impl MutVisitor for AstChecker {
fn visit_id(&mut self, id: &mut ast::NodeId) {
if *id != ast::DUMMY_NODE_ID && !self.ids.insert(*id) {
panic!("Duplicate id: {:?}", id);
}
}
fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
tracing::info!("Visiting stmt: {:?}", stmt);
ast::mut_visit::noop_flat_map_stmt(stmt, self)
}
}
tracing::info!("Full ast: {:?}", krate);
//AstChecker { ids: Default::default() }.visit_crate(krate);
}
7 changes: 4 additions & 3 deletions compiler/rustc_expand/src/placeholders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ pub fn placeholder(
style: ast::MacStmtStyle::Braces,
attrs: ast::AttrVec::new(),
tokens: None,
id,
});
ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac) }
ast::Stmt { span, kind: ast::StmtKind::MacCall(mac) }
}]),
AstFragmentKind::Arms => AstFragment::Arms(smallvec![ast::Arm {
attrs: Default::default(),
Expand Down Expand Up @@ -297,7 +298,7 @@ impl MutVisitor for PlaceholderExpander {

fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
let (style, mut stmts) = match stmt.kind {
ast::StmtKind::MacCall(mac) => (mac.style, self.remove(stmt.id).make_stmts()),
ast::StmtKind::MacCall(ref mac) => (mac.style, self.remove(stmt.id()).make_stmts()),
_ => return noop_flat_map_stmt(stmt, self),
};

Expand All @@ -324,7 +325,7 @@ impl MutVisitor for PlaceholderExpander {
// FIXME: We will need to preserve the original semicolon token and
// span as part of #15701
let empty_stmt =
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Empty, span: DUMMY_SP };
ast::Stmt { kind: ast::StmtKind::Empty { id: ast::DUMMY_NODE_ID }, span: DUMMY_SP };

if let Some(stmt) = stmts.pop() {
if stmt.has_trailing_semicolon() {
Expand Down
Loading