Skip to content

Commit ece5ebe

Browse files
Auto merge of #145354 - Kobzol:cache-proc-derive-macros, r=<try>
Cache derive proc macro expansion with incremental query
2 parents a2c8b0b + 8540970 commit ece5ebe

File tree

18 files changed

+300
-75
lines changed

18 files changed

+300
-75
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,11 +3748,13 @@ dependencies = [
37483748
"rustc_lexer",
37493749
"rustc_lint_defs",
37503750
"rustc_macros",
3751+
"rustc_middle",
37513752
"rustc_parse",
37523753
"rustc_proc_macro",
37533754
"rustc_serialize",
37543755
"rustc_session",
37553756
"rustc_span",
3757+
"scoped-tls",
37563758
"smallvec",
37573759
"thin-vec",
37583760
"tracing",

compiler/rustc_ast/src/ast.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3243,7 +3243,18 @@ impl UseTree {
32433243
/// Distinguishes between `Attribute`s that decorate items and Attributes that
32443244
/// are contained as statements within items. These two cases need to be
32453245
/// distinguished for pretty-printing.
3246-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3246+
#[derive(
3247+
Clone,
3248+
PartialEq,
3249+
Eq,
3250+
Encodable,
3251+
Decodable,
3252+
Hash,
3253+
Debug,
3254+
Copy,
3255+
HashStable_Generic,
3256+
Walkable
3257+
)]
32473258
pub enum AttrStyle {
32483259
Outer,
32493260
Inner,

compiler/rustc_ast/src/token.rs

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@ use rustc_span::{Ident, Symbol};
1616
use crate::ast;
1717
use crate::util::case::Case;
1818

19-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
19+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)]
2020
pub enum CommentKind {
2121
Line,
2222
Block,
2323
}
2424

25-
// This type must not implement `Hash` due to the unusual `PartialEq` impl below.
26-
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
25+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
2726
pub enum InvisibleOrigin {
2827
// From the expansion of a metavariable in a declarative macro.
2928
MetaVar(MetaVarKind),
@@ -45,20 +44,6 @@ impl InvisibleOrigin {
4544
}
4645
}
4746

48-
impl PartialEq for InvisibleOrigin {
49-
#[inline]
50-
fn eq(&self, _other: &InvisibleOrigin) -> bool {
51-
// When we had AST-based nonterminals we couldn't compare them, and the
52-
// old `Nonterminal` type had an `eq` that always returned false,
53-
// resulting in this restriction:
54-
// https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment
55-
// This `eq` emulates that behaviour. We could consider lifting this
56-
// restriction now but there are still cases involving invisible
57-
// delimiters that make it harder than it first appears.
58-
false
59-
}
60-
}
61-
6247
/// Annoyingly similar to `NonterminalKind`, but the slight differences are important.
6348
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
6449
pub enum MetaVarKind {
@@ -114,7 +99,7 @@ impl fmt::Display for MetaVarKind {
11499
/// Describes how a sequence of token trees is delimited.
115100
/// Cannot use `proc_macro::Delimiter` directly because this
116101
/// structure should implement some additional traits.
117-
#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
102+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
118103
pub enum Delimiter {
119104
/// `( ... )`
120105
Parenthesis,
@@ -142,7 +127,8 @@ impl Delimiter {
142127
}
143128
}
144129

145-
// This exists because `InvisibleOrigin`s should be compared. It is only used for assertions.
130+
// This exists because `InvisibleOrigin`s should not be compared. It is only used for
131+
// assertions.
146132
pub fn eq_ignoring_invisible_origin(&self, other: &Delimiter) -> bool {
147133
match (self, other) {
148134
(Delimiter::Parenthesis, Delimiter::Parenthesis) => true,
@@ -176,7 +162,7 @@ impl Delimiter {
176162
// type. This means that float literals like `1f32` are classified by this type
177163
// as `Int`. Only upon conversion to `ast::LitKind` will such a literal be
178164
// given the `Float` kind.
179-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
165+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)]
180166
pub enum LitKind {
181167
Bool, // AST only, must never appear in a `Token`
182168
Byte,
@@ -193,7 +179,7 @@ pub enum LitKind {
193179
}
194180

195181
/// A literal token.
196-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
182+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)]
197183
pub struct Lit {
198184
pub kind: LitKind,
199185
pub symbol: Symbol,
@@ -339,7 +325,7 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: IdentIsRaw) -> bool {
339325
.contains(&name)
340326
}
341327

342-
#[derive(PartialEq, Encodable, Decodable, Debug, Copy, Clone, HashStable_Generic)]
328+
#[derive(PartialEq, Eq, Encodable, Decodable, Hash, Debug, Copy, Clone, HashStable_Generic)]
343329
pub enum IdentIsRaw {
344330
No,
345331
Yes,
@@ -366,7 +352,7 @@ impl From<bool> for IdentIsRaw {
366352
}
367353
}
368354

369-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
355+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)]
370356
pub enum TokenKind {
371357
/* Expression-operator symbols. */
372358
/// `=`
@@ -516,7 +502,7 @@ pub enum TokenKind {
516502
Eof,
517503
}
518504

519-
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
505+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)]
520506
pub struct Token {
521507
pub kind: TokenKind,
522508
pub span: Span,

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! which are themselves a single [`Token`] or a `Delimited` subsequence of tokens.
66
77
use std::borrow::Cow;
8+
use std::hash::Hash;
89
use std::ops::Range;
910
use std::sync::Arc;
1011
use std::{cmp, fmt, iter, mem};
@@ -22,7 +23,7 @@ use crate::token::{self, Delimiter, Token, TokenKind};
2223
use crate::{AttrVec, Attribute};
2324

2425
/// Part of a `TokenStream`.
25-
#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
26+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2627
pub enum TokenTree {
2728
/// A single token. Should never be `OpenDelim` or `CloseDelim`, because
2829
/// delimiters are implicitly represented by `Delimited`.
@@ -540,7 +541,7 @@ pub struct AttrsTarget {
540541
/// compound token. Used for conversions to `proc_macro::Spacing`. Also used to
541542
/// guide pretty-printing, which is where the `JointHidden` value (which isn't
542543
/// part of `proc_macro::Spacing`) comes in useful.
543-
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
544+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
544545
pub enum Spacing {
545546
/// The token cannot join with the following token to form a compound
546547
/// token.
@@ -597,7 +598,7 @@ pub enum Spacing {
597598
}
598599

599600
/// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s.
600-
#[derive(Clone, Debug, Default, Encodable, Decodable)]
601+
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Encodable, Decodable)]
601602
pub struct TokenStream(pub(crate) Arc<Vec<TokenTree>>);
602603

603604
impl TokenStream {
@@ -813,14 +814,6 @@ impl TokenStream {
813814
}
814815
}
815816

816-
impl PartialEq<TokenStream> for TokenStream {
817-
fn eq(&self, other: &TokenStream) -> bool {
818-
self.iter().eq(other.iter())
819-
}
820-
}
821-
822-
impl Eq for TokenStream {}
823-
824817
impl FromIterator<TokenTree> for TokenStream {
825818
fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self {
826819
TokenStream::new(iter.into_iter().collect::<Vec<TokenTree>>())
@@ -972,7 +965,18 @@ impl TokenCursor {
972965
}
973966
}
974967

975-
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
968+
#[derive(
969+
Debug,
970+
Copy,
971+
Clone,
972+
PartialEq,
973+
Eq,
974+
Hash,
975+
Encodable,
976+
Decodable,
977+
HashStable_Generic,
978+
Walkable
979+
)]
976980
pub struct DelimSpan {
977981
pub open: Span,
978982
pub close: Span,
@@ -996,7 +1000,7 @@ impl DelimSpan {
9961000
}
9971001
}
9981002

999-
#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1003+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
10001004
pub struct DelimSpacing {
10011005
pub open: Spacing,
10021006
pub close: Spacing,

compiler/rustc_expand/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ rustc_hir = { path = "../rustc_hir" }
2121
rustc_lexer = { path = "../rustc_lexer" }
2222
rustc_lint_defs = { path = "../rustc_lint_defs" }
2323
rustc_macros = { path = "../rustc_macros" }
24+
rustc_middle = { path = "../rustc_middle" }
2425
rustc_parse = { path = "../rustc_parse" }
2526
# We must use the proc_macro version that we will compile proc-macros against,
2627
# not the one from our own sysroot.
2728
rustc_proc_macro = { path = "../rustc_proc_macro" }
2829
rustc_serialize = { path = "../rustc_serialize" }
2930
rustc_session = { path = "../rustc_session" }
3031
rustc_span = { path = "../rustc_span" }
32+
scoped-tls = "1.0"
3133
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
3234
thin-vec = "0.2.12"
3335
tracing = "0.1"

compiler/rustc_expand/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ pub mod module;
3131
#[allow(rustc::untranslatable_diagnostic)]
3232
pub mod proc_macro;
3333

34+
pub fn provide(providers: &mut rustc_middle::util::Providers) {
35+
providers.derive_macro_expansion = proc_macro::provide_derive_macro_expansion;
36+
}
37+
3438
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

compiler/rustc_expand/src/mbe/macro_parser.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use std::rc::Rc;
7777

7878
pub(crate) use NamedMatch::*;
7979
pub(crate) use ParseResult::*;
80-
use rustc_ast::token::{self, DocComment, NonterminalKind, Token};
80+
use rustc_ast::token::{self, DocComment, NonterminalKind, Token, TokenKind};
8181
use rustc_data_structures::fx::FxHashMap;
8282
use rustc_errors::ErrorGuaranteed;
8383
use rustc_lint_defs::pluralize;
@@ -397,7 +397,23 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
397397
{
398398
ident1.name == ident2.name && is_raw1 == is_raw2
399399
} else {
400-
t1.kind == t2.kind
400+
// Note: we SHOULD NOT use `t1.kind == t2.kind` here, and we should instead compare the
401+
// tokens using the special comparison logic below.
402+
// It makes sure that variants containing `InvisibleOrigin` will
403+
// never compare equal to one another.
404+
//
405+
// When we had AST-based nonterminals we couldn't compare them, and the
406+
// old `Nonterminal` type had an `eq` that always returned false,
407+
// resulting in this restriction:
408+
// <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment>
409+
// This comparison logic emulates that behaviour. We could consider lifting this
410+
// restriction now but there are still cases involving invisible
411+
// delimiters that make it harder than it first appears.
412+
match (t1.kind, t2.kind) {
413+
(TokenKind::OpenInvisible(_) | TokenKind::CloseInvisible(_), _)
414+
| (_, TokenKind::OpenInvisible(_) | TokenKind::CloseInvisible(_)) => false,
415+
(a, b) => a == b,
416+
}
401417
}
402418
}
403419

0 commit comments

Comments
 (0)