Auto merge of #85296 - bjorn3:plugin_cleanup, r=petrochenkov

Plugin interface cleanup

The first commit performs two uncontroversial cleanups. The second commit removes `#[plugin_registrar]` and instead requires you to export a `__rustc_plugin_registrar` function, this will require a change to servo's script_plugins (cc `@jdm)`
This commit is contained in:
bors 2021-08-12 04:30:41 +00:00
commit eb2226b1f1
35 changed files with 287 additions and 556 deletions

View File

@ -375,14 +375,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::Fn(..) => {
if self.sess.contains_name(&i.attrs[..], sym::plugin_registrar) {
gate_feature_post!(
&self,
plugin_registrar,
i.span,
"compiler plugins are experimental and possibly buggy"
);
}
if self.sess.contains_name(&i.attrs[..], sym::start) {
gate_feature_post!(
&self,

View File

@ -137,10 +137,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
reachable_non_generics.insert(id.to_def_id(), SymbolExportLevel::C);
}
if let Some(id) = tcx.plugin_registrar_fn(()) {
reachable_non_generics.insert(id.to_def_id(), SymbolExportLevel::C);
}
reachable_non_generics
}

View File

@ -281,9 +281,6 @@ declare_features! (
// feature-group-start: actual feature gates
// -------------------------------------------------------------------------
/// Allows using `#[plugin_registrar]` on functions.
(active, plugin_registrar, "1.0.0", Some(29597), None),
/// Allows using `#![plugin(myplugin)]`.
(active, plugin, "1.0.0", Some(29597), None),

View File

@ -291,18 +291,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
// Plugins:
(
sym::plugin_registrar, Normal, template!(Word),
Gated(
Stability::Deprecated(
"https://github.com/rust-lang/rust/pull/64675",
Some("may be removed in a future compiler version"),
),
sym::plugin_registrar,
"compiler plugins are deprecated",
cfg_fn!(plugin_registrar)
)
),
(
sym::plugin, CrateLevel, template!(List: "name"),
Gated(

View File

@ -139,6 +139,9 @@ declare_features! (
/// Allows the definition of `const` functions with some advanced features.
(removed, const_fn, "1.54.0", Some(57563), None,
Some("split into finer-grained feature gates")),
/// Allows using `#[plugin_registrar]` on functions.
(removed, plugin_registrar, "1.54.0", Some(29597), None,
Some("a __rustc_plugin_registrar symbol must now be defined instead")),
/// Allows `#[doc(include = "some-file")]`.
(removed, external_doc, "1.54.0", Some(44732), None,

View File

@ -741,7 +741,6 @@ pub static DEFAULT_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| {
let providers = &mut Providers::default();
providers.analysis = analysis;
proc_macro_decls::provide(providers);
plugin::build::provide(providers);
rustc_middle::hir::provide(providers);
mir::provide(providers);
mir_build::provide(providers);
@ -856,8 +855,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
{
entry_point = sess.time("looking_for_entry_point", || tcx.entry_fn(()));
sess.time("looking_for_plugin_registrar", || tcx.ensure().plugin_registrar_fn(()));
sess.time("looking_for_derive_registrar", || {
tcx.ensure().proc_macro_decls_static(())
});

View File

@ -226,7 +226,7 @@ use rustc_session::config::{self, CrateType};
use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
use rustc_session::search_paths::PathKind;
use rustc_session::utils::CanonicalizedPath;
use rustc_session::{Session, StableCrateId};
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use rustc_target::spec::{Target, TargetTriple};
@ -787,7 +787,7 @@ pub fn find_plugin_registrar(
metadata_loader: &dyn MetadataLoader,
span: Span,
name: Symbol,
) -> (PathBuf, StableCrateId) {
) -> PathBuf {
match find_plugin_registrar_impl(sess, metadata_loader, name) {
Ok(res) => res,
// `core` is always available if we got as far as loading plugins.
@ -799,7 +799,7 @@ fn find_plugin_registrar_impl<'a>(
sess: &'a Session,
metadata_loader: &dyn MetadataLoader,
name: Symbol,
) -> Result<(PathBuf, StableCrateId), CrateError> {
) -> Result<PathBuf, CrateError> {
info!("find plugin registrar `{}`", name);
let mut locator = CrateLocator::new(
sess,
@ -816,7 +816,7 @@ fn find_plugin_registrar_impl<'a>(
match locator.maybe_load_library_crate()? {
Some(library) => match library.source.dylib {
Some(dylib) => Ok((dylib.0, library.metadata.get_root().stable_crate_id())),
Some(dylib) => Ok(dylib.0),
None => Err(CrateError::NonDylibPlugin(name)),
},
None => Err(locator.into_error()),

View File

@ -1252,9 +1252,6 @@ rustc_queries! {
query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> {
desc { "looking up the entry function of a crate" }
}
query plugin_registrar_fn(_: ()) -> Option<LocalDefId> {
desc { "looking up the plugin registrar for a crate" }
}
query proc_macro_decls_static(_: ()) -> Option<LocalDefId> {
desc { "looking up the derive registrar for a crate" }
}

View File

@ -1,57 +0,0 @@
//! Used by `rustc` when compiling a plugin crate.
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
use rustc_span::Span;
struct RegistrarFinder<'tcx> {
tcx: TyCtxt<'tcx>,
registrars: Vec<(LocalDefId, Span)>,
}
impl<'v, 'tcx> ItemLikeVisitor<'v> for RegistrarFinder<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
if let hir::ItemKind::Fn(..) = item.kind {
let attrs = self.tcx.hir().attrs(item.hir_id());
if self.tcx.sess.contains_name(attrs, sym::plugin_registrar) {
self.registrars.push((item.def_id, item.span));
}
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
}
/// Finds the function marked with `#[plugin_registrar]`, if any.
fn plugin_registrar_fn(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
let mut finder = RegistrarFinder { tcx, registrars: Vec::new() };
tcx.hir().krate().visit_all_item_likes(&mut finder);
let (def_id, span) = finder.registrars.pop()?;
if !finder.registrars.is_empty() {
let diagnostic = tcx.sess.diagnostic();
let mut e = diagnostic.struct_err("multiple plugin registration functions found");
e.span_note(span, "one is here");
for &(_, span) in &finder.registrars {
e.span_note(span, "one is here");
}
e.emit();
diagnostic.abort_if_errors();
unreachable!();
}
Some(def_id)
}
pub fn provide(providers: &mut Providers) {
*providers = Providers { plugin_registrar_fn, ..*providers };
}

View File

@ -12,7 +12,6 @@
use rustc_lint::LintStore;
pub mod build;
pub mod load;
/// Structure used to register plugins.

View File

@ -55,20 +55,13 @@ fn load_plugin(
metadata_loader: &dyn MetadataLoader,
ident: Ident,
) {
let (lib, disambiguator) =
locator::find_plugin_registrar(sess, metadata_loader, ident.span, ident.name);
let symbol = sess.generate_plugin_registrar_symbol(disambiguator);
let fun = dylink_registrar(sess, ident.span, lib, symbol);
let lib = locator::find_plugin_registrar(sess, metadata_loader, ident.span, ident.name);
let fun = dylink_registrar(sess, ident.span, lib);
plugins.push(fun);
}
// Dynamically link a registrar function into the compiler process.
fn dylink_registrar(
sess: &Session,
span: Span,
path: PathBuf,
symbol: String,
) -> PluginRegistrarFn {
fn dylink_registrar(sess: &Session, span: Span, path: PathBuf) -> PluginRegistrarFn {
use rustc_metadata::dynamic_lib::DynamicLibrary;
// Make sure the path contains a / or the linker will search for it.
@ -83,7 +76,7 @@ fn dylink_registrar(
};
unsafe {
let registrar = match lib.symbol(&symbol) {
let registrar = match lib.symbol("__rustc_plugin_registrar") {
Ok(registrar) => mem::transmute::<*mut u8, PluginRegistrarFn>(registrar),
// again fatal if we can't register macros
Err(err) => sess.span_fatal(span, &err),
@ -91,7 +84,7 @@ fn dylink_registrar(
// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long
// (e.g., an @-box cycle or a thread).
// (e.g., an Rc cycle or a thread).
mem::forget(lib);
registrar

View File

@ -792,12 +792,6 @@ impl Session {
)
}
/// Returns the symbol name for the registrar function,
/// given the crate `Svh` and the function `DefIndex`.
pub fn generate_plugin_registrar_symbol(&self, stable_crate_id: StableCrateId) -> String {
format!("__rustc_plugin_registrar_{:08x}__", stable_crate_id.to_u64())
}
pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String {
format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.to_u64())
}

View File

@ -164,10 +164,6 @@ fn compute_symbol_name(
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
let is_foreign = if let Some(def_id) = def_id.as_local() {
if tcx.plugin_registrar_fn(()) == Some(def_id) {
let stable_crate_id = tcx.sess.local_stable_crate_id();
return tcx.sess.generate_plugin_registrar_symbol(stable_crate_id);
}
if tcx.proc_macro_decls_static(()) == Some(def_id) {
let stable_crate_id = tcx.sess.local_stable_crate_id();
return tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);

View File

@ -1,13 +0,0 @@
# `plugin_registrar`
The tracking issue for this feature is: [#29597]
[#29597]: https://github.com/rust-lang/rust/issues/29597
This feature is part of "compiler plugins." It will often be used with the
[`plugin`] and `rustc_private` features as well. For more details, see
their docs.
[`plugin`]: plugin.md
------------------------

View File

@ -6,9 +6,7 @@ The tracking issue for this feature is: [#29597]
This feature is part of "compiler plugins." It will often be used with the
[`plugin_registrar`] and `rustc_private` features.
[`plugin_registrar`]: plugin-registrar.md
`rustc_private` feature.
------------------------
@ -39,7 +37,6 @@ additional checks for code style, safety, etc. Now let's write a plugin
that warns about any item named `lintme`.
```rust,ignore (requires-stage-2)
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
extern crate rustc_ast;
@ -68,8 +65,8 @@ impl EarlyLintPass for Pass {
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_LINT]);
reg.lint_store.register_early_pass(|| box Pass);
}

View File

@ -1,10 +1,9 @@
// force-host
#![feature(plugin_registrar)]
#![feature(rustc_private)]
extern crate rustc_driver;
use rustc_driver::plugin::Registry;
#[plugin_registrar]
pub fn plugin_registrar(_: &mut Registry) {}
#[no_mangle]
fn __rustc_plugin_registrar(_: &mut Registry) {}

View File

@ -1,10 +1,9 @@
#![feature(box_syntax, plugin, plugin_registrar, rustc_private)]
#![feature(box_syntax, plugin, rustc_private)]
#![crate_type = "dylib"]
extern crate rustc_ast_pretty;
extern crate rustc_driver;
extern crate rustc_hir;
#[macro_use]
extern crate rustc_lint;
#[macro_use]
extern crate rustc_session;
@ -16,11 +15,11 @@ use rustc_driver::plugin::Registry;
use rustc_hir as hir;
use rustc_hir::intravisit;
use rustc_hir::Node;
use rustc_lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_span::source_map;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
reg.lint_store.register_late_pass(|| box MissingAllowedAttrPass);
}

View File

@ -1,6 +1,6 @@
// force-host
#![feature(plugin_registrar, rustc_private)]
#![feature(rustc_private)]
#![feature(box_syntax)]
extern crate rustc_driver;
@ -64,8 +64,8 @@ fake_lint_pass! {
Symbol::intern("crate_grey"), Symbol::intern("crate_green")
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[
&CRATE_NOT_OKAY,
&CRATE_NOT_RED,

View File

@ -1,6 +1,6 @@
// force-host
#![feature(plugin_registrar, rustc_private)]
#![feature(rustc_private)]
#![feature(box_syntax)]
extern crate rustc_driver;
@ -38,8 +38,8 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
reg.lint_store.register_late_pass(|| box Pass);
}

View File

@ -1,6 +1,5 @@
// force-host
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
// Load rustc as a plugin to get macros.
@ -34,8 +33,8 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]);
reg.lint_store.register_late_pass(|| box Pass);
reg.lint_store.register_group(

View File

@ -1,6 +1,5 @@
// force-host
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
extern crate rustc_ast;
@ -29,8 +28,8 @@ impl EarlyLintPass for Pass {
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_LINT]);
reg.lint_store.register_early_pass(|| box Pass);
}

View File

@ -1,4 +1,3 @@
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
extern crate rustc_ast;
@ -44,8 +43,8 @@ impl EarlyLintPass for Pass {
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&TEST_RUSTC_TOOL_LINT, &TEST_LINT, &TEST_GROUP]);
reg.lint_store.register_early_pass(|| box Pass);
reg.lint_store.register_group(

View File

@ -1,6 +1,5 @@
// force-host
#![feature(plugin_registrar)]
#![feature(rustc_private)]
extern crate rustc_middle;
@ -8,5 +7,5 @@ extern crate rustc_driver;
use rustc_driver::plugin::Registry;
#[plugin_registrar]
pub fn plugin_registrar(_reg: &mut Registry) {}
#[no_mangle]
fn __rustc_plugin_registrar(_reg: &mut Registry) {}

View File

@ -0,0 +1,10 @@
#![crate_type = "dylib"]
#![feature(rustc_private)]
extern crate rustc_middle;
extern crate rustc_driver;
use rustc_driver::plugin::Registry;
#[no_mangle]
fn __rustc_plugin_registrar(_: &mut Registry) {}

View File

@ -0,0 +1,10 @@
#![crate_type = "dylib"]
#![feature(rustc_private)]
extern crate rustc_middle;
extern crate rustc_driver;
use rustc_driver::plugin::Registry;
#[no_mangle]
fn __rustc_plugin_registrar(_: &mut Registry) {}

View File

@ -1,6 +1,5 @@
// force-host
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
extern crate rustc_middle;
@ -18,8 +17,8 @@ impl Drop for Foo {
fn drop(&mut self) {}
}
#[plugin_registrar]
pub fn registrar(_: &mut Registry) {
#[no_mangle]
fn __rustc_plugin_registrar(_: &mut Registry) {
thread_local!(static FOO: RefCell<Option<Box<Any+Send>>> = RefCell::new(None));
FOO.with(|s| *s.borrow_mut() = Some(box Foo { foo: 10 } as Box<Any+Send>));
}

View File

@ -1,12 +1,12 @@
// no-prefer-dynamic
#![crate_type = "rlib"]
#![feature(plugin_registrar, rustc_private)]
#![feature(rustc_private)]
extern crate rustc_middle;
extern crate rustc_driver;
use rustc_driver::plugin::Registry;
#[plugin_registrar]
pub fn plugin_registrar(_: &mut Registry) {}
#[no_mangle]
fn __rustc_plugin_registrar(_: &mut Registry) {}

View File

@ -0,0 +1,11 @@
// run-pass
// aux-build:multiple-plugins-1.rs
// aux-build:multiple-plugins-2.rs
// Check that the plugin registrar of multiple plugins doesn't conflict
#![feature(plugin)]
#![plugin(multiple_plugins_1)] //~ WARN use of deprecated attribute `plugin`
#![plugin(multiple_plugins_2)] //~ WARN use of deprecated attribute `plugin`
fn main() {}

View File

@ -0,0 +1,16 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/multiple-plugins.rs:8:1
|
LL | #![plugin(multiple_plugins_1)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/multiple-plugins.rs:9:1
|
LL | #![plugin(multiple_plugins_2)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
warning: 2 warnings emitted

View File

@ -1,11 +0,0 @@
// Test that `#[plugin_registrar]` attribute is gated by `plugin_registrar`
// feature gate.
// the registration function isn't typechecked yet
#[plugin_registrar]
//~^ ERROR compiler plugins are deprecated
//~| WARN use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated
pub fn registrar() {}
//~^ ERROR compiler plugins are experimental and possibly buggy
fn main() {}

View File

@ -1,29 +0,0 @@
error[E0658]: compiler plugins are experimental and possibly buggy
--> $DIR/feature-gate-plugin_registrar.rs:8:1
|
LL | pub fn registrar() {}
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #29597 <https://github.com/rust-lang/rust/issues/29597> for more information
= help: add `#![feature(plugin_registrar)]` to the crate attributes to enable
error[E0658]: compiler plugins are deprecated
--> $DIR/feature-gate-plugin_registrar.rs:5:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #29597 <https://github.com/rust-lang/rust/issues/29597> for more information
= help: add `#![feature(plugin_registrar)]` to the crate attributes to enable
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/feature-gate-plugin_registrar.rs:5:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0658`.

View File

@ -35,18 +35,11 @@
// check-pass
#![feature(test, plugin_registrar)]
#![feature(test)]
#![warn(unused_attributes, unknown_lints)]
//~^ NOTE the lint level is defined here
//~| NOTE the lint level is defined here
// Exception, a gated and deprecated attribute.
#![plugin_registrar]
//~^ WARN unused attribute
//~| WARN use of deprecated attribute
//~| HELP may be removed in a future compiler version
// UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES
#![warn(x5400)] //~ WARN unknown lint: `x5400`
@ -90,6 +83,7 @@
#![crate_id = "10"]
//~^ WARN use of deprecated attribute
//~| HELP remove this attribute
//~| NOTE `#[warn(deprecated)]` on by default
// FIXME(#44232) we should warn that this isn't used.
#![feature(rust1)]
@ -219,35 +213,6 @@ mod macro_export {
//~^ WARN unused attribute
}
#[plugin_registrar]
//~^ WARN unused attribute
//~| WARN use of deprecated attribute
//~| HELP may be removed in a future compiler version
mod plugin_registrar {
mod inner { #![plugin_registrar] }
//~^ WARN unused attribute
//~| WARN use of deprecated attribute
//~| HELP may be removed in a future compiler version
//~| NOTE `#[warn(deprecated)]` on by default
// for `fn f()` case, see gated-plugin_registrar.rs
#[plugin_registrar] struct S;
//~^ WARN unused attribute
//~| WARN use of deprecated attribute
//~| HELP may be removed in a future compiler version
#[plugin_registrar] type T = S;
//~^ WARN unused attribute
//~| WARN use of deprecated attribute
//~| HELP may be removed in a future compiler version
#[plugin_registrar] impl S { }
//~^ WARN unused attribute
//~| WARN use of deprecated attribute
//~| HELP may be removed in a future compiler version
}
// At time of unit test authorship, if compiling without `--test` then
// non-crate-level #[test] attributes seem to be ignored.

View File

@ -1,12 +0,0 @@
// error-pattern: multiple plugin registration functions found
#![feature(plugin_registrar)]
// the registration function isn't typechecked yet
#[plugin_registrar]
pub fn one() {}
#[plugin_registrar]
pub fn two() {}
fn main() {}

View File

@ -1,29 +0,0 @@
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/multiple-plugin-registrars.rs:6:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/multiple-plugin-registrars.rs:9:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
error: multiple plugin registration functions found
|
note: one is here
--> $DIR/multiple-plugin-registrars.rs:10:1
|
LL | pub fn two() {}
| ^^^^^^^^^^^^^^^
note: one is here
--> $DIR/multiple-plugin-registrars.rs:7:1
|
LL | pub fn one() {}
| ^^^^^^^^^^^^^^^
error: aborting due to previous error; 2 warnings emitted