]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //! Used by `rustc` when compiling a plugin crate. |
2 | ||
dfeec247 | 3 | use rustc_hir as hir; |
17df50a5 | 4 | use rustc_hir::def_id::LocalDefId; |
dfeec247 | 5 | use rustc_hir::itemlikevisit::ItemLikeVisitor; |
ba9703b0 XL |
6 | use rustc_middle::ty::query::Providers; |
7 | use rustc_middle::ty::TyCtxt; | |
dfeec247 XL |
8 | use rustc_span::symbol::sym; |
9 | use rustc_span::Span; | |
1a4d82fc | 10 | |
3dfed10e XL |
11 | struct RegistrarFinder<'tcx> { |
12 | tcx: TyCtxt<'tcx>, | |
6a06907d | 13 | registrars: Vec<(LocalDefId, Span)>, |
1a4d82fc JJ |
14 | } |
15 | ||
3dfed10e | 16 | impl<'v, 'tcx> ItemLikeVisitor<'v> for RegistrarFinder<'tcx> { |
dfeec247 | 17 | fn visit_item(&mut self, item: &hir::Item<'_>) { |
e74abb32 | 18 | if let hir::ItemKind::Fn(..) = item.kind { |
6a06907d XL |
19 | let attrs = self.tcx.hir().attrs(item.hir_id()); |
20 | if self.tcx.sess.contains_name(attrs, sym::plugin_registrar) { | |
21 | self.registrars.push((item.def_id, item.span)); | |
1a4d82fc JJ |
22 | } |
23 | } | |
32a655c1 SL |
24 | } |
25 | ||
dfeec247 | 26 | fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {} |
476ff2be | 27 | |
dfeec247 | 28 | fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {} |
fc512014 XL |
29 | |
30 | fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {} | |
1a4d82fc JJ |
31 | } |
32 | ||
9fa01778 | 33 | /// Finds the function marked with `#[plugin_registrar]`, if any. |
17df50a5 | 34 | fn plugin_registrar_fn(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> { |
3dfed10e | 35 | let mut finder = RegistrarFinder { tcx, registrars: Vec::new() }; |
0731742a | 36 | tcx.hir().krate().visit_all_item_likes(&mut finder); |
1a4d82fc | 37 | |
17df50a5 XL |
38 | let (def_id, span) = finder.registrars.pop()?; |
39 | ||
40 | if !finder.registrars.is_empty() { | |
41 | let diagnostic = tcx.sess.diagnostic(); | |
42 | let mut e = diagnostic.struct_err("multiple plugin registration functions found"); | |
43 | e.span_note(span, "one is here"); | |
44 | for &(_, span) in &finder.registrars { | |
45 | e.span_note(span, "one is here"); | |
1a4d82fc | 46 | } |
17df50a5 XL |
47 | e.emit(); |
48 | diagnostic.abort_if_errors(); | |
49 | unreachable!(); | |
1a4d82fc | 50 | } |
17df50a5 XL |
51 | |
52 | Some(def_id) | |
1a4d82fc | 53 | } |
0731742a | 54 | |
f035d41b | 55 | pub fn provide(providers: &mut Providers) { |
dfeec247 | 56 | *providers = Providers { plugin_registrar_fn, ..*providers }; |
0731742a | 57 | } |