Skip to content

Commit ffd82d5

Browse files
Allow for regular comments to be part of the AST and pretty-printed
This commit is merely a test to check if, and by how much, this patch incurs in performance regressions.
1 parent 3ebe60c commit ffd82d5

File tree

30 files changed

+278
-52
lines changed

30 files changed

+278
-52
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3394,6 +3394,9 @@ pub enum AttrKind {
33943394
/// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
33953395
/// variant (which is much less compact and thus more expensive).
33963396
DocComment(CommentKind, Symbol),
3397+
3398+
/// A regular (non-doc) comment.
3399+
Comment(CommentKind, Symbol),
33973400
}
33983401

33993402
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]

compiler/rustc_ast/src/ast_traits.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,16 @@ impl HasTokens for Attribute {
173173
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
174174
match &self.kind {
175175
AttrKind::Normal(normal) => normal.tokens.as_ref(),
176-
kind @ AttrKind::DocComment(..) => {
177-
panic!("Called tokens on doc comment attr {kind:?}")
176+
kind @ (AttrKind::DocComment(..) | AttrKind::Comment(..)) => {
177+
panic!("Called tokens on (doc) comment attr {kind:?}")
178178
}
179179
}
180180
}
181181
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
182182
Some(match &mut self.kind {
183183
AttrKind::Normal(normal) => &mut normal.tokens,
184-
kind @ AttrKind::DocComment(..) => {
185-
panic!("Called tokens_mut on doc comment attr {kind:?}")
184+
kind @ (AttrKind::DocComment(..) | AttrKind::Comment(..)) => {
185+
panic!("Called tokens_mut on (doc) comment attr {kind:?}")
186186
}
187187
})
188188
}

compiler/rustc_ast/src/attr/mod.rs

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl Attribute {
6262
pub fn get_normal_item(&self) -> &AttrItem {
6363
match &self.kind {
6464
AttrKind::Normal(normal) => &normal.item,
65-
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
65+
AttrKind::DocComment(..) | AttrKind::Comment(..) => panic!("unexpected (doc) comment"),
6666
}
6767
}
6868

@@ -71,14 +71,14 @@ impl Attribute {
7171
pub fn replace_args(&mut self, new_args: AttrItemKind) {
7272
match &mut self.kind {
7373
AttrKind::Normal(normal) => normal.item.args = new_args,
74-
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
74+
AttrKind::DocComment(..) | AttrKind::Comment(..) => panic!("unexpected (doc) comment"),
7575
}
7676
}
7777

7878
pub fn unwrap_normal_item(self) -> AttrItem {
7979
match self.kind {
8080
AttrKind::Normal(normal) => normal.item,
81-
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
81+
AttrKind::DocComment(..) | AttrKind::Comment(..) => panic!("unexpected (doc) comment"),
8282
}
8383
}
8484
}
@@ -94,7 +94,7 @@ impl AttributeExt for Attribute {
9494
AttrArgs::Eq { expr, .. } => Some(expr.span),
9595
_ => None,
9696
},
97-
AttrKind::DocComment(..) => None,
97+
AttrKind::DocComment(..) | AttrKind::Comment(..) => None,
9898
}
9999
}
100100

@@ -103,7 +103,7 @@ impl AttributeExt for Attribute {
103103
/// a doc comment) will return `false`.
104104
fn is_doc_comment(&self) -> Option<Span> {
105105
match self.kind {
106-
AttrKind::Normal(..) => None,
106+
AttrKind::Normal(..) | AttrKind::Comment(..) => None,
107107
AttrKind::DocComment(..) => Some(self.span),
108108
}
109109
}
@@ -118,7 +118,7 @@ impl AttributeExt for Attribute {
118118
None
119119
}
120120
}
121-
AttrKind::DocComment(..) => None,
121+
AttrKind::DocComment(..) | AttrKind::Comment(..) => None,
122122
}
123123
}
124124

@@ -127,14 +127,14 @@ impl AttributeExt for Attribute {
127127
AttrKind::Normal(p) => {
128128
Some(p.item.path.segments.iter().map(|i| i.ident.name).collect())
129129
}
130-
AttrKind::DocComment(_, _) => None,
130+
AttrKind::DocComment(_, _) | AttrKind::Comment(_, _) => None,
131131
}
132132
}
133133

134134
fn path_span(&self) -> Option<Span> {
135135
match &self.kind {
136136
AttrKind::Normal(attr) => Some(attr.item.path.span),
137-
AttrKind::DocComment(_, _) => None,
137+
AttrKind::DocComment(_, _) | AttrKind::Comment(_, _) => None,
138138
}
139139
}
140140

@@ -150,7 +150,7 @@ impl AttributeExt for Attribute {
150150
.zip(name)
151151
.all(|(s, n)| s.args.is_none() && s.ident.name == *n)
152152
}
153-
AttrKind::DocComment(..) => false,
153+
AttrKind::DocComment(..) | AttrKind::Comment(..) => false,
154154
}
155155
}
156156

@@ -176,7 +176,7 @@ impl AttributeExt for Attribute {
176176
fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
177177
match &self.kind {
178178
AttrKind::Normal(normal) => normal.item.meta_item_list(),
179-
AttrKind::DocComment(..) => None,
179+
AttrKind::DocComment(..) | AttrKind::Comment(..) => None,
180180
}
181181
}
182182

@@ -198,7 +198,7 @@ impl AttributeExt for Attribute {
198198
fn value_str(&self) -> Option<Symbol> {
199199
match &self.kind {
200200
AttrKind::Normal(normal) => normal.item.value_str(),
201-
AttrKind::DocComment(..) => None,
201+
AttrKind::DocComment(..) | AttrKind::Comment(..) => None,
202202
}
203203
}
204204

@@ -266,6 +266,7 @@ impl AttributeExt for Attribute {
266266
fn doc_resolution_scope(&self) -> Option<AttrStyle> {
267267
match &self.kind {
268268
AttrKind::DocComment(..) => Some(self.style),
269+
AttrKind::Comment(..) => None,
269270
AttrKind::Normal(normal)
270271
if normal.item.path == sym::doc && normal.item.value_str().is_some() =>
271272
{
@@ -307,6 +308,11 @@ impl Attribute {
307308
self.style
308309
}
309310

311+
/// Returns `true` if this is a regular (non-doc) comment (`//` or `/* */`).
312+
pub fn is_comment(&self) -> bool {
313+
matches!(self.kind, AttrKind::Comment(..))
314+
}
315+
310316
pub fn may_have_doc_links(&self) -> bool {
311317
self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
312318
|| self.deprecation_note().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
@@ -316,14 +322,14 @@ impl Attribute {
316322
pub fn meta(&self) -> Option<MetaItem> {
317323
match &self.kind {
318324
AttrKind::Normal(normal) => normal.item.meta(self.span),
319-
AttrKind::DocComment(..) => None,
325+
AttrKind::DocComment(..) | AttrKind::Comment(..) => None,
320326
}
321327
}
322328

323329
pub fn meta_kind(&self) -> Option<MetaItemKind> {
324330
match &self.kind {
325331
AttrKind::Normal(normal) => normal.item.meta_kind(),
326-
AttrKind::DocComment(..) => None,
332+
AttrKind::DocComment(..) | AttrKind::Comment(..) => None,
327333
}
328334
}
329335

@@ -339,6 +345,9 @@ impl Attribute {
339345
token::DocComment(comment_kind, self.style, data),
340346
self.span,
341347
)],
348+
// Regular comments are never part of any real token stream; returning
349+
// an empty vec prevents them from being injected into macro inputs.
350+
AttrKind::Comment(..) => vec![],
342351
}
343352
}
344353
}
@@ -737,6 +746,20 @@ pub fn mk_doc_comment(
737746
Attribute { kind: AttrKind::DocComment(comment_kind, data), id: g.mk_attr_id(), style, span }
738747
}
739748

749+
pub fn mk_comment(
750+
g: &AttrIdGenerator,
751+
comment_kind: CommentKind,
752+
data: Symbol,
753+
span: Span,
754+
) -> Attribute {
755+
Attribute {
756+
kind: AttrKind::Comment(comment_kind, data),
757+
id: g.mk_attr_id(),
758+
style: AttrStyle::Outer,
759+
span,
760+
}
761+
}
762+
740763
fn mk_attr(
741764
g: &AttrIdGenerator,
742765
style: AttrStyle,

compiler/rustc_ast/src/token.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ pub enum TokenKind {
524524
/// similarly to symbols in string literal tokens.
525525
DocComment(CommentKind, ast::AttrStyle, Symbol),
526526

527+
/// A regular (non-doc) comment token.
528+
/// `Symbol` is the comment's data excluding its delimiters (`//`, `/*`, `*/`).
529+
Comment(CommentKind, Symbol),
530+
527531
/// End Of File
528532
Eof,
529533
}
@@ -654,8 +658,8 @@ impl Token {
654658
| FatArrow | Pound | Dollar | Question | SingleQuote => true,
655659

656660
OpenParen | CloseParen | OpenBrace | CloseBrace | OpenBracket | CloseBracket
657-
| OpenInvisible(_) | CloseInvisible(_) | Literal(..) | DocComment(..) | Ident(..)
658-
| NtIdent(..) | Lifetime(..) | NtLifetime(..) | Eof => false,
661+
| OpenInvisible(_) | CloseInvisible(_) | Literal(..) | DocComment(..) | Comment(..)
662+
| Ident(..) | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Eof => false,
659663
}
660664
}
661665

@@ -1072,7 +1076,7 @@ impl Token {
10721076
| Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question
10731077
| OpenParen | CloseParen | OpenBrace | CloseBrace | OpenBracket | CloseBracket
10741078
| OpenInvisible(_) | CloseInvisible(_) | Literal(..) | Ident(..) | NtIdent(..)
1075-
| Lifetime(..) | NtLifetime(..) | DocComment(..) | Eof,
1079+
| Lifetime(..) | NtLifetime(..) | DocComment(..) | Comment(..) | Eof,
10761080
_,
10771081
) => {
10781082
return None;

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,22 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
696696
));
697697
self.hardbreak()
698698
}
699+
ast::AttrKind::Comment(comment_kind, data) => {
700+
// Printing here too would duplicate every comment.
701+
// Only emit from the AST attribute when there is no source text available.
702+
if self.comments().is_some() {
703+
return false;
704+
}
705+
match comment_kind {
706+
ast::token::CommentKind::Line => {
707+
self.word(format!("//{}", data));
708+
}
709+
ast::token::CommentKind::Block => {
710+
self.word(format!("/*{}*/", data));
711+
}
712+
}
713+
self.hardbreak()
714+
}
699715
}
700716
true
701717
}
@@ -1095,6 +1111,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
10951111
doc_comment_to_string(DocFragmentKind::Sugared(comment_kind), attr_style, data)
10961112
.into()
10971113
}
1114+
token::Comment(comment_kind, data) => match comment_kind {
1115+
token::CommentKind::Line => format!("//{data}").into(),
1116+
token::CommentKind::Block => format!("/*{data}*/").into(),
1117+
},
10981118
token::Eof => "<eof>".into(),
10991119
}
11001120
}

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ impl<'a> State<'a> {
420420
// let _ = add_attr!(1 + 1);
421421
//
422422
// We must pretty-print `#[attr] (1 + 1)` not `#[attr] 1 + 1`.
423-
!attrs.is_empty()
423+
attrs.iter().any(|a| !a.is_comment())
424424
&& matches!(
425425
expr.kind,
426426
ast::ExprKind::Binary(..)

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
311311
comment: *symbol,
312312
}));
313313
}
314+
// Regular comments have no semantic meaning
315+
// for attribute parsing; skip them.
316+
ast::AttrKind::Comment(..) => continue,
314317
ast::AttrKind::Normal(n) => {
315318
attr_paths.push(PathParser(&n.item.path));
316319
let attr_path = AttrPath::from_ast(&n.item.path, lower_span);

compiler/rustc_attr_parsing/src/validate_attr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ use rustc_span::{Span, Symbol, sym};
2222
use crate::{AttributeParser, Late, session_diagnostics as errors};
2323

2424
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
25-
if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace)
25+
if attr.is_doc_comment()
26+
|| attr.is_comment()
27+
|| attr.has_name(sym::cfg_trace)
28+
|| attr.has_name(sym::cfg_attr_trace)
2629
{
2730
return;
2831
}

compiler/rustc_builtin_macros/src/asm.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ fn validate_asm_args<'a>(
6464

6565
for arg in args {
6666
for attr in arg.attributes.0.iter() {
67+
// FIXME: can we simply skip them?
68+
if attr.is_comment() {
69+
continue;
70+
}
6771
if !matches!(attr.name(), Some(sym::cfg | sym::cfg_attr)) {
6872
ecx.dcx().emit_err(errors::AsmAttributeNotSupported { span: attr.span() });
6973
}

compiler/rustc_expand/src/config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub(crate) fn attr_into_trace(mut attr: Attribute, trace_name: Symbol) -> Attrib
167167
// This makes the trace attributes unobservable to token-based proc macros.
168168
*tokens = Some(LazyAttrTokenStream::new_direct(AttrTokenStream::default()));
169169
}
170-
AttrKind::DocComment(..) => unreachable!(),
170+
AttrKind::DocComment(..) | AttrKind::Comment(..) => unreachable!(),
171171
}
172172
attr
173173
}
@@ -415,6 +415,10 @@ impl<'a> StripUnconfigured<'a> {
415415
/// If attributes are not allowed on expressions, emit an error for `attr`
416416
#[instrument(level = "trace", skip(self))]
417417
pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
418+
// Regular comments are never "real" attributes.
419+
if attr.is_comment() {
420+
return;
421+
}
418422
if self.features.is_some_and(|features| !features.stmt_expr_attributes())
419423
&& !attr.span.allows_unstable(sym::stmt_expr_attributes)
420424
{

0 commit comments

Comments
 (0)