diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md
index 77642a850fae8..386f6008d06aa 100644
--- a/src/doc/rustc/src/lints/listing/warn-by-default.md
+++ b/src/doc/rustc/src/lints/listing/warn-by-default.md
@@ -307,18 +307,6 @@ warning: path statement with no effect
   |
 ```
 
-## plugin-as-library
-
-This lint detects when compiler plugins are used as ordinary library in
-non-plugin crate. Some example code that triggers this lint:
-
-```rust,ignore
-#![feature(plugin)]
-#![plugin(macro_crate_test)]
-
-extern crate macro_crate_test;
-```
-
 ## private-in-public
 
 This lint detects private items in public interfaces not caught by the old implementation. Some
diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index cd1137e762e6b..495cdee62c87d 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -21,15 +21,10 @@ the crate attribute `#![plugin(...)]`.  See the
 `rustc_driver::plugin` documentation for more about the
 mechanics of defining and loading a plugin.
 
-If present, arguments passed as `#![plugin(foo(... args ...))]` are not
-interpreted by rustc itself.  They are provided to the plugin through the
-`Registry`'s `args` method.
-
 In the vast majority of cases, a plugin should *only* be used through
 `#![plugin]` and not through an `extern crate` item.  Linking a plugin would
 pull in all of libsyntax and librustc as dependencies of your crate.  This is
-generally unwanted unless you are building another plugin.  The
-`plugin_as_library` lint checks these guidelines.
+generally unwanted unless you are building another plugin.
 
 The usual practice is to put compiler plugins in their own crate, separate from
 any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 05543f1d2ef73..7f72154e42c61 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -47,8 +47,7 @@ use rustc_error_codes::*;
 /// This is basically the subset of `Context` that we can
 /// build early in the compile pipeline.
 pub struct LintStore {
-    /// Registered lints. The bool is true if the lint was
-    /// added by a plugin.
+    /// Registered lints.
     lints: Vec<&'static Lint>,
 
     /// Constructor functions for each variety of lint pass.
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index fbfae721bbe91..d2ac5436cc802 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1364,8 +1364,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "enable queries of the dependency graph for regression testing"),
     no_analysis: bool = (false, parse_bool, [UNTRACKED],
         "parse and expand the source, but run no analysis"),
-    extra_plugins: Vec<String> = (Vec::new(), parse_list, [TRACKED],
-        "load extra plugins"),
     unstable_options: bool = (false, parse_bool, [UNTRACKED],
         "adds unstable command line options to rustc interface"),
     force_overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 74ba83d0ee4d4..f673ea3e771c5 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -76,7 +76,6 @@ pub struct Session {
     /// (sub)diagnostics that have been set once, but should not be set again,
     /// in order to avoid redundantly verbose output (Issue #24690, #44953).
     pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
-    pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
     pub crate_types: Once<Vec<config::CrateType>>,
     /// The `crate_disambiguator` is constructed out of all the `-C metadata`
     /// arguments passed to the compiler. Its value together with the crate-name
@@ -1149,7 +1148,6 @@ fn build_session_(
         local_crate_source_file,
         working_dir,
         one_time_diagnostics: Default::default(),
-        plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
         crate_types: Once::new(),
         crate_disambiguator: Once::new(),
         features: Once::new(),
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 5dfb04a4436e6..07ac76cec990b 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -365,20 +365,6 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
 
             add_sanitizer_passes(config, &mut extra_passes);
 
-            for pass_name in &cgcx.plugin_passes {
-                if let Some(pass) = find_pass(pass_name) {
-                    extra_passes.push(pass);
-                } else {
-                    diag_handler.err(&format!("a plugin asked for LLVM pass \
-                                               `{}` but LLVM does not \
-                                               recognize it", pass_name));
-                }
-
-                if pass_name == "name-anon-globals" {
-                    have_name_anon_globals_pass = true;
-                }
-            }
-
             // Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
             // to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
             // we'll get errors in LLVM.
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 9d3e57449f899..863b41ec15ec0 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -231,8 +231,6 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     pub total_cgus: usize,
     // Handler to use for diagnostics produced during codegen.
     pub diag_emitter: SharedEmitter,
-    // LLVM passes added by plugins.
-    pub plugin_passes: Vec<String>,
     // LLVM optimizations for which we want to print remarks.
     pub remark: Passes,
     // Worker thread number
@@ -1028,7 +1026,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
         time_passes: sess.time_extended(),
         prof: sess.prof.clone(),
         exported_symbols,
-        plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
         remark: sess.opts.cg.remark.clone(),
         worker: 0,
         incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs
index f72df00a8e821..9c936492cbded 100644
--- a/src/librustc_feature/builtin_attrs.rs
+++ b/src/librustc_feature/builtin_attrs.rs
@@ -283,7 +283,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         )
     ),
     (
-        sym::plugin, CrateLevel, template!(List: "name|name(args)"),
+        sym::plugin, CrateLevel, template!(List: "name"),
         Gated(
             Stability::Deprecated(
                 "https://github.com/rust-lang/rust/pull/64675",
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index e953a64f1906f..f985a5b37558c 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -30,7 +30,6 @@ use rustc_mir as mir;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
 use rustc_passes::{self, ast_validation, hir_stats, layout_test};
 use rustc_plugin_impl as plugin;
-use rustc_plugin_impl::registry::Registry;
 use rustc_privacy;
 use rustc_resolve::{Resolver, ResolverArenas};
 use rustc_traits;
@@ -106,8 +105,7 @@ declare_box_region_type!(
     (&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
 );
 
-/// Runs the "early phases" of the compiler: initial `cfg` processing,
-/// loading compiler plugins (including those from `addl_plugins`),
+/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
 /// syntax expansion, secondary `cfg` expansion, synthesis of a test
 /// harness if one is to be provided, injection of a dependency on the
 /// standard library and prelude, and name resolution.
@@ -209,33 +207,22 @@ pub fn register_plugins<'a>(
         middle::recursion_limit::update_limits(sess, &krate);
     });
 
-    let registrars = time(sess, "plugin loading", || {
-        plugin::load::load_plugins(
-            sess,
-            metadata_loader,
-            &krate,
-            Some(sess.opts.debugging_opts.extra_plugins.clone()),
-        )
-    });
-
     let mut lint_store = rustc_lint::new_lint_store(
         sess.opts.debugging_opts.no_interleave_lints,
         sess.unstable_options(),
     );
+    register_lints(&sess, &mut lint_store);
 
-    (register_lints)(&sess, &mut lint_store);
-
-    let mut registry = Registry::new(sess, &mut lint_store, krate.span);
-
+    let registrars = time(sess, "plugin loading", || {
+        plugin::load::load_plugins(sess, metadata_loader, &krate)
+    });
     time(sess, "plugin registration", || {
+        let mut registry = plugin::Registry { lint_store: &mut lint_store };
         for registrar in registrars {
-            registry.args_hidden = Some(registrar.args);
-            (registrar.fun)(&mut registry);
+            registrar(&mut registry);
         }
     });
 
-    *sess.plugin_llvm_passes.borrow_mut() = registry.llvm_passes;
-
     Ok((krate, Lrc::new(lint_store)))
 }
 
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index d39a5d3a07345..4c630b56cb4ce 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -650,10 +650,6 @@ fn test_debugging_options_tracking_hash() {
     opts.debugging_opts.continue_parse_after_error = true;
     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
-    opts = reference.clone();
-    opts.debugging_opts.extra_plugins = vec![String::from("plugin1"), String::from("plugin2")];
-    assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
-
     opts = reference.clone();
     opts.debugging_opts.force_overflow_checks = Some(true);
     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 5d3a6cccc4e73..b08a095beac4e 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -24,7 +24,7 @@
 use std::fmt::Write;
 
 use rustc::hir::def::{Res, DefKind};
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::DefId;
 use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx};
 use rustc::{lint, util};
 use rustc::lint::FutureIncompatibleInfo;
@@ -800,45 +800,6 @@ impl EarlyLintPass for UnusedDocComment {
     }
 }
 
-declare_lint! {
-    PLUGIN_AS_LIBRARY,
-    Warn,
-    "compiler plugin used as ordinary library in non-plugin crate"
-}
-
-declare_lint_pass!(PluginAsLibrary => [PLUGIN_AS_LIBRARY]);
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary {
-    fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
-        if cx.tcx.plugin_registrar_fn(LOCAL_CRATE).is_some() {
-            // We're compiling a plugin; it's fine to link other plugins.
-            return;
-        }
-
-        match it.kind {
-            hir::ItemKind::ExternCrate(..) => (),
-            _ => return,
-        };
-
-        let def_id = cx.tcx.hir().local_def_id(it.hir_id);
-        let prfn = match cx.tcx.extern_mod_stmt_cnum(def_id) {
-            Some(cnum) => cx.tcx.plugin_registrar_fn(cnum),
-            None => {
-                // Probably means we aren't linking the crate for some reason.
-                //
-                // Not sure if / when this could happen.
-                return;
-            }
-        };
-
-        if prfn.is_some() {
-            cx.span_lint(PLUGIN_AS_LIBRARY,
-                         it.span,
-                         "compiler plugin used as an ordinary library");
-        }
-    }
-}
-
 declare_lint! {
     NO_MANGLE_CONST_ITEMS,
     Deny,
@@ -1268,7 +1229,6 @@ declare_lint_pass!(
         MISSING_DEBUG_IMPLEMENTATIONS,
         ANONYMOUS_PARAMETERS,
         UNUSED_DOC_COMMENTS,
-        PLUGIN_AS_LIBRARY,
         NO_MANGLE_CONST_ITEMS,
         NO_MANGLE_GENERIC_ITEMS,
         MUTABLE_TRANSMUTES,
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 7e8dc1d167984..ab4063c421cd2 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -157,8 +157,6 @@ macro_rules! late_lint_mod_passes {
             // Depends on types used in type definitions
             MissingCopyImplementations: MissingCopyImplementations,
 
-            PluginAsLibrary: PluginAsLibrary,
-
             // Depends on referenced function signatures in expressions
             MutableTransmutes: MutableTransmutes,
 
@@ -350,6 +348,7 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
         "converted into hard error, see https://github.com/rust-lang/rust/issues/35896");
     store.register_removed("nested_impl_trait",
         "converted into hard error, see https://github.com/rust-lang/rust/issues/59014");
+    store.register_removed("plugin_as_library", "plugins have been deprecated and retired");
 }
 
 fn register_internals(store: &mut lint::LintStore) {
diff --git a/src/librustc_plugin_impl/lib.rs b/src/librustc_plugin_impl/lib.rs
index f4e90b7b7da3d..5c4ea39aecc92 100644
--- a/src/librustc_plugin_impl/lib.rs
+++ b/src/librustc_plugin_impl/lib.rs
@@ -10,10 +10,16 @@
 
 #![feature(nll)]
 
-#![recursion_limit="256"]
+use rustc::lint::LintStore;
 
-pub use registry::Registry;
-
-pub mod registry;
-pub mod load;
 pub mod build;
+pub mod load;
+
+/// Structure used to register plugins.
+///
+/// A plugin registrar function takes an `&mut Registry` and should call
+/// methods to register its plugins.
+pub struct Registry<'a> {
+    /// The `LintStore` allows plugins to register new lints.
+    pub lint_store: &'a mut LintStore,
+}
diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs
index 31b3b07c3e1fb..0bd91076592bf 100644
--- a/src/librustc_plugin_impl/load.rs
+++ b/src/librustc_plugin_impl/load.rs
@@ -3,33 +3,21 @@
 use rustc::middle::cstore::MetadataLoader;
 use rustc::session::Session;
 use rustc_metadata::locator;
-use crate::registry::Registry;
+use crate::Registry;
 
 use std::borrow::ToOwned;
 use std::env;
 use std::mem;
 use std::path::PathBuf;
-use syntax::ast;
+use syntax::ast::{Crate, Ident};
 use syntax::struct_span_err;
-use syntax::symbol::{Symbol, kw, sym};
-use syntax_pos::{Span, DUMMY_SP};
+use syntax::symbol::sym;
+use syntax_pos::Span;
 
 use rustc_error_codes::*;
 
 /// Pointer to a registrar function.
-pub type PluginRegistrarFun =
-    fn(&mut Registry<'_>);
-
-pub struct PluginRegistrar {
-    pub fun: PluginRegistrarFun,
-    pub args: Vec<ast::NestedMetaItem>,
-}
-
-struct PluginLoader<'a> {
-    sess: &'a Session,
-    metadata_loader: &'a dyn MetadataLoader,
-    plugins: Vec<PluginRegistrar>,
-}
+type PluginRegistrarFn = fn(&mut Registry<'_>);
 
 fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
     struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
@@ -40,98 +28,76 @@ fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
 /// Read plugin metadata and dynamically load registrar functions.
 pub fn load_plugins(sess: &Session,
                     metadata_loader: &dyn MetadataLoader,
-                    krate: &ast::Crate,
-                    addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
-    let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };
-
-    // do not report any error now. since crate attributes are
-    // not touched by expansion, every use of plugin without
-    // the feature enabled will result in an error later...
-    if sess.features_untracked().plugin {
-        for attr in &krate.attrs {
-            if !attr.check_name(sym::plugin) {
-                continue;
-            }
+                    krate: &Crate) -> Vec<PluginRegistrarFn> {
+    let mut plugins = Vec::new();
 
-            let plugins = match attr.meta_item_list() {
-                Some(xs) => xs,
-                None => continue,
-            };
-
-            for plugin in plugins {
-                // plugins must have a name and can't be key = value
-                let name = plugin.name_or_empty();
-                if name != kw::Invalid && !plugin.is_value_str() {
-                    let args = plugin.meta_item_list().map(ToOwned::to_owned);
-                    loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
-                } else {
-                    call_malformed_plugin_attribute(sess, attr.span);
-                }
-            }
+    for attr in &krate.attrs {
+        if !attr.check_name(sym::plugin) {
+            continue;
         }
-    }
 
-    if let Some(plugins) = addl_plugins {
-        for plugin in plugins {
-            loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
+        for plugin in attr.meta_item_list().unwrap_or_default() {
+            match plugin.ident() {
+                Some(ident) if plugin.is_word() =>
+                    load_plugin(&mut plugins, sess, metadata_loader, ident),
+                _ => call_malformed_plugin_attribute(sess, plugin.span()),
+            }
         }
     }
 
-    loader.plugins
+    plugins
 }
 
-impl<'a> PluginLoader<'a> {
-    fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
-        let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);
-
-        if let Some((lib, disambiguator)) = registrar {
-            let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
-            let fun = self.dylink_registrar(span, lib, symbol);
-            self.plugins.push(PluginRegistrar {
-                fun,
-                args,
-            });
-        }
+fn load_plugin(plugins: &mut Vec<PluginRegistrarFn>,
+               sess: &Session,
+               metadata_loader: &dyn MetadataLoader,
+               ident: Ident) {
+    let registrar = locator::find_plugin_registrar(sess, metadata_loader, ident.span, ident.name);
+
+    if let Some((lib, disambiguator)) = registrar {
+        let symbol = sess.generate_plugin_registrar_symbol(disambiguator);
+        let fun = dylink_registrar(sess, ident.span, lib, symbol);
+        plugins.push(fun);
     }
+}
 
-    // Dynamically link a registrar function into the compiler process.
-    fn dylink_registrar(&mut self,
-                        span: Span,
-                        path: PathBuf,
-                        symbol: String) -> PluginRegistrarFun {
-        use rustc_metadata::dynamic_lib::DynamicLibrary;
-
-        // Make sure the path contains a / or the linker will search for it.
-        let path = env::current_dir().unwrap().join(&path);
-
-        let lib = match DynamicLibrary::open(Some(&path)) {
-            Ok(lib) => lib,
-            // this is fatal: there are almost certainly macros we need
-            // inside this crate, so continue would spew "macro undefined"
-            // errors
-            Err(err) => {
-                self.sess.span_fatal(span, &err)
-            }
-        };
-
-        unsafe {
-            let registrar =
-                match lib.symbol(&symbol) {
-                    Ok(registrar) => {
-                        mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
-                    }
-                    // again fatal if we can't register macros
-                    Err(err) => {
-                        self.sess.span_fatal(span, &err)
-                    }
-                };
-
-            // 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).
-            mem::forget(lib);
-
-            registrar
+// Dynamically link a registrar function into the compiler process.
+fn dylink_registrar(sess: &Session,
+                    span: Span,
+                    path: PathBuf,
+                    symbol: String) -> PluginRegistrarFn {
+    use rustc_metadata::dynamic_lib::DynamicLibrary;
+
+    // Make sure the path contains a / or the linker will search for it.
+    let path = env::current_dir().unwrap().join(&path);
+
+    let lib = match DynamicLibrary::open(Some(&path)) {
+        Ok(lib) => lib,
+        // this is fatal: there are almost certainly macros we need
+        // inside this crate, so continue would spew "macro undefined"
+        // errors
+        Err(err) => {
+            sess.span_fatal(span, &err)
         }
+    };
+
+    unsafe {
+        let registrar =
+            match lib.symbol(&symbol) {
+                Ok(registrar) => {
+                    mem::transmute::<*mut u8, PluginRegistrarFn>(registrar)
+                }
+                // again fatal if we can't register macros
+                Err(err) => {
+                    sess.span_fatal(span, &err)
+                }
+            };
+
+        // 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).
+        mem::forget(lib);
+
+        registrar
     }
 }
diff --git a/src/librustc_plugin_impl/registry.rs b/src/librustc_plugin_impl/registry.rs
deleted file mode 100644
index bc684d59e5a99..0000000000000
--- a/src/librustc_plugin_impl/registry.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-//! Used by plugin crates to tell `rustc` about the plugins they provide.
-
-use rustc::lint::LintStore;
-use rustc::session::Session;
-use syntax::ast;
-use syntax_pos::Span;
-
-use std::borrow::ToOwned;
-
-/// Structure used to register plugins.
-///
-/// A plugin registrar function takes an `&mut Registry` and should call
-/// methods to register its plugins.
-///
-/// This struct has public fields and other methods for use by `rustc`
-/// itself. They are not documented here, and plugin authors should
-/// not use them.
-pub struct Registry<'a> {
-    /// Compiler session. Useful if you want to emit diagnostic messages
-    /// from the plugin registrar.
-    pub sess: &'a Session,
-
-    /// The `LintStore` allows plugins to register new lints.
-    pub lint_store: &'a mut LintStore,
-
-    #[doc(hidden)]
-    pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
-
-    #[doc(hidden)]
-    pub krate_span: Span,
-
-    #[doc(hidden)]
-    pub llvm_passes: Vec<String>,
-}
-
-impl<'a> Registry<'a> {
-    #[doc(hidden)]
-    pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
-        Registry {
-            sess,
-            lint_store,
-            args_hidden: None,
-            krate_span,
-            llvm_passes: vec![],
-        }
-    }
-
-    /// Gets the plugin's arguments, if any.
-    ///
-    /// These are specified inside the `plugin` crate attribute as
-    ///
-    /// ```no_run
-    /// #![plugin(my_plugin_name(... args ...))]
-    /// ```
-    ///
-    /// Returns empty slice in case the plugin was loaded
-    /// with `--extra-plugins`
-    pub fn args(&self) -> &[ast::NestedMetaItem] {
-        self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
-    }
-
-    /// Register an LLVM pass.
-    ///
-    /// Registration with LLVM itself is handled through static C++ objects with
-    /// constructors. This method simply adds a name to the list of passes to
-    /// execute.
-    pub fn register_llvm_pass(&mut self, name: &str) {
-        self.llvm_passes.push(name.to_owned());
-    }
-}
diff --git a/src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs b/src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs
deleted file mode 100644
index 2ff1c2e363d50..0000000000000
--- a/src/test/ui-fulldeps/auxiliary/llvm-pass-plugin.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// force-host
-
-#![feature(plugin_registrar)]
-#![feature(rustc_private)]
-
-extern crate rustc;
-extern crate rustc_driver;
-
-use rustc_driver::plugin::Registry;
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    // This pass is built in to LLVM.
-    //
-    // Normally, we would name a pass that was registered through
-    // C++ static object constructors in the same .so file as the
-    // plugin registrar.
-    reg.register_llvm_pass("gvn");
-}
diff --git a/src/test/ui/feature-gates/feature-gate-plugin.rs b/src/test/ui-fulldeps/feature-gate-plugin.rs
similarity index 60%
rename from src/test/ui/feature-gates/feature-gate-plugin.rs
rename to src/test/ui-fulldeps/feature-gate-plugin.rs
index 8904ec0448ada..85eaf53364315 100644
--- a/src/test/ui/feature-gates/feature-gate-plugin.rs
+++ b/src/test/ui-fulldeps/feature-gate-plugin.rs
@@ -1,6 +1,7 @@
-// Test that `#![plugin(...)]` attribute is gated by `plugin` feature gate
+// aux-build:empty-plugin.rs
+// ignore-stage1
 
-#![plugin(foo)]
+#![plugin(empty_plugin)]
 //~^ ERROR compiler plugins are deprecated
 //~| WARN use of deprecated attribute `plugin`: compiler plugins are deprecated
 
diff --git a/src/test/ui/feature-gates/feature-gate-plugin.stderr b/src/test/ui-fulldeps/feature-gate-plugin.stderr
similarity index 67%
rename from src/test/ui/feature-gates/feature-gate-plugin.stderr
rename to src/test/ui-fulldeps/feature-gate-plugin.stderr
index f89ddf995c49e..c922325c341ea 100644
--- a/src/test/ui/feature-gates/feature-gate-plugin.stderr
+++ b/src/test/ui-fulldeps/feature-gate-plugin.stderr
@@ -1,17 +1,17 @@
 error[E0658]: compiler plugins are deprecated
-  --> $DIR/feature-gate-plugin.rs:3:1
+  --> $DIR/feature-gate-plugin.rs:4:1
    |
-LL | #![plugin(foo)]
-   | ^^^^^^^^^^^^^^^
+LL | #![plugin(empty_plugin)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29597
    = help: add `#![feature(plugin)]` to the crate attributes to enable
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/feature-gate-plugin.rs:3:1
+  --> $DIR/feature-gate-plugin.rs:4:1
    |
-LL | #![plugin(foo)]
-   | ^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+LL | #![plugin(empty_plugin)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
    |
    = note: `#[warn(deprecated)]` on by default
 
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs
index fd681536b5b2b..0bd95dfbd14a9 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs
@@ -1,9 +1,9 @@
-// run-pass
+// check-pass
 // aux-build:lint-plugin-test.rs
 // ignore-stage1
-// compile-flags: -Z extra-plugins=lint_plugin_test
+// compile-flags: -Z crate-attr=plugin(lint_plugin_test)
 
-#![allow(dead_code)]
+#![feature(plugin)]
 
 fn lintme() { } //~ WARNING item is named 'lintme'
 
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
index 5a6b35433ac98..1263a0efe624f 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
@@ -1,3 +1,11 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> <crate attribute>:1:1
+   |
+LL | plugin(lint_plugin_test)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 warning: item is named 'lintme'
   --> $DIR/lint-plugin-cmdline-load.rs:8:1
    |
diff --git a/src/test/ui-fulldeps/llvm-pass-plugin.rs b/src/test/ui-fulldeps/llvm-pass-plugin.rs
deleted file mode 100644
index fa5cbc1e80830..0000000000000
--- a/src/test/ui-fulldeps/llvm-pass-plugin.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-pass
-// aux-build:llvm-pass-plugin.rs
-// ignore-stage1
-
-#![feature(plugin)]
-#![plugin(llvm_pass_plugin)] //~ WARNING compiler plugins are deprecated
-
-pub fn main() { }
diff --git a/src/test/ui-fulldeps/llvm-pass-plugin.stderr b/src/test/ui-fulldeps/llvm-pass-plugin.stderr
deleted file mode 100644
index 61b53bb2b7cdf..0000000000000
--- a/src/test/ui-fulldeps/llvm-pass-plugin.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/llvm-pass-plugin.rs:6:1
-   |
-LL | #![plugin(llvm_pass_plugin)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
diff --git a/src/test/ui-fulldeps/macro-crate-multi-decorator.rs b/src/test/ui-fulldeps/macro-crate-multi-decorator.rs
index e396cf0161557..f21617be5d26f 100644
--- a/src/test/ui-fulldeps/macro-crate-multi-decorator.rs
+++ b/src/test/ui-fulldeps/macro-crate-multi-decorator.rs
@@ -1,9 +1,4 @@
-// run-pass
-
-#![allow(plugin_as_library)]
-#![allow(dead_code)]
-#![allow(unused_variables)]
-#![allow(unused_imports)]
+// check-pass
 // aux-build:macro-crate-test.rs
 // ignore-stage1
 
diff --git a/src/test/ui-fulldeps/plugin-args-1.rs b/src/test/ui-fulldeps/plugin-args-1.rs
deleted file mode 100644
index 1865819053ef6..0000000000000
--- a/src/test/ui-fulldeps/plugin-args-1.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// check-pass
-// aux-build:empty-plugin.rs
-// ignore-stage1
-
-#![feature(plugin)]
-#![plugin(empty_plugin)] //~ WARNING compiler plugins are deprecated
-
-fn main() {}
diff --git a/src/test/ui-fulldeps/plugin-args-1.stderr b/src/test/ui-fulldeps/plugin-args-1.stderr
deleted file mode 100644
index 4e82961acc218..0000000000000
--- a/src/test/ui-fulldeps/plugin-args-1.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/plugin-args-1.rs:6:1
-   |
-LL | #![plugin(empty_plugin)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
diff --git a/src/test/ui-fulldeps/plugin-args-2.rs b/src/test/ui-fulldeps/plugin-args-2.rs
deleted file mode 100644
index c4bd1916b8542..0000000000000
--- a/src/test/ui-fulldeps/plugin-args-2.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// check-pass
-// aux-build:empty-plugin.rs
-// ignore-stage1
-
-#![feature(plugin)]
-#![plugin(empty_plugin())] //~ WARNING compiler plugins are deprecated
-
-fn main() {}
diff --git a/src/test/ui-fulldeps/plugin-args-2.stderr b/src/test/ui-fulldeps/plugin-args-2.stderr
deleted file mode 100644
index 92bd69b0e4b32..0000000000000
--- a/src/test/ui-fulldeps/plugin-args-2.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/plugin-args-2.rs:6:1
-   |
-LL | #![plugin(empty_plugin())]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
diff --git a/src/test/ui-fulldeps/plugin-args-3.rs b/src/test/ui-fulldeps/plugin-args-3.rs
deleted file mode 100644
index c8818cc6c3178..0000000000000
--- a/src/test/ui-fulldeps/plugin-args-3.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// check-pass
-// aux-build:empty-plugin.rs
-// ignore-stage1
-
-#![feature(plugin)]
-#![plugin(empty_plugin(hello(there), how(are="you")))] //~ WARNING compiler plugins are deprecated
-
-fn main() {}
diff --git a/src/test/ui-fulldeps/plugin-args-3.stderr b/src/test/ui-fulldeps/plugin-args-3.stderr
deleted file mode 100644
index 278853e0881ba..0000000000000
--- a/src/test/ui-fulldeps/plugin-args-3.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/plugin-args-3.rs:6:1
-   |
-LL | #![plugin(empty_plugin(hello(there), how(are="you")))]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
diff --git a/src/test/ui-fulldeps/plugin-args.rs b/src/test/ui-fulldeps/plugin-args.rs
new file mode 100644
index 0000000000000..488f2b775bf0b
--- /dev/null
+++ b/src/test/ui-fulldeps/plugin-args.rs
@@ -0,0 +1,9 @@
+// aux-build:empty-plugin.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(empty_plugin(args))]
+//~^ ERROR malformed `plugin` attribute
+//~| WARNING compiler plugins are deprecated
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/plugin-args.stderr b/src/test/ui-fulldeps/plugin-args.stderr
new file mode 100644
index 0000000000000..2b9094c4c44b3
--- /dev/null
+++ b/src/test/ui-fulldeps/plugin-args.stderr
@@ -0,0 +1,16 @@
+error[E0498]: malformed `plugin` attribute
+  --> $DIR/plugin-args.rs:5:11
+   |
+LL | #![plugin(empty_plugin(args))]
+   |           ^^^^^^^^^^^^^^^^^^ malformed attribute
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/plugin-args.rs:5:1
+   |
+LL | #![plugin(empty_plugin(args))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to previous error
+
diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs
index fa7826c9df76e..f231efc0a9a16 100644
--- a/src/test/ui-fulldeps/plugin-as-extern-crate.rs
+++ b/src/test/ui-fulldeps/plugin-as-extern-crate.rs
@@ -1,11 +1,10 @@
+// check-pass
 // aux-build:empty-plugin.rs
 // ignore-cross-compile
 //
 // empty_plugin will not compile on a cross-compiled target because
 // libsyntax is not compiled for it.
 
-#![deny(plugin_as_library)]
+extern crate empty_plugin; // OK, plugin crates are still crates
 
-extern crate empty_plugin; //~ ERROR compiler plugin used as an ordinary library
-
-fn main() { }
+fn main() {}
diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr
deleted file mode 100644
index d2fbb5d35172c..0000000000000
--- a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: compiler plugin used as an ordinary library
-  --> $DIR/plugin-as-extern-crate.rs:9:1
-   |
-LL | extern crate empty_plugin;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/plugin-as-extern-crate.rs:7:9
-   |
-LL | #![deny(plugin_as_library)]
-   |         ^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/malformed/malformed-plugin-1.stderr b/src/test/ui/malformed/malformed-plugin-1.stderr
index 3860864bd1336..2a4f772850e92 100644
--- a/src/test/ui/malformed/malformed-plugin-1.stderr
+++ b/src/test/ui/malformed/malformed-plugin-1.stderr
@@ -2,7 +2,7 @@ error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-1.rs:2:1
    |
 LL | #![plugin]
-   | ^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
+   | ^^^^^^^^^^ help: must be of the form: `#[plugin(name)]`
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
   --> $DIR/malformed-plugin-1.rs:2:1
diff --git a/src/test/ui/malformed/malformed-plugin-2.stderr b/src/test/ui/malformed/malformed-plugin-2.stderr
index e4bca93f13b35..fe116a4061025 100644
--- a/src/test/ui/malformed/malformed-plugin-2.stderr
+++ b/src/test/ui/malformed/malformed-plugin-2.stderr
@@ -2,7 +2,7 @@ error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-2.rs:2:1
    |
 LL | #![plugin="bleh"]
-   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name)]`
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
   --> $DIR/malformed-plugin-2.rs:2:1
diff --git a/src/test/ui/malformed/malformed-plugin-3.stderr b/src/test/ui/malformed/malformed-plugin-3.stderr
index 7393072cb1ca3..4af933c15f61e 100644
--- a/src/test/ui/malformed/malformed-plugin-3.stderr
+++ b/src/test/ui/malformed/malformed-plugin-3.stderr
@@ -1,8 +1,8 @@
 error[E0498]: malformed `plugin` attribute
-  --> $DIR/malformed-plugin-3.rs:2:1
+  --> $DIR/malformed-plugin-3.rs:2:11
    |
 LL | #![plugin(foo="bleh")]
-   | ^^^^^^^^^^^^^^^^^^^^^^ malformed attribute
+   |           ^^^^^^^^^^ malformed attribute
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
   --> $DIR/malformed-plugin-3.rs:2:1