]>
git.proxmox.com Git - rustc.git/blob - src/librustc_plugin_impl/load.rs
1 //! Used by `rustc` when loading a plugin.
5 use rustc_errors
::struct_span_err
;
6 use rustc_metadata
::locator
;
7 use rustc_middle
::middle
::cstore
::MetadataLoader
;
8 use rustc_session
::Session
;
9 use rustc_span
::symbol
::{sym, Ident}
;
12 use std
::borrow
::ToOwned
;
15 use std
::path
::PathBuf
;
17 /// Pointer to a registrar function.
18 type PluginRegistrarFn
= fn(&mut Registry
<'_
>);
20 fn call_malformed_plugin_attribute(sess
: &Session
, span
: Span
) {
21 struct_span_err
!(sess
, span
, E0498
, "malformed `plugin` attribute")
22 .span_label(span
, "malformed attribute")
26 /// Read plugin metadata and dynamically load registrar functions.
29 metadata_loader
: &dyn MetadataLoader
,
31 ) -> Vec
<PluginRegistrarFn
> {
32 let mut plugins
= Vec
::new();
34 for attr
in &krate
.attrs
{
35 if !sess
.check_name(attr
, sym
::plugin
) {
39 for plugin
in attr
.meta_item_list().unwrap_or_default() {
40 match plugin
.ident() {
41 Some(ident
) if plugin
.is_word() => {
42 load_plugin(&mut plugins
, sess
, metadata_loader
, ident
)
44 _
=> call_malformed_plugin_attribute(sess
, plugin
.span()),
53 plugins
: &mut Vec
<PluginRegistrarFn
>,
55 metadata_loader
: &dyn MetadataLoader
,
58 let (lib
, disambiguator
) =
59 locator
::find_plugin_registrar(sess
, metadata_loader
, ident
.span
, ident
.name
);
60 let symbol
= sess
.generate_plugin_registrar_symbol(disambiguator
);
61 let fun
= dylink_registrar(sess
, ident
.span
, lib
, symbol
);
65 // Dynamically link a registrar function into the compiler process.
71 ) -> PluginRegistrarFn
{
72 use rustc_metadata
::dynamic_lib
::DynamicLibrary
;
74 // Make sure the path contains a / or the linker will search for it.
75 let path
= env
::current_dir().unwrap().join(&path
);
77 let lib
= match DynamicLibrary
::open(&path
) {
79 // this is fatal: there are almost certainly macros we need
80 // inside this crate, so continue would spew "macro undefined"
82 Err(err
) => sess
.span_fatal(span
, &err
),
86 let registrar
= match lib
.symbol(&symbol
) {
87 Ok(registrar
) => mem
::transmute
::<*mut u8, PluginRegistrarFn
>(registrar
),
88 // again fatal if we can't register macros
89 Err(err
) => sess
.span_fatal(span
, &err
),
92 // Intentionally leak the dynamic library. We can't ever unload it
93 // since the library can make things that will live arbitrarily long
94 // (e.g., an @-box cycle or a thread).