From 81163b8cd4a03ac0d37807e02de20ad2605e26dd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 7 Jan 2022 18:51:10 +0100 Subject: [PATCH] fix: Fix attribute stripping ignoring doc comments --- crates/hir/src/lib.rs | 13 ++++++++----- crates/hir_expand/src/db.rs | 11 ++++++++--- crates/hir_expand/src/hygiene.rs | 9 +++++++-- crates/hir_expand/src/lib.rs | 19 +++++++++++-------- crates/syntax/src/ast/node_ext.rs | 1 + 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c6d401a6d6..ec8349cfde 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -68,7 +68,7 @@ use once_cell::unsync::Lazy; use rustc_hash::FxHashSet; use stdx::{format_to, impl_from}; use syntax::{ - ast::{self, HasAttrs as _, HasName}, + ast::{self, HasAttrs as _, HasDocComments, HasName}, AstNode, AstPtr, SmolStr, SyntaxKind, SyntaxNodePtr, }; use tt::{Ident, Leaf, Literal, TokenTree}; @@ -612,10 +612,13 @@ impl Module { } MacroCallKind::Attr { ast_id, invoc_attr_index, attr_name, .. } => { let node = ast_id.to_node(db.upcast()); - let attr = - node.attrs().nth((*invoc_attr_index) as usize).unwrap_or_else( - || panic!("cannot find attribute #{}", invoc_attr_index), - ); + let attr = node + .doc_comments_and_attrs() + .nth((*invoc_attr_index) as usize) + .and_then(Either::right) + .unwrap_or_else(|| { + panic!("cannot find attribute #{}", invoc_attr_index) + }); ( ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))), Some(attr_name.clone()), diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index c88b5639f0..c39825b591 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -3,12 +3,13 @@ use std::sync::Arc; use base_db::{salsa, SourceDatabase}; +use either::Either; use limit::Limit; use mbe::{syntax_node_to_token_tree, ExpandError, ExpandResult}; use rustc_hash::FxHashSet; use syntax::{ algo::diff, - ast::{self, HasAttrs}, + ast::{self, HasAttrs, HasDocComments}, AstNode, GreenNode, Parse, SyntaxNode, SyntaxToken, T, }; @@ -153,7 +154,10 @@ pub fn expand_speculative( // Attributes may have an input token tree, build the subtree and map for this as well // then try finding a token id for our token if it is inside this input subtree. let item = ast::Item::cast(speculative_args.clone())?; - let attr = item.attrs().nth(invoc_attr_index as usize)?; + let attr = item + .doc_comments_and_attrs() + .nth(invoc_attr_index as usize) + .and_then(Either::right)?; match attr.token_tree() { Some(token_tree) => { let (mut tree, map) = syntax_node_to_token_tree(attr.token_tree()?.syntax()); @@ -328,8 +332,9 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet { cov_mark::hit!(attribute_macro_attr_censoring); ast::Item::cast(node.clone())? - .attrs() + .doc_comments_and_attrs() .nth(invoc_attr_index as usize) + .and_then(Either::right) .map(|attr| attr.syntax().clone()) .into_iter() .collect() diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index e74c705217..d7dc0443b2 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs @@ -9,7 +9,7 @@ use db::TokenExpander; use either::Either; use mbe::Origin; use syntax::{ - ast::{self, HasAttrs}, + ast::{self, HasDocComments}, AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize, }; @@ -187,7 +187,12 @@ fn make_hygiene_info( }); let attr_input_or_mac_def = def.or_else(|| match loc.kind { MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => { - let tt = ast_id.to_node(db).attrs().nth(invoc_attr_index as usize)?.token_tree()?; + let tt = ast_id + .to_node(db) + .doc_comments_and_attrs() + .nth(invoc_attr_index as usize) + .and_then(Either::right)? + .token_tree()?; Some(InFile::new(ast_id.file_id, tt)) } _ => None, diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 3e2e1ba630..5f190b8727 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -25,7 +25,7 @@ use std::{hash::Hash, iter, sync::Arc}; use base_db::{impl_intern_key, salsa, CrateId, FileId, FileRange}; use syntax::{ algo::{self, skip_trivia_token}, - ast::{self, AstNode, HasAttrs}, + ast::{self, AstNode, HasDocComments}, Direction, SyntaxNode, SyntaxToken, }; @@ -201,8 +201,9 @@ impl HirFileId { MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => { let tt = ast_id .to_node(db) - .attrs() - .nth(invoc_attr_index as usize)? + .doc_comments_and_attrs() + .nth(invoc_attr_index as usize) + .and_then(Either::right)? .token_tree()?; Some(InFile::new(ast_id.file_id, tt)) } @@ -429,8 +430,11 @@ impl ExpansionInfo { let token_range = token.value.text_range(); match &loc.kind { - MacroCallKind::Attr { attr_args, invoc_attr_index, .. } => { - let attr = item.attrs().nth(*invoc_attr_index as usize)?; + MacroCallKind::Attr { attr_args: (_, map), invoc_attr_index, .. } => { + let attr = item + .doc_comments_and_attrs() + .nth(*invoc_attr_index as usize) + .and_then(Either::right)?; match attr.token_tree() { Some(token_tree) if token_tree.syntax().text_range().contains_range(token_range) => @@ -440,9 +444,8 @@ impl ExpansionInfo { let relative_range = token.value.text_range().checked_sub(attr_input_start)?; // shift by the item's tree's max id - let token_id = self - .macro_arg_shift - .shift(attr_args.1.token_by_range(relative_range)?); + let token_id = + self.macro_arg_shift.shift(map.token_by_range(relative_range)?); Some(token_id) } _ => None, diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 705aa5edac..470e9a04b3 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -772,6 +772,7 @@ impl ast::HasLoopBody for ast::ForExpr { } impl ast::HasAttrs for ast::AnyHasDocComments {} +impl ast::HasDocComments for ast::Item {} impl From for ast::Item { fn from(it: ast::Adt) -> Self {