Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r--crates/hir/src/semantics.rs71
1 files changed, 33 insertions, 38 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 8eb1c9725c..62ce3daab7 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -21,6 +21,7 @@ use hir_def::{
};
use hir_expand::{
EditionedFileId, ExpandResult, FileRange, HirFileId, InMacroFile, MacroCallId,
+ attrs::collect_attrs,
builtin::{BuiltinFnLikeExpander, EagerExpander},
db::ExpandDatabase,
files::{FileRangeWrapper, HirFileRange, InRealFile},
@@ -35,7 +36,7 @@ use intern::{Interned, Symbol, sym};
use itertools::Itertools;
use rustc_hash::{FxHashMap, FxHashSet};
use smallvec::{SmallVec, smallvec};
-use span::{FileId, SyntaxContext};
+use span::{Edition, FileId, SyntaxContext};
use stdx::{TupleExt, always};
use syntax::{
AstNode, AstToken, Direction, SyntaxKind, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange,
@@ -385,14 +386,17 @@ impl<'db> SemanticsImpl<'db> {
}
pub fn attach_first_edition(&self, file: FileId) -> Option<EditionedFileId> {
- let krate = self.file_to_module_defs(file).next()?.krate();
- Some(EditionedFileId::new(self.db, file, krate.edition(self.db), krate.id))
+ Some(EditionedFileId::new(
+ self.db,
+ file,
+ self.file_to_module_defs(file).next()?.krate().edition(self.db),
+ ))
}
pub fn parse_guess_edition(&self, file_id: FileId) -> ast::SourceFile {
let file_id = self
.attach_first_edition(file_id)
- .unwrap_or_else(|| EditionedFileId::current_edition_guess_origin(self.db, file_id));
+ .unwrap_or_else(|| EditionedFileId::new(self.db, file_id, Edition::CURRENT));
let tree = self.db.parse(file_id).tree();
self.cache(tree.syntax().clone(), file_id.into());
@@ -1193,34 +1197,33 @@ impl<'db> SemanticsImpl<'db> {
.zip(Some(item))
})
.map(|(call_id, item)| {
- let item_range = item.syntax().text_range();
- let loc = db.lookup_intern_macro_call(call_id);
- let text_range = match loc.kind {
+ let attr_id = match db.lookup_intern_macro_call(call_id).kind {
hir_expand::MacroCallKind::Attr {
- censored_attr_ids: attr_ids,
- ..
- } => {
- // FIXME: here, the attribute's text range is used to strip away all
- // entries from the start of the attribute "list" up the invoking
- // attribute. But in
- // ```
- // mod foo {
- // #![inner]
- // }
- // ```
- // we don't wanna strip away stuff in the `mod foo {` range, that is
- // here if the id corresponds to an inner attribute we got strip all
- // text ranges of the outer ones, and then all of the inner ones up
- // to the invoking attribute so that the inbetween is ignored.
- // FIXME: Should cfg_attr be handled differently?
- let (attr, _, _, _) = attr_ids
- .invoc_attr()
- .find_attr_range_with_source(db, loc.krate, &item);
- let start = attr.syntax().text_range().start();
- TextRange::new(start, item_range.end())
- }
- _ => item_range,
+ invoc_attr_index, ..
+ } => invoc_attr_index.ast_index(),
+ _ => 0,
};
+ // FIXME: here, the attribute's text range is used to strip away all
+ // entries from the start of the attribute "list" up the invoking
+ // attribute. But in
+ // ```
+ // mod foo {
+ // #![inner]
+ // }
+ // ```
+ // we don't wanna strip away stuff in the `mod foo {` range, that is
+ // here if the id corresponds to an inner attribute we got strip all
+ // text ranges of the outer ones, and then all of the inner ones up
+ // to the invoking attribute so that the inbetween is ignored.
+ let text_range = item.syntax().text_range();
+ let start = collect_attrs(&item)
+ .nth(attr_id)
+ .map(|attr| match attr.1 {
+ Either::Left(it) => it.syntax().text_range().start(),
+ Either::Right(it) => it.syntax().text_range().start(),
+ })
+ .unwrap_or_else(|| text_range.start());
+ let text_range = TextRange::new(start, text_range.end());
filter_duplicates(tokens, text_range);
process_expansion_for_token(ctx, &mut stack, call_id)
})
@@ -1470,14 +1473,6 @@ impl<'db> SemanticsImpl<'db> {
FileRangeWrapper { file_id: file_id.file_id(self.db), range }
}
- pub fn diagnostics_display_range_for_range(
- &self,
- src: InFile<TextRange>,
- ) -> FileRangeWrapper<FileId> {
- let FileRange { file_id, range } = src.original_node_file_range_rooted(self.db);
- FileRangeWrapper { file_id: file_id.file_id(self.db), range }
- }
-
fn token_ancestors_with_macros(
&self,
token: SyntaxToken,