Skip to content

Commit ddad284

Browse files
committed
Allow name querying for derive helpers
1 parent aa1491e commit ddad284

File tree

8 files changed

+53
-18
lines changed

8 files changed

+53
-18
lines changed

crates/hir-def/src/data.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
db::DefDatabase,
1313
intern::Interned,
1414
item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, ModItem, Param, TreeId},
15-
nameres::{attr_resolution::ResolvedAttr, DefMap},
15+
nameres::{attr_resolution::ResolvedAttr, proc_macro::ProcMacroKind, DefMap},
1616
type_ref::{TraitRef, TypeBound, TypeRef},
1717
visibility::RawVisibility,
1818
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -348,7 +348,8 @@ impl MacroRulesData {
348348
#[derive(Debug, Clone, PartialEq, Eq)]
349349
pub struct ProcMacroData {
350350
pub name: Name,
351-
// FIXME: Record deriver helper here?
351+
/// Derive helpers, if this is a derive
352+
pub helpers: Option<Box<[Name]>>,
352353
}
353354

354355
impl ProcMacroData {
@@ -360,17 +361,23 @@ impl ProcMacroData {
360361
let item_tree = loc.id.item_tree(db);
361362
let makro = &item_tree[loc.id.value];
362363

363-
let name = if let Some(def) = item_tree
364+
let (name, helpers) = if let Some(def) = item_tree
364365
.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
365366
.parse_proc_macro_decl(&makro.name)
366367
{
367-
def.name
368+
(
369+
def.name,
370+
match def.kind {
371+
ProcMacroKind::CustomDerive { helpers } => Some(helpers),
372+
ProcMacroKind::FnLike | ProcMacroKind::Attr => None,
373+
},
374+
)
368375
} else {
369376
// eeeh...
370377
stdx::never!("proc macro declaration is not a proc macro");
371-
makro.name.clone()
378+
(makro.name.clone(), None)
372379
};
373-
Arc::new(ProcMacroData { name })
380+
Arc::new(ProcMacroData { name, helpers })
374381
}
375382
}
376383

crates/hir-def/src/nameres.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@
4848
//! the result
4949
5050
pub mod attr_resolution;
51-
mod collector;
51+
pub mod proc_macro;
5252
pub mod diagnostics;
53+
mod collector;
5354
mod mod_resolution;
5455
mod path_resolution;
55-
mod proc_macro;
5656

5757
#[cfg(test)]
5858
mod tests;

crates/hir/src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -2255,12 +2255,27 @@ impl Local {
22552255
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22562256
pub struct DeriveHelper {
22572257
pub(crate) derive: MacroId,
2258+
pub(crate) idx: usize,
22582259
}
22592260

22602261
impl DeriveHelper {
22612262
pub fn derive(&self) -> Macro {
22622263
Macro { id: self.derive.into() }
22632264
}
2265+
2266+
pub fn name(&self, db: &dyn HirDatabase) -> Name {
2267+
match self.derive {
2268+
MacroId::Macro2Id(_) => None,
2269+
MacroId::MacroRulesId(_) => None,
2270+
MacroId::ProcMacroId(proc_macro) => db
2271+
.proc_macro_data(proc_macro)
2272+
.helpers
2273+
.as_ref()
2274+
.and_then(|it| it.get(self.idx))
2275+
.cloned(),
2276+
}
2277+
.unwrap_or_else(|| Name::missing())
2278+
}
22642279
}
22652280

22662281
// FIXME: Wrong name? This is could also be a registered attribute

crates/hir/src/source_analyzer.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use hir_ty::{
3535
method_resolution, Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution,
3636
TyExt, TyKind, TyLoweringContext,
3737
};
38+
use itertools::Itertools;
3839
use smallvec::SmallVec;
3940
use syntax::{
4041
ast::{self, AstNode},
@@ -487,10 +488,16 @@ impl SourceAnalyzer {
487488
{
488489
// FIXME: Multiple derives can have the same helper
489490
let name_ref = name_ref.as_name();
490-
if let Some(&(_, derive, _)) =
491-
helpers.iter().find(|(name, ..)| *name == name_ref)
491+
for (macro_id, mut helpers) in
492+
helpers.iter().group_by(|(_, macro_id, ..)| macro_id).into_iter()
492493
{
493-
return Some(PathResolution::DeriveHelper(DeriveHelper { derive }));
494+
if let Some(idx) = helpers.position(|(name, ..)| *name == name_ref)
495+
{
496+
return Some(PathResolution::DeriveHelper(DeriveHelper {
497+
derive: *macro_id,
498+
idx,
499+
}));
500+
}
494501
}
495502
}
496503
}

crates/ide-db/src/defs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl Definition {
121121
Definition::Label(it) => it.name(db),
122122
Definition::BuiltinAttr(_) => return None, // FIXME
123123
Definition::ToolModule(_) => return None, // FIXME
124-
Definition::DeriveHelper(_) => return None, // FIXME
124+
Definition::DeriveHelper(it) => it.name(db),
125125
};
126126
Some(name)
127127
}

crates/ide-db/src/search.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,16 @@ impl Definition {
278278
}
279279
}
280280
hir::MacroKind::BuiltIn => SearchScope::crate_graph(db),
281-
// FIXME: We don't actually see derives in derive attributes as these do not
282-
// expand to something that references the derive macro in the output.
283-
// We could get around this by doing pseudo expansions for proc_macro_derive like we
284-
// do for the derive attribute
285281
hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => {
286282
SearchScope::reverse_dependencies(db, module.krate())
287283
}
288284
};
289285
}
290286

287+
if let Definition::DeriveHelper(_) = self {
288+
return SearchScope::reverse_dependencies(db, module.krate());
289+
}
290+
291291
let vis = self.visibility(db);
292292
if let Some(Visibility::Public) = vis {
293293
return SearchScope::reverse_dependencies(db, module.krate());

crates/ide/src/hover/render.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,7 @@ pub(super) fn definition(
370370
// FIXME: We should be able to show more info about these
371371
Definition::BuiltinAttr(it) => return render_builtin_attr(db, it),
372372
Definition::ToolModule(it) => return Some(Markup::fenced_block(&it.name(db))),
373-
// FIXME: it.name(db)
374-
Definition::DeriveHelper(_it) => ("derive-helper".to_owned(), None),
373+
Definition::DeriveHelper(it) => (format!("derive_helper {}", it.name(db)), None),
375374
};
376375

377376
let docs = match config.documentation {

crates/ide/src/syntax_highlighting.rs

+7
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,13 @@ fn traverse(
432432
// let the editor do its highlighting for these tokens instead
433433
continue;
434434
}
435+
if highlight.tag == HlTag::UnresolvedReference
436+
&& matches!(attr_or_derive_item, Some(AttrOrDerive::Derive(_)) if inside_attribute)
437+
{
438+
// do not emit unresolved references in derive helpers if the token mapping maps to
439+
// something unresolvable. FIXME: There should be a way to prevent that
440+
continue;
441+
}
435442
if inside_attribute {
436443
highlight |= HlMod::Attribute
437444
}

0 commit comments

Comments
 (0)