diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 243ba63b8a..1156dfe98e 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -5,7 +5,6 @@ mod source_to_def; use std::{cell::RefCell, fmt, iter}; use base_db::{FileId, FileRange}; -use either::Either; use hir_def::{ body, resolver::{self, HasResolver, Resolver, TypeNs}, @@ -19,17 +18,16 @@ use smallvec::{smallvec, SmallVec}; use syntax::{ algo::skip_trivia_token, ast::{self, HasAttrs as _, HasGenericParams, HasLoopBody}, - match_ast, AstNode, AstToken, Direction, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, - TextSize, T, + match_ast, AstNode, Direction, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextSize, }; use crate::{ db::HirDatabase, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{resolve_hir_path, SourceAnalyzer}, - Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasAttrs as _, - HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, - Name, Path, ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef, + Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource, + HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, + ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -350,14 +348,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.resolve_bind_pat_to_const(pat) } - pub fn resolve_derive_ident( - &self, - derive: &ast::Attr, - ident: &ast::Ident, - ) -> Option { - self.imp.resolve_derive_ident(derive, ident) - } - pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> { self.imp.record_literal_missing_fields(literal) } @@ -475,7 +465,7 @@ impl<'db> SemanticsImpl<'db> { let adt = InFile::new(file_id, &adt); let src = InFile::new(file_id, attr.clone()); self.with_ctx(|ctx| { - let (_, res) = ctx.attr_to_derive_macro_call(adt, src)?; + let (.., res) = ctx.attr_to_derive_macro_call(adt, src)?; Some(res.to_vec()) }) } @@ -668,7 +658,27 @@ impl<'db> SemanticsImpl<'db> { // FIXME replace map.while_some with take_while once stable token.value.ancestors().map(ast::TokenTree::cast).while_some().last() { - let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?; + let parent = tt.syntax().parent()?; + // check for derive attribute here + let macro_call = match_ast! { + match parent { + ast::MacroCall(mcall) => mcall, + // attribute we failed expansion for earlier, this might be a derive invocation + // so try downmapping the token into the pseudo derive expansion + ast::Meta(meta) => { + let attr = meta.parent_attr()?; + let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; + let call_id = self.with_ctx(|ctx| { + let (_, call_id, _) = ctx.attr_to_derive_macro_call(token.with_value(&adt), token.with_value(attr))?; + Some(call_id) + })?; + let file_id = call_id.as_file(); + return process_expansion_for_token(&mut stack,file_id,Some(adt.into()),token.as_ref(),); + }, + _ => return None, + } + }; + if tt.left_delimiter_token().map_or(false, |it| it == token.value) { return None; } @@ -898,72 +908,6 @@ impl<'db> SemanticsImpl<'db> { self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) } - fn resolve_derive_ident( - &self, - derive: &ast::Attr, - ident: &ast::Ident, - ) -> Option { - debug_assert!(ident.syntax().parent().and_then(ast::TokenTree::cast).is_some()); - debug_assert!(ident.syntax().ancestors().any(|anc| anc == *derive.syntax())); - // derive macros are always at depth 2, tokentree -> meta -> attribute - let syntax = ident.syntax(); - - let tt = derive.token_tree()?; - let file = self.find_file(derive.syntax()); - let adt = derive.syntax().parent().and_then(ast::Adt::cast)?; - let adt_def = ToDef::to_def(self, file.with_value(adt.clone()))?; - let res = self.with_ctx(|ctx| { - let (attr_id, derives) = ctx.attr_to_derive_macro_call( - file.with_value(&adt), - file.with_value(derive.clone()), - )?; - let attrs = adt_def.attrs(self.db); - let mut derive_paths = attrs.get(attr_id)?.parse_path_comma_token_tree()?; - - let derive_idx = tt - .syntax() - .children_with_tokens() - .filter_map(SyntaxElement::into_token) - .take_while(|tok| tok != syntax) - .filter(|t| t.kind() == T![,]) - .count(); - let path_segment_idx = syntax - .siblings_with_tokens(Direction::Prev) - .filter_map(SyntaxElement::into_token) - .take_while(|tok| matches!(tok.kind(), T![:] | T![ident])) - .filter(|tok| tok.kind() == T![ident]) - .count(); - - let mut mod_path = derive_paths.nth(derive_idx)?; - - if path_segment_idx < mod_path.len() { - // the path for the given ident is a qualifier, resolve to module if possible - while path_segment_idx < mod_path.len() { - mod_path.pop_segment(); - } - Some(Either::Left(mod_path)) - } else { - // otherwise fetch the derive - Some(Either::Right(derives[derive_idx])) - } - })?; - - match res { - Either::Left(path) => { - let len = path.len(); - resolve_hir_path( - self.db, - &self.scope(derive.syntax()).resolver, - &Path::from_known_path(path, vec![None; len]), - ) - .filter(|res| matches!(res, PathResolution::Def(ModuleDef::Module(_)))) - } - Either::Right(derive) => derive - .map(|call| MacroDef { id: self.db.lookup_intern_macro_call(call).def }) - .map(PathResolution::Macro), - } - } - fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> { self.analyze(literal.syntax()) .record_literal_missing_fields(self.db, literal) diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 5061861239..c0d8e69e49 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -249,9 +249,11 @@ impl SourceToDefCtx<'_, '_> { &mut self, item: InFile<&ast::Adt>, src: InFile, - ) -> Option<(AttrId, &[Option])> { + ) -> Option<(AttrId, MacroCallId, &[Option])> { let map = self.dyn_map(item)?; - map[keys::DERIVE_MACRO_CALL].get(&src.value).map(|(id, ids)| (*id, &**ids)) + map[keys::DERIVE_MACRO_CALL] + .get(&src.value) + .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids)) } fn to_def( diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 03e4420985..ef32a5891c 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -371,10 +371,10 @@ impl SourceAnalyzer { return builtin.map(PathResolution::BuiltinAttr); } return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) { - res @ Some(m) if m.is_attr() => res.map(PathResolution::Macro), + Some(m) => Some(PathResolution::Macro(m)), // this labels any path that starts with a tool module as the tool itself, this is technically wrong // but there is no benefit in differentiating these two cases for the time being - _ => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| { + None => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| { match self.resolver.krate() { Some(krate) => ToolModule::by_name(db, krate.into(), &name_ref.text()), None => ToolModule::builtin(&name_ref.text()), diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs index 5c32a31e44..1e1573d4ae 100644 --- a/crates/hir_def/src/child_by_source.rs +++ b/crates/hir_def/src/child_by_source.rs @@ -116,11 +116,11 @@ impl ChildBySource for ItemScope { self.derive_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each( |(ast_id, calls)| { let adt = ast_id.to_node(db.upcast()); - calls.for_each(|(attr_id, calls)| { + calls.for_each(|(attr_id, call_id, calls)| { if let Some(Either::Left(attr)) = adt.doc_comments_and_attrs().nth(attr_id.ast_index as usize) { - res[keys::DERIVE_MACRO_CALL].insert(attr, (attr_id, calls.into())); + res[keys::DERIVE_MACRO_CALL].insert(attr, (attr_id, call_id, calls.into())); } }); }, diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index 258d1e0f6c..fffec96bab 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs @@ -66,8 +66,10 @@ pub struct ItemScope { attr_macros: FxHashMap, MacroCallId>, /// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes /// paired with the derive macro invocations for the specific attribute. - derive_macros: - FxHashMap, SmallVec<[(AttrId, SmallVec<[Option; 1]>); 1]>>, + derive_macros: FxHashMap< + AstId, + SmallVec<[(AttrId, MacroCallId, SmallVec<[Option; 1]>); 1]>, + >, } pub(crate) static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { @@ -210,7 +212,7 @@ impl ItemScope { idx: usize, ) { if let Some(derives) = self.derive_macros.get_mut(&adt) { - if let Some((_, invocs)) = derives.iter_mut().find(|&&mut (id, _)| id == attr_id) { + if let Some((.., invocs)) = derives.iter_mut().find(|&&mut (id, ..)| id == attr_id) { invocs[idx] = Some(call); } } @@ -223,19 +225,23 @@ impl ItemScope { &mut self, adt: AstId, attr_id: AttrId, + call_id: MacroCallId, len: usize, ) { - self.derive_macros.entry(adt).or_default().push((attr_id, smallvec![None; len])); + self.derive_macros.entry(adt).or_default().push((attr_id, call_id, smallvec![None; len])); } pub(crate) fn derive_macro_invocs( &self, ) -> impl Iterator< - Item = (AstId, impl Iterator])>), + Item = ( + AstId, + impl Iterator])>, + ), > + '_ { - self.derive_macros - .iter() - .map(|(k, v)| (*k, v.iter().map(|(attr_id, invocs)| (*attr_id, &**invocs)))) + self.derive_macros.iter().map(|(k, v)| { + (*k, v.iter().map(|&(attr_id, call_id, ref invocs)| (attr_id, call_id, &**invocs))) + }) } pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option { diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs index 93c92c1b9c..1c9d99eb78 100644 --- a/crates/hir_def/src/keys.rs +++ b/crates/hir_def/src/keys.rs @@ -34,7 +34,8 @@ pub const CONST_PARAM: Key = Key::new(); pub const MACRO: Key = Key::new(); pub const ATTR_MACRO_CALL: Key = Key::new(); -pub const DERIVE_MACRO_CALL: Key]>)> = Key::new(); +pub const DERIVE_MACRO_CALL: Key]>)> = + Key::new(); /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are /// equal if they point to exactly the same object. diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 7e33e53599..bb65d1dec8 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs @@ -690,9 +690,9 @@ impl AsMacroCall for InFile<&ast::MacroCall> { }; macro_call_as_call_id( + db, &AstIdWithPath::new(ast_id.file_id, ast_id.value, path), expands_to, - db, krate, resolver, error_sink, @@ -714,9 +714,9 @@ impl AstIdWithPath { } fn macro_call_as_call_id( + db: &dyn db::DefDatabase, call: &AstIdWithPath, expand_to: ExpandTo, - db: &dyn db::DefDatabase, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option, error_sink: &mut dyn FnMut(ExpandError), @@ -739,10 +739,10 @@ fn macro_call_as_call_id( } fn derive_macro_as_call_id( + db: &dyn db::DefDatabase, item_attr: &AstIdWithPath, derive_attr: AttrId, derive_pos: u32, - db: &dyn db::DefDatabase, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option, ) -> Result { @@ -761,11 +761,12 @@ fn derive_macro_as_call_id( } fn attr_macro_as_call_id( + db: &dyn db::DefDatabase, item_attr: &AstIdWithPath, macro_attr: &Attr, - db: &dyn db::DefDatabase, krate: CrateId, def: MacroDefId, + is_derive: bool, ) -> MacroCallId { let mut arg = match macro_attr.input.as_deref() { Some(attr::AttrInput::TokenTree(tt, map)) => (tt.clone(), map.clone()), @@ -782,6 +783,7 @@ fn attr_macro_as_call_id( ast_id: item_attr.ast_id, attr_args: Arc::new(arg), invoc_attr_index: macro_attr.id.ast_index, + is_derive, }, ); res diff --git a/crates/hir_def/src/nameres/attr_resolution.rs b/crates/hir_def/src/nameres/attr_resolution.rs index 4a7211b5c9..4c436250db 100644 --- a/crates/hir_def/src/nameres/attr_resolution.rs +++ b/crates/hir_def/src/nameres/attr_resolution.rs @@ -54,7 +54,7 @@ impl DefMap { None => return Err(UnresolvedMacro { path: ast_id.path.clone() }), }; - Ok(ResolvedAttr::Macro(attr_macro_as_call_id(&ast_id, attr, db, self.krate, def))) + Ok(ResolvedAttr::Macro(attr_macro_as_call_id(db, &ast_id, attr, self.krate, def, false))) } pub(crate) fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool { diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index ec6af65a92..9e29f28d98 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -1055,9 +1055,9 @@ impl DefCollector<'_> { match &directive.kind { MacroDirectiveKind::FnLike { ast_id, expand_to } => { let call_id = macro_call_as_call_id( + self.db, ast_id, *expand_to, - self.db, self.def_map.krate, &resolver, &mut |_err| (), @@ -1070,10 +1070,10 @@ impl DefCollector<'_> { } MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos } => { let call_id = derive_macro_as_call_id( + self.db, ast_id, *derive_attr, *derive_pos as u32, - self.db, self.def_map.krate, &resolver, ); @@ -1170,9 +1170,17 @@ impl DefCollector<'_> { len = idx; } + let call_id = attr_macro_as_call_id( + self.db, + file_ast_id, + attr, + self.def_map.krate, + def, + true, + ); self.def_map.modules[directive.module_id] .scope - .init_derive_attribute(ast_id, attr.id, len + 1); + .init_derive_attribute(ast_id, attr.id, call_id, len + 1); } None => { let diag = DefDiagnostic::malformed_derive( @@ -1192,8 +1200,14 @@ impl DefCollector<'_> { } // Not resolved to a derive helper or the derive attribute, so try to treat as a normal attribute. - let call_id = - attr_macro_as_call_id(file_ast_id, attr, self.db, self.def_map.krate, def); + let call_id = attr_macro_as_call_id( + self.db, + file_ast_id, + attr, + self.def_map.krate, + def, + false, + ); let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call_id); // Skip #[test]/#[bench] expansion, which would merely result in more memory usage @@ -1310,9 +1324,9 @@ impl DefCollector<'_> { match &directive.kind { MacroDirectiveKind::FnLike { ast_id, expand_to } => { let macro_call_as_call_id = macro_call_as_call_id( + self.db, ast_id, *expand_to, - self.db, self.def_map.krate, |path| { let resolved_res = self.def_map.resolve_path_fp_with_macro( @@ -1959,9 +1973,9 @@ impl ModCollector<'_, '_> { // Case 1: try to resolve in legacy scope and expand macro_rules let mut error = None; match macro_call_as_call_id( + self.def_collector.db, &ast_id, mac.expand_to, - self.def_collector.db, self.def_collector.def_map.krate, |path| { path.as_ident().and_then(|name| { diff --git a/crates/hir_expand/src/builtin_attr_macro.rs b/crates/hir_expand/src/builtin_attr_macro.rs index 907ee02e33..1996624598 100644 --- a/crates/hir_expand/src/builtin_attr_macro.rs +++ b/crates/hir_expand/src/builtin_attr_macro.rs @@ -1,9 +1,11 @@ //! Builtin attributes. +use itertools::Itertools; use syntax::ast; use crate::{ - db::AstDatabase, name, AstId, CrateId, ExpandResult, MacroCallId, MacroDefId, MacroDefKind, + db::AstDatabase, name, AstId, CrateId, ExpandResult, MacroCallId, MacroCallKind, MacroDefId, + MacroDefKind, }; macro_rules! register_builtin { @@ -53,7 +55,7 @@ register_builtin! { (bench, Bench) => dummy_attr_expand, (cfg_accessible, CfgAccessible) => dummy_attr_expand, (cfg_eval, CfgEval) => dummy_attr_expand, - (derive, Derive) => dummy_attr_expand, + (derive, Derive) => derive_attr_expand, (global_allocator, GlobalAllocator) => dummy_attr_expand, (test, Test) => dummy_attr_expand, (test_case, TestCase) => dummy_attr_expand @@ -79,3 +81,76 @@ fn dummy_attr_expand( ) -> ExpandResult { ExpandResult::ok(tt.clone()) } + +fn derive_attr_expand( + db: &dyn AstDatabase, + id: MacroCallId, + tt: &tt::Subtree, +) -> ExpandResult { + // we generate a very specific expansion here, as we do not actually expand the `#[derive]` attribute + // itself in name res, but we do want to expand it to something for the IDE layer, so that the input + // derive attributes can be downmapped, and resolved + // This is basically a hack, to get rid of hacks in the IDE layer that slowly accumulate more and more + // in various places. + + // we transform the token tree of `#[derive(Foo, bar::Bar)]` into + // ``` + // #[Foo] + // #[bar::Bar] + // (); + // ``` + // which allows fallback path resolution in hir::Semantics to properly identify our derives + let loc = db.lookup_intern_macro_call(id); + let derives = match &loc.kind { + MacroCallKind::Attr { attr_args, .. } => &attr_args.0, + _ => return ExpandResult::ok(tt.clone()), + }; + + let mut token_trees = Vec::new(); + for (comma, group) in &derives + .token_trees + .iter() + .filter_map(|tt| match tt { + tt::TokenTree::Leaf(l) => Some(l), + tt::TokenTree::Subtree(_) => None, + }) + .group_by(|l| matches!(l, tt::Leaf::Punct(tt::Punct { char: ',', .. }))) + { + if comma { + continue; + } + let wrap = |leaf| tt::TokenTree::Leaf(tt::Leaf::Punct(leaf)); + token_trees.push(wrap(tt::Punct { + char: '#', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + })); + token_trees.push(wrap(tt::Punct { + char: '[', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + })); + token_trees.extend(group.cloned().map(tt::TokenTree::Leaf)); + token_trees.push(wrap(tt::Punct { + char: ']', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + })); + token_trees.push(wrap(tt::Punct { + char: '(', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + })); + token_trees.push(wrap(tt::Punct { + char: ')', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + })); + token_trees.push(wrap(tt::Punct { + char: ';', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + })); + } + ExpandResult::ok(tt::Subtree { delimiter: tt.delimiter, token_trees }) +} diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 91c1631e81..d6d33b4cd7 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -342,6 +342,7 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet return None, MacroCallKind::Attr { invoc_attr_index, .. } => { cov_mark::hit!(attribute_macro_attr_censoring); ast::Item::cast(node.clone())? diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 27c3f097ab..2ccf4c56ee 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -166,6 +166,7 @@ pub enum MacroCallKind { /// Outer attributes are counted first, then inner attributes. This does not support /// out-of-line modules, which may have attributes spread across 2 files! invoc_attr_index: u32, + is_derive: bool, }, } @@ -431,6 +432,7 @@ impl MacroCallKind { match self { MacroCallKind::FnLike { expand_to, .. } => *expand_to, MacroCallKind::Derive { .. } => ExpandTo::Items, + MacroCallKind::Attr { is_derive: true, .. } => ExpandTo::Statements, MacroCallKind::Attr { .. } => ExpandTo::Items, // is this always correct? } } @@ -497,7 +499,7 @@ impl ExpansionInfo { let token_range = token.value.text_range(); match &loc.kind { - MacroCallKind::Attr { attr_args, invoc_attr_index, .. } => { + MacroCallKind::Attr { attr_args, invoc_attr_index, is_derive, .. } => { let attr = item .doc_comments_and_attrs() .nth(*invoc_attr_index as usize) @@ -511,9 +513,13 @@ 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 = attr_args.1.token_by_range(relative_range)?; + let token_id = if *is_derive { + // we do not shift for `#[derive]`, as we only need to downmap the derive attribute tokens + token_id + } else { + self.macro_arg_shift.shift(token_id) + }; Some(token_id) } _ => None, diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index c5c531c30b..a232ebd4fb 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -15,6 +15,7 @@ fn check_hover_no_result(ra_fixture: &str) { assert!(hover.is_none(), "hover not expected but found: {:?}", hover.unwrap()); } +#[track_caller] fn check(ra_fixture: &str, expect: Expect) { let (analysis, position) = fixture::position(ra_fixture); let hover = analysis diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index f09f291e96..d67f6baff0 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -361,7 +361,7 @@ fn traverse( syntactic_name_ref_highlighting, node, ), - NodeOrToken::Token(token) => highlight::token(sema, krate, token).zip(Some(None)), + NodeOrToken::Token(token) => highlight::token(sema, token).zip(Some(None)), }; if let Some((mut highlight, binding_hash)) = element { if inside_attribute { diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index c869db3b8b..85c0c1b286 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -18,11 +18,7 @@ use crate::{ Highlight, HlMod, HlTag, }; -pub(super) fn token( - sema: &Semantics, - krate: Option, - token: SyntaxToken, -) -> Option { +pub(super) fn token(sema: &Semantics, token: SyntaxToken) -> Option { if let Some(comment) = ast::Comment::cast(token.clone()) { let h = HlTag::Comment; return Some(match comment.kind().doc { @@ -39,17 +35,10 @@ pub(super) fn token( INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), BYTE => HlTag::ByteLiteral.into(), CHAR => HlTag::CharLiteral.into(), - IDENT => { - let tt = ast::TokenTree::cast(token.parent()?)?; - let ident = ast::Ident::cast(token)?; + IDENT if token.parent().and_then(ast::TokenTree::cast).is_some() => { // from this point on we are inside a token tree, this only happens for identifiers // that were not mapped down into macro invocations - (|| { - let attr = tt.parent_meta()?.parent_attr()?; - let res = sema.resolve_derive_ident(&attr, &ident)?; - Some(highlight_def(sema, krate, Definition::from(res))) - })() - .unwrap_or_else(|| HlTag::None.into()) + HlTag::None.into() } p if p.is_punct() => punctuation(sema, token, p), k if k.is_keyword() => keyword(sema, token, k)?, diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index 4b1de8058d..0d59f77a55 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs @@ -58,15 +58,15 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext ( hir::AssocItem::Function(fn_item), ImplCompletionKind::All | ImplCompletionKind::Fn, - ) => add_function_impl(&trigger, acc, ctx, fn_item, hir_impl), + ) => add_function_impl(acc, ctx, &trigger, fn_item, hir_impl), ( hir::AssocItem::TypeAlias(type_item), ImplCompletionKind::All | ImplCompletionKind::TypeAlias, - ) => add_type_alias_impl(&trigger, acc, ctx, type_item), + ) => add_type_alias_impl(acc, ctx, &trigger, type_item), ( hir::AssocItem::Const(const_item), ImplCompletionKind::All | ImplCompletionKind::Const, - ) => add_const_impl(&trigger, acc, ctx, const_item, hir_impl), + ) => add_const_impl(acc, ctx, &trigger, const_item, hir_impl), _ => {} } }); @@ -126,9 +126,9 @@ fn completion_match(mut token: SyntaxToken) -> Option<(ImplCompletionKind, Synta } fn add_function_impl( - fn_def_node: &SyntaxNode, acc: &mut Completions, ctx: &CompletionContext, + fn_def_node: &SyntaxNode, func: hir::Function, impl_def: hir::Impl, ) { @@ -199,9 +199,9 @@ fn get_transformed_assoc_item( } fn add_type_alias_impl( - type_def_node: &SyntaxNode, acc: &mut Completions, ctx: &CompletionContext, + type_def_node: &SyntaxNode, type_alias: hir::TypeAlias, ) { let alias_name = type_alias.name(ctx.db).to_smol_str(); @@ -217,9 +217,9 @@ fn add_type_alias_impl( } fn add_const_impl( - const_def_node: &SyntaxNode, acc: &mut Completions, ctx: &CompletionContext, + const_def_node: &SyntaxNode, const_: hir::Const, impl_def: hir::Impl, ) { diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 5a4cfe6e94..08104efcdc 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -14,7 +14,7 @@ use hir::{ use stdx::impl_from; use syntax::{ ast::{self, AstNode}, - match_ast, AstToken, SyntaxKind, SyntaxNode, SyntaxToken, + match_ast, SyntaxKind, SyntaxNode, SyntaxToken, }; use crate::RootDatabase; @@ -142,16 +142,6 @@ impl IdentClass { token: &SyntaxToken, ) -> Option { let parent = token.parent()?; - // resolve derives if possible - if let Some(ident) = ast::Ident::cast(token.clone()) { - let attr = ast::TokenTree::cast(parent.clone()) - .and_then(|tt| tt.parent_meta()) - .and_then(|meta| meta.parent_attr()); - if let Some(attr) = attr { - return NameRefClass::classify_derive(sema, &attr, &ident) - .map(IdentClass::NameRefClass); - } - } Self::classify_node(sema, &parent) } @@ -461,14 +451,6 @@ impl NameRefClass { _ => None, } } - - pub fn classify_derive( - sema: &Semantics, - attr: &ast::Attr, - ident: &ast::Ident, - ) -> Option { - sema.resolve_derive_ident(&attr, &ident).map(Definition::from).map(NameRefClass::Definition) - } } impl_from!(