Skip to content

Commit df4ce78

Browse files
committed
make declare macro a part of query system
1 parent 60faa27 commit df4ce78

File tree

21 files changed

+364
-68
lines changed

21 files changed

+364
-68
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3809,6 +3809,7 @@ dependencies = [
38093809
"rustc_lexer",
38103810
"rustc_lint_defs",
38113811
"rustc_macros",
3812+
"rustc_middle",
38123813
"rustc_parse",
38133814
"rustc_serialize",
38143815
"rustc_session",

compiler/rustc_ast/src/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2769,7 +2769,7 @@ impl UseTree {
27692769
/// Distinguishes between `Attribute`s that decorate items and Attributes that
27702770
/// are contained as statements within items. These two cases need to be
27712771
/// distinguished for pretty-printing.
2772-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
2772+
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Hash)]
27732773
pub enum AttrStyle {
27742774
Outer,
27752775
Inner,

compiler/rustc_ast/src/token.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ use rustc_span::symbol::{Ident, Symbol};
1717
use rustc_span::{edition::Edition, ErrorGuaranteed, Span, DUMMY_SP};
1818
use std::borrow::Cow;
1919
use std::fmt;
20+
use std::hash::{Hash, Hasher};
2021

21-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
22+
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Hash)]
2223
pub enum CommentKind {
2324
Line,
2425
Block,
@@ -63,7 +64,7 @@ pub enum Delimiter {
6364
// type. This means that float literals like `1f32` are classified by this type
6465
// as `Int`. Only upon conversion to `ast::LitKind` will such a literal be
6566
// given the `Float` kind.
66-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
67+
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Hash)]
6768
pub enum LitKind {
6869
Bool, // AST only, must never appear in a `Token`
6970
Byte,
@@ -80,7 +81,7 @@ pub enum LitKind {
8081
}
8182

8283
/// A literal token.
83-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
84+
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Hash)]
8485
pub struct Lit {
8586
pub kind: LitKind,
8687
pub symbol: Symbol,
@@ -224,7 +225,7 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: IdentIsRaw) -> bool {
224225
.contains(&name)
225226
}
226227

227-
#[derive(PartialEq, Encodable, Decodable, Debug, Copy, Clone, HashStable_Generic)]
228+
#[derive(PartialEq, Encodable, Decodable, Debug, Copy, Clone, HashStable_Generic, Hash)]
228229
pub enum IdentIsRaw {
229230
No,
230231
Yes,
@@ -244,7 +245,7 @@ impl From<IdentIsRaw> for bool {
244245

245246
// SAFETY: due to the `Clone` impl below, all fields of all variants other than
246247
// `Interpolated` must impl `Copy`.
247-
#[derive(PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
248+
#[derive(PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Hash)]
248249
pub enum TokenKind {
249250
/* Expression-operator symbols. */
250251
/// `=`
@@ -370,7 +371,7 @@ impl Clone for TokenKind {
370371
}
371372
}
372373

373-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
374+
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Hash)]
374375
pub struct Token {
375376
pub kind: TokenKind,
376377
pub span: Span,
@@ -869,7 +870,7 @@ pub enum Nonterminal {
869870
NtVis(P<ast::Visibility>),
870871
}
871872

872-
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
873+
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, Hash)]
873874
pub enum NonterminalKind {
874875
Item,
875876
Block,
@@ -1018,6 +1019,12 @@ where
10181019
}
10191020
}
10201021

1022+
impl Hash for Nonterminal {
1023+
fn hash<H: Hasher>(&self, _state: &mut H) {
1024+
panic!("interpolated tokens should not be present in the HIR")
1025+
}
1026+
}
1027+
10211028
// Some types are used a lot. Make sure they don't unintentionally get bigger.
10221029
#[cfg(target_pointer_width = "64")]
10231030
mod size_asserts {

compiler/rustc_ast/src/tokenstream.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ use rustc_span::{sym, Span, SpanDecoder, SpanEncoder, Symbol, DUMMY_SP};
2626
use smallvec::{smallvec, SmallVec};
2727

2828
use std::borrow::Cow;
29+
use std::hash::{Hash, Hasher};
2930
use std::{cmp, fmt, iter};
3031

3132
/// Part of a `TokenStream`.
32-
#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
33+
#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Hash)]
3334
pub enum TokenTree {
3435
/// A single token. Should never be `OpenDelim` or `CloseDelim`, because
3536
/// delimiters are implicitly represented by `Delimited`.
@@ -107,6 +108,14 @@ where
107108
}
108109
}
109110

111+
impl Hash for TokenStream {
112+
fn hash<H: Hasher>(&self, state: &mut H) {
113+
for sub_tt in self.trees() {
114+
sub_tt.hash(state);
115+
}
116+
}
117+
}
118+
110119
pub trait ToAttrTokenStream: sync::DynSend + sync::DynSync {
111120
fn to_attr_token_stream(&self) -> AttrTokenStream;
112121
}
@@ -297,7 +306,7 @@ pub struct TokenStream(pub(crate) Lrc<Vec<TokenTree>>);
297306
/// compound token. Used for conversions to `proc_macro::Spacing`. Also used to
298307
/// guide pretty-printing, which is where the `JointHidden` value (which isn't
299308
/// part of `proc_macro::Spacing`) comes in useful.
300-
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
309+
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Hash)]
301310
pub enum Spacing {
302311
/// The token cannot join with the following token to form a compound
303312
/// token.
@@ -733,7 +742,7 @@ impl TokenTreeCursor {
733742
}
734743
}
735744

736-
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
745+
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Hash)]
737746
pub struct DelimSpan {
738747
pub open: Span,
739748
pub close: Span,
@@ -757,7 +766,7 @@ impl DelimSpan {
757766
}
758767
}
759768

760-
#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
769+
#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Hash)]
761770
pub struct DelimSpacing {
762771
pub open: Spacing,
763772
pub close: Spacing,

compiler/rustc_expand/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
2020
rustc_lexer = { path = "../rustc_lexer" }
2121
rustc_lint_defs = { path = "../rustc_lint_defs" }
2222
rustc_macros = { path = "../rustc_macros" }
23+
rustc_middle = { path = "../rustc_middle" }
2324
rustc_parse = { path = "../rustc_parse" }
2425
rustc_serialize = { path = "../rustc_serialize" }
2526
rustc_session = { path = "../rustc_session" }

compiler/rustc_expand/src/base.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
1616
use rustc_feature::Features;
1717
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
1818
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, RegisteredTools};
19+
use rustc_middle::expand::{CanRetry, TcxMacroExpander};
1920
use rustc_parse::{parser, MACRO_ARGUMENTS};
2021
use rustc_session::config::CollapseMacroDebuginfo;
2122
use rustc_session::{parse::ParseSess, Limit, Session};
@@ -676,6 +677,11 @@ pub enum SyntaxExtensionKind {
676677
Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
677678
),
678679

680+
TcxLegacyBang(
681+
/// An expander with signature TokenStream -> AST.
682+
Lrc<dyn TcxMacroExpander + sync::DynSync + sync::DynSend>,
683+
),
684+
679685
/// A token-based attribute macro.
680686
Attr(
681687
/// An expander with signature (TokenStream, TokenStream) -> TokenStream.
@@ -749,7 +755,9 @@ impl SyntaxExtension {
749755
/// Returns which kind of macro calls this syntax extension.
750756
pub fn macro_kind(&self) -> MacroKind {
751757
match self.kind {
752-
SyntaxExtensionKind::Bang(..) | SyntaxExtensionKind::LegacyBang(..) => MacroKind::Bang,
758+
SyntaxExtensionKind::Bang(..)
759+
| SyntaxExtensionKind::LegacyBang(..)
760+
| SyntaxExtensionKind::TcxLegacyBang(..) => MacroKind::Bang,
753761
SyntaxExtensionKind::Attr(..)
754762
| SyntaxExtensionKind::LegacyAttr(..)
755763
| SyntaxExtensionKind::NonMacroAttr => MacroKind::Attr,
@@ -1031,6 +1039,13 @@ pub trait ResolverExpand {
10311039

10321040
/// Tools registered with `#![register_tool]` and used by tool attributes and lints.
10331041
fn registered_tools(&self) -> &RegisteredTools;
1042+
1043+
fn expand_legacy_bang(
1044+
&self,
1045+
invoc_id: LocalExpnId,
1046+
span: Span,
1047+
current_expansion: LocalExpnId,
1048+
) -> Result<(TokenStream, usize), CanRetry>;
10341049
}
10351050

10361051
pub trait LintStoreExpand {

compiler/rustc_expand/src/expand.rs

+80-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ use rustc_ast::ptr::P;
1414
use rustc_ast::token::{self, Delimiter};
1515
use rustc_ast::tokenstream::TokenStream;
1616
use rustc_ast::visit::{self, try_visit, walk_list, AssocCtxt, Visitor, VisitorResult};
17-
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind};
17+
use rustc_ast::{
18+
AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind, DUMMY_NODE_ID,
19+
};
1820
use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId};
1921
use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind};
2022
use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind};
@@ -35,11 +37,15 @@ use rustc_span::hygiene::SyntaxContext;
3537
use rustc_span::symbol::{sym, Ident};
3638
use rustc_span::{ErrorGuaranteed, FileName, LocalExpnId, Span};
3739

40+
use crate::mbe::macro_rules::{trace_macros_note, ParserAnyMacro};
41+
use rustc_middle::expand::CanRetry;
42+
use rustc_middle::ty::TyCtxt;
3843
use smallvec::SmallVec;
3944
use std::ops::Deref;
4045
use std::path::PathBuf;
4146
use std::rc::Rc;
4247
use std::{iter, mem};
48+
use tracing::debug;
4349

4450
macro_rules! ast_fragments {
4551
(
@@ -387,6 +393,18 @@ pub struct MacroExpander<'a, 'b> {
387393
monotonic: bool, // cf. `cx.monotonic_expander()`
388394
}
389395

396+
pub fn expand_legacy_bang<'tcx>(
397+
tcx: TyCtxt<'tcx>,
398+
key: (LocalExpnId, Span, LocalExpnId),
399+
) -> Result<(&'tcx TokenStream, usize), CanRetry> {
400+
let (invoc_id, span, current_expansion) = key;
401+
let map = tcx.macro_map.borrow();
402+
let (arg, expander) = map.get(&invoc_id).as_ref().unwrap();
403+
expander
404+
.expand(&tcx.sess, span, arg.clone(), current_expansion)
405+
.map(|(tts, i)| (tcx.arena.alloc(tts) as &TokenStream, i))
406+
}
407+
390408
impl<'a, 'b> MacroExpander<'a, 'b> {
391409
pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self {
392410
MacroExpander { cx, monotonic }
@@ -672,6 +690,67 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
672690
Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
673691
}
674692
}
693+
SyntaxExtensionKind::TcxLegacyBang(expander) => {
694+
// Macros defined in the current crate have a real node id,
695+
// whereas macros from an external crate have a dummy id.
696+
if self.cx.trace_macros() {
697+
let msg = format!(
698+
"expanding `{}! {{ {} }}`",
699+
expander.name(),
700+
pprust::tts_to_string(&mac.args.tokens)
701+
);
702+
trace_macros_note(&mut self.cx.expansions, span, msg);
703+
}
704+
705+
// Macros defined in the current crate have a real node id,
706+
// whereas macros from an external crate have a dummy id.\
707+
let tok_result: Box<dyn MacResult> = match self.cx.resolver.expand_legacy_bang(
708+
invoc.expansion_data.id,
709+
span,
710+
self.cx.current_expansion.id,
711+
) {
712+
Ok((tts, i)) => {
713+
if self.cx.trace_macros() {
714+
let msg = format!("to `{}`", pprust::tts_to_string(&tts));
715+
trace_macros_note(&mut self.cx.expansions, span, msg);
716+
}
717+
let is_local = expander.node_id() != DUMMY_NODE_ID;
718+
if is_local {
719+
self.cx.resolver.record_macro_rule_usage(expander.node_id(), i);
720+
}
721+
722+
// Let the context choose how to interpret the result.
723+
// Weird, but useful for X-macros.
724+
Box::new(ParserAnyMacro::new(
725+
Parser::new(&self.cx.sess.psess, tts.clone(), None),
726+
// Pass along the original expansion site and the name of the macro,
727+
// so we can print a useful error message if the parse of the expanded
728+
// macro leaves unparsed tokens.
729+
span,
730+
expander.name(),
731+
self.cx.current_expansion.lint_node_id,
732+
self.cx.current_expansion.is_trailing_mac,
733+
expander.arm_span(i),
734+
is_local,
735+
))
736+
}
737+
Err(CanRetry::No(guar)) => {
738+
debug!("Will not retry matching as an error was emitted already");
739+
DummyResult::any(span, guar)
740+
}
741+
Err(CanRetry::Yes) => {
742+
// Retry and emit a better error.
743+
DummyResult::any_valid(span)
744+
}
745+
};
746+
let result = if let Some(result) = fragment_kind.make_from(tok_result) {
747+
result
748+
} else {
749+
let guar = self.error_wrong_fragment_kind(fragment_kind, &mac, span);
750+
fragment_kind.dummy(span, guar)
751+
};
752+
result
753+
}
675754
SyntaxExtensionKind::LegacyBang(expander) => {
676755
let tok_result = match expander.expand(self.cx, span, mac.args.tokens.clone()) {
677756
ExpandResult::Ready(tok_result) => tok_result,

compiler/rustc_expand/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@ mod placeholders;
2626
mod proc_macro_server;
2727

2828
pub use mbe::macro_rules::compile_declarative_macro;
29-
pub mod base;
29+
use rustc_middle::query::Providers;pub mod base;
3030
pub mod config;
3131
pub mod expand;
3232
pub mod module;
3333
// FIXME(Nilstrieb) Translate proc_macro diagnostics
3434
#[allow(rustc::untranslatable_diagnostic)]
3535
pub mod proc_macro;
3636

37+
pub fn provide(providers: &mut Providers) {
38+
providers.expand_legacy_bang = expand::expand_legacy_bang;
39+
}
40+
3741
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

compiler/rustc_expand/src/mbe/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use tracing::debug;
1818

1919
use super::macro_rules::{parser_from_cx, NoopTracker};
2020

21-
pub(super) fn failed_to_match_macro<'cx>(
21+
pub(crate) fn failed_to_match_macro<'cx>(
2222
cx: &'cx mut ExtCtxt<'_>,
2323
sp: Span,
2424
def_span: Span,

0 commit comments

Comments
 (0)