]>
Commit | Line | Data |
---|---|---|
54a0048b | 1 | //! Walks the crate looking for items/impl-items/trait-items that have |
532ac7d7 | 2 | //! either a `rustc_symbol_name` or `rustc_def_path` attribute and |
54a0048b | 3 | //! generates an error giving, respectively, the symbol name or |
532ac7d7 | 4 | //! def-path. This is used for unit testing the code that generates |
54a0048b SL |
5 | //! paths etc in all kinds of annoying scenarios. |
6 | ||
dfeec247 | 7 | use rustc_hir as hir; |
6a06907d | 8 | use rustc_hir::def_id::LocalDefId; |
29967ef6 XL |
9 | use rustc_middle::ty::print::with_no_trimmed_paths; |
10 | use rustc_middle::ty::{subst::InternalSubsts, Instance, TyCtxt}; | |
dfeec247 | 11 | use rustc_span::symbol::{sym, Symbol}; |
54a0048b | 12 | |
48663c56 XL |
13 | const SYMBOL_NAME: Symbol = sym::rustc_symbol_name; |
14 | const DEF_PATH: Symbol = sym::rustc_def_path; | |
54a0048b | 15 | |
416331ca | 16 | pub fn report_symbol_names(tcx: TyCtxt<'_>) { |
54a0048b SL |
17 | // if the `rustc_attrs` feature is not enabled, then the |
18 | // attributes we are interested in cannot be present anyway, so | |
19 | // skip the walk. | |
0531ce1d | 20 | if !tcx.features().rustc_attrs { |
54a0048b SL |
21 | return; |
22 | } | |
23 | ||
2c00a5a8 | 24 | tcx.dep_graph.with_ignore(|| { |
a1dfa0c6 | 25 | let mut visitor = SymbolNamesTest { tcx }; |
c295e0f8 | 26 | tcx.hir().visit_all_item_likes(&mut visitor); |
2c00a5a8 | 27 | }) |
54a0048b SL |
28 | } |
29 | ||
dc9dc135 XL |
30 | struct SymbolNamesTest<'tcx> { |
31 | tcx: TyCtxt<'tcx>, | |
54a0048b SL |
32 | } |
33 | ||
dc9dc135 | 34 | impl SymbolNamesTest<'tcx> { |
6a06907d | 35 | fn process_attrs(&mut self, def_id: LocalDefId) { |
cc61c64b | 36 | let tcx = self.tcx; |
f9f354fc | 37 | for attr in tcx.get_attrs(def_id.to_def_id()).iter() { |
94222f64 | 38 | if attr.has_name(SYMBOL_NAME) { |
29967ef6 XL |
39 | let def_id = def_id.to_def_id(); |
40 | let instance = Instance::new( | |
41 | def_id, | |
fc512014 | 42 | tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def_id)), |
29967ef6 | 43 | ); |
3dfed10e | 44 | let mangled = tcx.symbol_name(instance); |
dc9dc135 | 45 | tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled)); |
3dfed10e | 46 | if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) { |
dc9dc135 XL |
47 | tcx.sess.span_err(attr.span, &format!("demangling({})", demangling)); |
48 | tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling)); | |
49 | } | |
94222f64 | 50 | } else if attr.has_name(DEF_PATH) { |
29967ef6 | 51 | let path = with_no_trimmed_paths(|| tcx.def_path_str(def_id.to_def_id())); |
532ac7d7 | 52 | tcx.sess.span_err(attr.span, &format!("def-path({})", path)); |
54a0048b SL |
53 | } |
54 | ||
55 | // (*) The formatting of `tag({})` is chosen so that tests can elect | |
56 | // to test the entirety of the string, if they choose, or else just | |
57 | // some subset. | |
58 | } | |
59 | } | |
60 | } | |
61 | ||
dc9dc135 | 62 | impl hir::itemlikevisit::ItemLikeVisitor<'tcx> for SymbolNamesTest<'tcx> { |
dfeec247 | 63 | fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { |
6a06907d | 64 | self.process_attrs(item.def_id); |
54a0048b SL |
65 | } |
66 | ||
dfeec247 | 67 | fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { |
6a06907d | 68 | self.process_attrs(trait_item.def_id); |
54a0048b SL |
69 | } |
70 | ||
dfeec247 | 71 | fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { |
6a06907d | 72 | self.process_attrs(impl_item.def_id); |
54a0048b | 73 | } |
fc512014 XL |
74 | |
75 | fn visit_foreign_item(&mut self, foreign_item: &'tcx hir::ForeignItem<'tcx>) { | |
6a06907d | 76 | self.process_attrs(foreign_item.def_id); |
fc512014 | 77 | } |
54a0048b | 78 | } |