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

rustc_expand cleanups #124607

Merged
merged 14 commits into from
May 3, 2024
58 changes: 23 additions & 35 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_session::config::CollapseMacroDebuginfo;
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{FileName, Span, DUMMY_SP};
Expand All @@ -32,8 +32,6 @@ use std::path::{Path, PathBuf};
use std::rc::Rc;
use thin_vec::ThinVec;

pub(crate) use rustc_span::hygiene::MacroKind;

// When adding new variants, make sure to
// adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
// to use `assign_id!`
Expand Down Expand Up @@ -573,35 +571,6 @@ impl DummyResult {
tokens: None,
})
}

/// A plain dummy pattern.
pub fn raw_pat(sp: Span) -> ast::Pat {
ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: sp, tokens: None }
}

/// A plain dummy type.
pub fn raw_ty(sp: Span) -> P<ast::Ty> {
// FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
// values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
// support, so we use an empty tuple instead.
P(ast::Ty {
id: ast::DUMMY_NODE_ID,
kind: ast::TyKind::Tup(ThinVec::new()),
span: sp,
tokens: None,
})
}

/// A plain dummy crate.
pub fn raw_crate() -> ast::Crate {
ast::Crate {
attrs: Default::default(),
items: Default::default(),
spans: Default::default(),
id: ast::DUMMY_NODE_ID,
is_placeholder: Default::default(),
}
}
}

impl MacResult for DummyResult {
Expand All @@ -610,7 +579,12 @@ impl MacResult for DummyResult {
}

fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
Some(P(DummyResult::raw_pat(self.span)))
Some(P(ast::Pat {
id: ast::DUMMY_NODE_ID,
kind: PatKind::Wild,
span: self.span,
tokens: None,
}))
}

fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
Expand Down Expand Up @@ -638,7 +612,15 @@ impl MacResult for DummyResult {
}

fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
Some(DummyResult::raw_ty(self.span))
// FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
// values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
// support, so we use an empty tuple instead.
Some(P(ast::Ty {
id: ast::DUMMY_NODE_ID,
kind: ast::TyKind::Tup(ThinVec::new()),
span: self.span,
tokens: None,
}))
}

fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
Expand Down Expand Up @@ -670,7 +652,13 @@ impl MacResult for DummyResult {
}

fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
Some(DummyResult::raw_crate())
Some(ast::Crate {
attrs: Default::default(),
items: Default::default(),
spans: Default::default(),
id: ast::DUMMY_NODE_ID,
is_placeholder: Default::default(),
})
}
}

Expand Down
27 changes: 0 additions & 27 deletions compiler/rustc_expand/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,6 @@ impl<'a> ExtCtxt<'a> {
ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
}

pub fn stmt_let_pat(&self, sp: Span, pat: P<ast::Pat>, ex: P<ast::Expr>) -> ast::Stmt {
let local = P(ast::Local {
pat,
ty: None,
id: ast::DUMMY_NODE_ID,
kind: LocalKind::Init(ex),
span: sp,
colon_sp: None,
attrs: AttrVec::new(),
tokens: None,
});
self.stmt_local(local, sp)
}

pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
self.stmt_let_ty(sp, mutbl, ident, None, ex)
}
Expand Down Expand Up @@ -278,10 +264,6 @@ impl<'a> ExtCtxt<'a> {
self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
}

pub fn expr_field(&self, span: Span, expr: P<Expr>, field: Ident) -> P<ast::Expr> {
self.expr(span, ast::ExprKind::Field(expr, field))
}

pub fn expr_macro_call(&self, span: Span, call: P<ast::MacCall>) -> P<ast::Expr> {
self.expr(span, ast::ExprKind::MacCall(call))
}
Expand Down Expand Up @@ -394,11 +376,6 @@ impl<'a> ExtCtxt<'a> {
self.expr(span, ast::ExprKind::Lit(lit))
}

pub fn expr_char(&self, span: Span, ch: char) -> P<ast::Expr> {
let lit = token::Lit::new(token::Char, literal::escape_char_symbol(ch), None);
self.expr(span, ast::ExprKind::Lit(lit))
}

pub fn expr_byte_str(&self, span: Span, bytes: Vec<u8>) -> P<ast::Expr> {
let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None);
self.expr(span, ast::ExprKind::Lit(lit))
Expand All @@ -414,10 +391,6 @@ impl<'a> ExtCtxt<'a> {
self.expr_addr_of(sp, self.expr_array(sp, exprs))
}

pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> {
self.expr(sp, ast::ExprKind::Cast(expr, ty))
}

pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
self.expr_call_global(sp, some, thin_vec![expr])
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,11 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
// If the declared feature is unstable, record it.
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
(f.set_enabled)(&mut features);
// When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance
// that the person hitting the ICE may be using -Zbuild-std or similar with an untested target.
// The bug is probably in the standard library and not the compiler in that case, but that doesn't
// really matter - we want a bug report.
// When the ICE comes from core, alloc or std (approximation of the standard
// library), there's a chance that the person hitting the ICE may be using
// -Zbuild-std or similar with an untested target. The bug is probably in the
// standard library and not the compiler in that case, but that doesn't really
// matter - we want a bug report.
if features.internal(name)
&& ![sym::core, sym::alloc, sym::std].contains(&crate_name)
{
Expand Down
54 changes: 29 additions & 25 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::errors::{
IncompleteParse, RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported,
UnsupportedKeyValue, WrongFragmentKind,
};
use crate::hygiene::SyntaxContext;
use crate::mbe::diagnostics::annotate_err_with_kind;
use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
use crate::placeholders::{placeholder, PlaceholderExpander};
Expand Down Expand Up @@ -32,6 +31,7 @@ use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::parse::feature_err;
use rustc_session::{Limit, Session};
use rustc_span::hygiene::SyntaxContext;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{ErrorGuaranteed, FileName, LocalExpnId, Span};

Expand Down Expand Up @@ -87,7 +87,7 @@ macro_rules! ast_fragments {
}

impl AstFragment {
pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
fn add_placeholders(&mut self, placeholders: &[NodeId]) {
if placeholders.is_empty() {
return;
}
Expand All @@ -100,14 +100,14 @@ macro_rules! ast_fragments {
}
}

pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
pub(crate) fn make_opt_expr(self) -> Option<P<ast::Expr>> {
match self {
AstFragment::OptExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
}
}

pub fn make_method_receiver_expr(self) -> P<ast::Expr> {
pub(crate) fn make_method_receiver_expr(self) -> P<ast::Expr> {
match self {
AstFragment::MethodReceiverExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
Expand All @@ -125,7 +125,7 @@ macro_rules! ast_fragments {
T::fragment_to_output(self)
}

pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
pub(crate) fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
match self {
AstFragment::OptExpr(opt_expr) => {
visit_clobber(opt_expr, |opt_expr| {
Expand Down Expand Up @@ -372,6 +372,14 @@ impl Invocation {
InvocationKind::Derive { path, .. } => path.span,
}
}

fn span_mut(&mut self) -> &mut Span {
match &mut self.kind {
InvocationKind::Bang { span, .. } => span,
InvocationKind::Attr { attr, .. } => &mut attr.span,
InvocationKind::Derive { path, .. } => &mut path.span,
}
}
}

pub struct MacroExpander<'a, 'b> {
Expand Down Expand Up @@ -432,7 +440,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
break;
}
invocations = mem::take(&mut undetermined_invocations);
force = !mem::replace(&mut progress, false);
force = !progress;
progress = false;
if force && self.monotonic {
self.cx.dcx().span_delayed_bug(
invocations.last().unwrap().0.span(),
Expand Down Expand Up @@ -471,7 +480,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.cx.force_mode = force;

let fragment_kind = invoc.fragment_kind;
let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
match self.expand_invoc(invoc, &ext.kind) {
ExpandResult::Ready(fragment) => {
let mut derive_invocations = Vec::new();
let derive_placeholders = self
Expand Down Expand Up @@ -503,12 +512,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
})
.unwrap_or_default();

let (fragment, collected_invocations) =
let (expanded_fragment, collected_invocations) =
self.collect_invocations(fragment, &derive_placeholders);
// We choose to expand any derive invocations associated with this macro invocation
// *before* any macro invocations collected from the output 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);
(fragment, derive_invocations)

progress = true;
if expanded_fragments.len() < depth {
expanded_fragments.push(Vec::new());
}
expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
invocations.extend(derive_invocations.into_iter().rev());
}
ExpandResult::Retry(invoc) => {
if force {
Expand All @@ -519,17 +535,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
} else {
// Cannot expand, will retry this invocation later.
undetermined_invocations.push((invoc, Some(ext)));
continue;
}
}
};

progress = true;
if expanded_fragments.len() < depth {
expanded_fragments.push(Vec::new());
}
expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
invocations.extend(new_invocations.into_iter().rev());
}

self.cx.current_expansion = orig_expansion_data;
Expand Down Expand Up @@ -590,11 +598,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
for (invoc, _) in invocations.iter_mut() {
let expn_id = invoc.expansion_data.id;
let parent_def = self.cx.resolver.invocation_parent(expn_id);
let span = match &mut invoc.kind {
InvocationKind::Bang { span, .. } => span,
InvocationKind::Attr { attr, .. } => &mut attr.span,
InvocationKind::Derive { path, .. } => &mut path.span,
};
let span = invoc.span_mut();
*span = span.with_parent(Some(parent_def));
}
}
Expand Down Expand Up @@ -957,7 +961,7 @@ pub fn parse_ast_fragment<'a>(
})
}

pub fn ensure_complete_parse<'a>(
pub(crate) fn ensure_complete_parse<'a>(
parser: &Parser<'a>,
macro_path: &ast::Path,
kind_name: &str,
Expand Down
24 changes: 10 additions & 14 deletions compiler/rustc_expand/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,39 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![feature(array_windows)]
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(lint_reasons)]
#![feature(macro_metavar_expr)]
#![feature(map_try_insert)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_span)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(internal_features)]
// tidy-alphabetical-end

extern crate proc_macro as pm;

mod build;
mod errors;
// FIXME(Nilstrieb) Translate macro_rules diagnostics
#[allow(rustc::untranslatable_diagnostic)]
mod mbe;
mod placeholders;
mod proc_macro_server;

pub use mbe::macro_rules::compile_declarative_macro;
pub(crate) use rustc_span::hygiene;
pub mod base;
pub mod build;
#[macro_use]
pub mod config;
pub mod errors;
pub mod expand;
pub mod module;

// FIXME(Nilstrieb) Translate proc_macro diagnostics
#[allow(rustc::untranslatable_diagnostic)]
pub mod proc_macro;

// FIXME(Nilstrieb) Translate macro_rules diagnostics
#[allow(rustc::untranslatable_diagnostic)]
pub(crate) mod mbe;

// HACK(Centril, #64197): These shouldn't really be here.
// Rather, they should be with their respective modules which are defined in other crates.
// However, since for now constructing a `ParseSess` sorta requires `config` from this crate,
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_expand/src/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
//! official terminology: "declarative macros".

pub(crate) mod diagnostics;
pub(crate) mod macro_check;
pub(crate) mod macro_parser;
pub(crate) mod macro_rules;
pub(crate) mod metavar_expr;
pub(crate) mod quoted;
pub(crate) mod transcribe;

mod macro_check;
mod macro_parser;
mod metavar_expr;
mod quoted;
mod transcribe;

use metavar_expr::MetaVarExpr;
use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind};
Expand Down
Loading
Loading