about summary refs log tree commit diff
path: root/compiler/rustc_expand/src/config.rs
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-07-24 20:29:28 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2024-07-24 21:03:52 +1000
commitac26b883bf3824de42e7adbf0fa69e24f2586ddf (patch)
tree83099ceb7cdefd601b0f4874647f2558d5178285 /compiler/rustc_expand/src/config.rs
parent08a9ca7c18a30a23a72a43b65be616c9a6a36a5a (diff)
downloadrust-ac26b883bf3824de42e7adbf0fa69e24f2586ddf.tar.gz
rust-ac26b883bf3824de42e7adbf0fa69e24f2586ddf.zip
Improve spans on evaluated `cfg_attr`s.
When converting something like `#![cfg_attr(cond, attr)]` into
`#![attr]`, we currently duplicate the `#` token and the `!` token. But
weirdly, there is also this comment:

// We don't really have a good span to use for the synthesized `[]`
// in `#[attr]`, so just use the span of the `#` token.

Maybe that comment used to be true? But now it is false: we can
duplicate the existing delimiters (and their spans and spacing), much
like we do for the `#` and `!`.

This commit does that, thus removing the incorrect comment, and
improving the spans on `Group`s in a few proc-macro tests.
Diffstat (limited to 'compiler/rustc_expand/src/config.rs')
-rw-r--r--compiler/rustc_expand/src/config.rs56
1 files changed, 28 insertions, 28 deletions
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 9da4aa84db5..6c02c237115 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -6,7 +6,7 @@ use crate::errors::{
 };
 use rustc_ast::ptr::P;
 use rustc_ast::token::{Delimiter, Token, TokenKind};
-use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, DelimSpacing, DelimSpan, Spacing};
+use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, Spacing};
 use rustc_ast::tokenstream::{LazyAttrTokenStream, TokenTree};
 use rustc_ast::NodeId;
 use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem};
@@ -298,47 +298,47 @@ impl<'a> StripUnconfigured<'a> {
         cfg_attr: &Attribute,
         (item, item_span): (ast::AttrItem, Span),
     ) -> Attribute {
-        // We are taking an attribute of the form `#[cfg_attr(pred, attr)]`
-        // and producing an attribute of the form `#[attr]`. We
-        // have captured tokens for `attr` itself, but we need to
-        // synthesize tokens for the wrapper `#` and `[]`, which
-        // we do below.
-
-        // Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
-        // for `attr` when we expand it to `#[attr]`
+        // Convert `#[cfg_attr(pred, attr)]` to `#[attr]`.
+
+        // Use the `#` from `#[cfg_attr(pred, attr)]` in the result `#[attr]`.
         let mut orig_trees = cfg_attr.token_trees().into_iter();
-        let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }, _) =
-            orig_trees.next().unwrap().clone()
+        let Some(TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }, _)) =
+            orig_trees.next()
         else {
             panic!("Bad tokens for attribute {cfg_attr:?}");
         };
 
-        // We don't really have a good span to use for the synthesized `[]`
-        // in `#[attr]`, so just use the span of the `#` token.
-        let bracket_group = AttrTokenTree::Delimited(
-            DelimSpan::from_single(pound_token.span),
-            DelimSpacing::new(Spacing::JointHidden, Spacing::Alone),
-            Delimiter::Bracket,
-            item.tokens
-                .as_ref()
-                .unwrap_or_else(|| panic!("Missing tokens for {item:?}"))
-                .to_attr_token_stream(),
-        );
-        let trees = if cfg_attr.style == AttrStyle::Inner {
-            // For inner attributes, we do the same thing for the `!` in `#![some_attr]`
-            let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) =
-                orig_trees.next().unwrap().clone()
+        // For inner attributes, we do the same thing for the `!` in `#![attr]`.
+        let mut trees = if cfg_attr.style == AttrStyle::Inner {
+            let Some(TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _)) =
+                orig_trees.next()
             else {
                 panic!("Bad tokens for attribute {cfg_attr:?}");
             };
             vec![
                 AttrTokenTree::Token(pound_token, Spacing::Joint),
                 AttrTokenTree::Token(bang_token, Spacing::JointHidden),
-                bracket_group,
             ]
         } else {
-            vec![AttrTokenTree::Token(pound_token, Spacing::JointHidden), bracket_group]
+            vec![AttrTokenTree::Token(pound_token, Spacing::JointHidden)]
         };
+
+        // And the same thing for the `[`/`]` delimiters in `#[attr]`.
+        let Some(TokenTree::Delimited(delim_span, delim_spacing, Delimiter::Bracket, _)) =
+            orig_trees.next()
+        else {
+            panic!("Bad tokens for attribute {cfg_attr:?}");
+        };
+        trees.push(AttrTokenTree::Delimited(
+            delim_span,
+            delim_spacing,
+            Delimiter::Bracket,
+            item.tokens
+                .as_ref()
+                .unwrap_or_else(|| panic!("Missing tokens for {item:?}"))
+                .to_attr_token_stream(),
+        ));
+
         let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees)));
         let attr = attr::mk_attr_from_item(
             &self.sess.psess.attr_id_generator,