Skip to content

Commit 2aa7f2e

Browse files
bors[bot]Veykril
andauthored
Merge #6750
6750: Remove documentation query, move doc handling to attributes r=matklad a=Veykril Fixes #3182 Removes the documentation query in favor of `Attrs::docs`. Attrs already handlded doc comments partially but the alloc saving check was wrong so it only worked when other attributes existed as well. Unfortunately the `new` constructor has to do an intermediate allocation now because we need to keep the order of mixed doc attributes and doc comments. I've also partially adjusted the `hover` module to have its tests check the changes, it still has some `HasSource` trait usage due to the `ShortLabel` trait usage, as that is only implemented on the Ast parts and not the Hir, should this ideally be implemented for the Hir types as well?(would be a follow up PR of course) Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 4d4f119 + 3174e94 commit 2aa7f2e

File tree

12 files changed

+137
-213
lines changed

12 files changed

+137
-213
lines changed

crates/hir/src/attrs.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Attributes & documentation for hir types.
22
use hir_def::{
3-
attr::Attrs, docs::Documentation, path::ModPath, resolver::HasResolver, AttrDefId, ModuleDefId,
3+
attr::{Attrs, Documentation},
4+
path::ModPath,
5+
resolver::HasResolver,
6+
AttrDefId, ModuleDefId,
47
};
58
use hir_expand::hygiene::Hygiene;
69
use hir_ty::db::HirDatabase;
@@ -38,7 +41,7 @@ macro_rules! impl_has_attrs {
3841
}
3942
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
4043
let def = AttrDefId::$def_id(self.into());
41-
db.documentation(def)
44+
db.attrs(def).docs()
4245
}
4346
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
4447
let def = AttrDefId::$def_id(self.into());

crates/hir/src/db.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
33
pub use hir_def::db::{
44
AttrsQuery, BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQueryQuery,
5-
CrateLangItemsQuery, DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery,
6-
ExprScopesQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery,
7-
InternConstQuery, InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery,
8-
InternImplQuery, InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery,
9-
InternUnionQuery, ItemTreeQuery, LangItemQuery, ModuleLangItemsQuery, StaticDataQuery,
10-
StructDataQuery, TraitDataQuery, TypeAliasDataQuery, UnionDataQuery,
5+
CrateLangItemsQuery, DefDatabase, DefDatabaseStorage, EnumDataQuery, ExprScopesQuery,
6+
FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery, InternConstQuery,
7+
InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery, InternImplQuery,
8+
InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery, InternUnionQuery,
9+
ItemTreeQuery, LangItemQuery, ModuleLangItemsQuery, StaticDataQuery, StructDataQuery,
10+
TraitDataQuery, TypeAliasDataQuery, UnionDataQuery,
1111
};
1212
pub use hir_expand::db::{
1313
AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,

crates/hir/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ pub use crate::{
4444

4545
pub use hir_def::{
4646
adt::StructKind,
47-
attr::Attrs,
47+
attr::{Attrs, Documentation},
4848
body::scope::ExprScopes,
4949
builtin_type::BuiltinType,
50-
docs::Documentation,
5150
find_path::PrefixKind,
5251
import_map,
5352
item_scope::ItemInNs,

crates/hir_def/src/attr.rs

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use std::{ops, sync::Arc};
55
use cfg::{CfgExpr, CfgOptions};
66
use either::Either;
77
use hir_expand::{hygiene::Hygiene, AstId, InFile};
8+
use itertools::Itertools;
89
use mbe::ast_to_token_tree;
910
use syntax::{
1011
ast::{self, AstNode, AttrsOwner},
11-
SmolStr,
12+
AstToken, SmolStr,
1213
};
1314
use tt::Subtree;
1415

@@ -21,6 +22,22 @@ use crate::{
2122
AdtId, AttrDefId, Lookup,
2223
};
2324

25+
/// Holds documentation
26+
#[derive(Debug, Clone, PartialEq, Eq)]
27+
pub struct Documentation(String);
28+
29+
impl Documentation {
30+
pub fn as_str(&self) -> &str {
31+
&self.0
32+
}
33+
}
34+
35+
impl Into<String> for Documentation {
36+
fn into(self) -> String {
37+
self.0
38+
}
39+
}
40+
2441
#[derive(Default, Debug, Clone, PartialEq, Eq)]
2542
pub struct Attrs {
2643
entries: Option<Arc<[Attr]>>,
@@ -93,18 +110,25 @@ impl Attrs {
93110
}
94111

95112
pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
96-
let docs = ast::CommentIter::from_syntax_node(owner.syntax()).doc_comment_text().map(
97-
|docs_text| Attr {
98-
input: Some(AttrInput::Literal(SmolStr::new(docs_text))),
99-
path: ModPath::from(hir_expand::name!(doc)),
100-
},
101-
);
102-
let mut attrs = owner.attrs().peekable();
103-
let entries = if attrs.peek().is_none() {
113+
let docs = ast::CommentIter::from_syntax_node(owner.syntax()).map(|docs_text| {
114+
(
115+
docs_text.syntax().text_range().start(),
116+
docs_text.doc_comment().map(|doc| Attr {
117+
input: Some(AttrInput::Literal(SmolStr::new(doc))),
118+
path: ModPath::from(hir_expand::name!(doc)),
119+
}),
120+
)
121+
});
122+
let attrs = owner
123+
.attrs()
124+
.map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
125+
// sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
126+
let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
127+
let entries = if attrs.is_empty() {
104128
// Avoid heap allocation
105129
None
106130
} else {
107-
Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).chain(docs).collect())
131+
Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect())
108132
};
109133
Attrs { entries }
110134
}
@@ -140,6 +164,24 @@ impl Attrs {
140164
Some(cfg) => cfg_options.check(&cfg) != Some(false),
141165
}
142166
}
167+
168+
pub fn docs(&self) -> Option<Documentation> {
169+
let docs = self
170+
.by_key("doc")
171+
.attrs()
172+
.flat_map(|attr| match attr.input.as_ref()? {
173+
AttrInput::Literal(s) => Some(s),
174+
AttrInput::TokenTree(_) => None,
175+
})
176+
.intersperse(&SmolStr::new_inline("\n"))
177+
.map(|it| it.as_str())
178+
.collect::<String>();
179+
if docs.is_empty() {
180+
None
181+
} else {
182+
Some(Documentation(docs.into()))
183+
}
184+
}
143185
}
144186

145187
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -160,8 +202,10 @@ impl Attr {
160202
fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> {
161203
let path = ModPath::from_src(ast.path()?, hygiene)?;
162204
let input = if let Some(lit) = ast.literal() {
163-
// FIXME: escape? raw string?
164-
let value = lit.syntax().first_token()?.text().trim_matches('"').into();
205+
let value = match lit.kind() {
206+
ast::LiteralKind::String(string) => string.value()?.into(),
207+
_ => lit.syntax().first_token()?.text().trim_matches('"').into(),
208+
};
165209
Some(AttrInput::Literal(value))
166210
} else if let Some(tt) = ast.token_tree() {
167211
Some(AttrInput::TokenTree(ast_to_token_tree(&tt)?.0))

crates/hir_def/src/db.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use crate::{
1010
attr::Attrs,
1111
body::{scope::ExprScopes, Body, BodySourceMap},
1212
data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
13-
docs::Documentation,
1413
generics::GenericParams,
1514
import_map::ImportMap,
1615
item_tree::ItemTree,
@@ -105,11 +104,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
105104
#[salsa::invoke(LangItems::lang_item_query)]
106105
fn lang_item(&self, start_crate: CrateId, item: SmolStr) -> Option<LangItemTarget>;
107106

108-
// FIXME(https://github.com/rust-analyzer/rust-analyzer/issues/2148#issuecomment-550519102)
109-
// Remove this query completely, in favor of `Attrs::docs` method
110-
#[salsa::invoke(Documentation::documentation_query)]
111-
fn documentation(&self, def: AttrDefId) -> Option<Documentation>;
112-
113107
#[salsa::invoke(ImportMap::import_map_query)]
114108
fn import_map(&self, krate: CrateId) -> Arc<ImportMap>;
115109
}

crates/hir_def/src/docs.rs

Lines changed: 0 additions & 121 deletions
This file was deleted.

crates/hir_def/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub mod adt;
3131
pub mod data;
3232
pub mod generics;
3333
pub mod lang_item;
34-
pub mod docs;
3534

3635
pub mod expr;
3736
pub mod body;

crates/hir_def/src/nameres/tests/mod_resolution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() {
372372
check(
373373
r#"
374374
//- /main.rs
375-
#[path = "module\bar\mod.rs"]
375+
#[path = r"module\bar\mod.rs"]
376376
mod foo;
377377
378378
//- /module/bar/mod.rs

0 commit comments

Comments
 (0)