1 //! Used by `rustc` when compiling a plugin crate.
4 use syntax
::symbol
::sym
;
6 use rustc
::hir
::itemlikevisit
::ItemLikeVisitor
;
8 use rustc
::hir
::def_id
::{CrateNum, DefId, LOCAL_CRATE}
;
10 use rustc
::ty
::query
::Providers
;
12 struct RegistrarFinder
{
13 registrars
: Vec
<(hir
::HirId
, Span
)> ,
16 impl<'v
> ItemLikeVisitor
<'v
> for RegistrarFinder
{
17 fn visit_item(&mut self, item
: &hir
::Item
) {
18 if let hir
::ItemKind
::Fn(..) = item
.kind
{
19 if attr
::contains_name(&item
.attrs
, sym
::plugin_registrar
) {
20 self.registrars
.push((item
.hir_id
, item
.span
));
25 fn visit_trait_item(&mut self, _trait_item
: &hir
::TraitItem
) {
28 fn visit_impl_item(&mut self, _impl_item
: &hir
::ImplItem
) {
32 /// Finds the function marked with `#[plugin_registrar]`, if any.
33 pub fn find_plugin_registrar(tcx
: TyCtxt
<'_
>) -> Option
<DefId
> {
34 tcx
.plugin_registrar_fn(LOCAL_CRATE
)
37 fn plugin_registrar_fn(tcx
: TyCtxt
<'_
>, cnum
: CrateNum
) -> Option
<DefId
> {
38 assert_eq
!(cnum
, LOCAL_CRATE
);
40 let mut finder
= RegistrarFinder { registrars: Vec::new() }
;
41 tcx
.hir().krate().visit_all_item_likes(&mut finder
);
43 match finder
.registrars
.len() {
46 let (hir_id
, _
) = finder
.registrars
.pop().unwrap();
47 Some(tcx
.hir().local_def_id(hir_id
))
50 let diagnostic
= tcx
.sess
.diagnostic();
51 let mut e
= diagnostic
.struct_err("multiple plugin registration functions found");
52 for &(_
, span
) in &finder
.registrars
{
53 e
.span_note(span
, "one is here");
56 diagnostic
.abort_if_errors();
63 pub fn provide(providers
: &mut Providers
<'_
>) {
64 *providers
= Providers
{