summaryrefslogtreecommitdiffstats
path: root/tests/ui-fulldeps
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui-fulldeps')
-rw-r--r--tests/ui-fulldeps/auxiliary/empty-plugin.rs9
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-13560-1.rs3
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-13560-2.rs3
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-13560-3.rs6
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-16822.rs20
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-18502.rs21
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-24106.rs13
-rw-r--r--tests/ui-fulldeps/auxiliary/issue-40001-plugin.rs59
-rw-r--r--tests/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs80
-rw-r--r--tests/ui-fulldeps/auxiliary/lint-for-crate.rs45
-rw-r--r--tests/ui-fulldeps/auxiliary/lint-group-plugin-test.rs44
-rw-r--r--tests/ui-fulldeps/auxiliary/lint-plugin-test.rs33
-rw-r--r--tests/ui-fulldeps/auxiliary/lint-tool-test.rs52
-rw-r--r--tests/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs5
-rw-r--r--tests/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs11
-rw-r--r--tests/ui-fulldeps/auxiliary/multiple-plugins-1.rs10
-rw-r--r--tests/ui-fulldeps/auxiliary/multiple-plugins-2.rs10
-rw-r--r--tests/ui-fulldeps/auxiliary/outlive-expansion-phase.rs24
-rw-r--r--tests/ui-fulldeps/auxiliary/rlib-crate-test.rs12
-rw-r--r--tests/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs7
-rw-r--r--tests/ui-fulldeps/compiler-calls.rs33
-rw-r--r--tests/ui-fulldeps/create-dir-all-bare.rs11
-rw-r--r--tests/ui-fulldeps/deriving-encodable-decodable-box.rs34
-rw-r--r--tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs44
-rw-r--r--tests/ui-fulldeps/deriving-global.rs35
-rw-r--r--tests/ui-fulldeps/deriving-hygiene.rs25
-rw-r--r--tests/ui-fulldeps/dropck-tarena-cycle-checked.rs117
-rw-r--r--tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr14
-rw-r--r--tests/ui-fulldeps/dropck-tarena-unsound-drop.rs42
-rw-r--r--tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr14
-rw-r--r--tests/ui-fulldeps/dropck_tarena_sound_drop.rs48
-rw-r--r--tests/ui-fulldeps/empty-struct-braces-derive.rs61
-rw-r--r--tests/ui-fulldeps/extern-mod-syntax.rs11
-rw-r--r--tests/ui-fulldeps/feature-gate-plugin.rs8
-rw-r--r--tests/ui-fulldeps/feature-gate-plugin.stderr20
-rw-r--r--tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl1
-rw-r--r--tests/ui-fulldeps/fluent-messages/duplicate-a.ftl1
-rw-r--r--tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/missing-message.ftl1
-rw-r--r--tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl1
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.rs98
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.stderr98
-rw-r--r--tests/ui-fulldeps/fluent-messages/valid.ftl1
-rw-r--r--tests/ui-fulldeps/gated-plugin.rs8
-rw-r--r--tests/ui-fulldeps/gated-plugin.stderr20
-rw-r--r--tests/ui-fulldeps/hash-stable-is-unstable.rs17
-rw-r--r--tests/ui-fulldeps/hash-stable-is-unstable.stderr49
-rw-r--r--tests/ui-fulldeps/internal-lints/bad_opt_access.rs22
-rw-r--r--tests/ui-fulldeps/internal-lints/bad_opt_access.stderr20
-rw-r--r--tests/ui-fulldeps/internal-lints/default_hash_types.rs29
-rw-r--r--tests/ui-fulldeps/internal-lints/default_hash_types.stderr39
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.rs89
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.stderr44
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics_incorrect.rs15
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr17
-rw-r--r--tests/ui-fulldeps/internal-lints/existing_doc_keyword.rs11
-rw-r--r--tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr15
-rw-r--r--tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs46
-rw-r--r--tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr27
-rw-r--r--tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs35
-rw-r--r--tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr20
-rw-r--r--tests/ui-fulldeps/internal-lints/query_stability.rs24
-rw-r--r--tests/ui-fulldeps/internal-lints/query_stability.stderr39
-rw-r--r--tests/ui-fulldeps/internal-lints/query_stability_incorrect.rs15
-rw-r--r--tests/ui-fulldeps/internal-lints/query_stability_incorrect.stderr17
-rw-r--r--tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs118
-rw-r--r--tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr128
-rw-r--r--tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs54
-rw-r--r--tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr38
-rw-r--r--tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs55
-rw-r--r--tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr208
-rw-r--r--tests/ui-fulldeps/issue-11881.rs91
-rw-r--r--tests/ui-fulldeps/issue-13560.rs12
-rw-r--r--tests/ui-fulldeps/issue-14021.rs33
-rw-r--r--tests/ui-fulldeps/issue-15149.rs57
-rw-r--r--tests/ui-fulldeps/issue-15778-fail.rs9
-rw-r--r--tests/ui-fulldeps/issue-15778-fail.stderr22
-rw-r--r--tests/ui-fulldeps/issue-15924.rs53
-rw-r--r--tests/ui-fulldeps/issue-16822.rs22
-rw-r--r--tests/ui-fulldeps/issue-18502.rs8
-rw-r--r--tests/ui-fulldeps/issue-24106.rs8
-rw-r--r--tests/ui-fulldeps/issue-2804.rs81
-rw-r--r--tests/ui-fulldeps/issue-40001.rs10
-rw-r--r--tests/ui-fulldeps/issue-40001.stderr10
-rw-r--r--tests/ui-fulldeps/issue-81357-unsound-file-methods.rs81
-rw-r--r--tests/ui-fulldeps/lint-group-denied-lint-allowed.rs7
-rw-r--r--tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs7
-rw-r--r--tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr10
-rw-r--r--tests/ui-fulldeps/lint-group-plugin-deny-cmdline.rs17
-rw-r--r--tests/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr26
-rw-r--r--tests/ui-fulldeps/lint-group-plugin.rs17
-rw-r--r--tests/ui-fulldeps/lint-group-plugin.stderr26
-rw-r--r--tests/ui-fulldeps/lint-pass-macros.rs26
-rw-r--r--tests/ui-fulldeps/lint-plugin-cmdline-allow.rs12
-rw-r--r--tests/ui-fulldeps/lint-plugin-cmdline-allow.stderr10
-rw-r--r--tests/ui-fulldeps/lint-plugin-cmdline-load.rs13
-rw-r--r--tests/ui-fulldeps/lint-plugin-cmdline-load.stderr18
-rw-r--r--tests/ui-fulldeps/lint-plugin-deny-attr.rs13
-rw-r--r--tests/ui-fulldeps/lint-plugin-deny-attr.stderr22
-rw-r--r--tests/ui-fulldeps/lint-plugin-deny-cmdline.rs13
-rw-r--r--tests/ui-fulldeps/lint-plugin-deny-cmdline.stderr18
-rw-r--r--tests/ui-fulldeps/lint-plugin-forbid-attrs.rs16
-rw-r--r--tests/ui-fulldeps/lint-plugin-forbid-attrs.stderr41
-rw-r--r--tests/ui-fulldeps/lint-plugin-forbid-cmdline.rs15
-rw-r--r--tests/ui-fulldeps/lint-plugin-forbid-cmdline.stderr35
-rw-r--r--tests/ui-fulldeps/lint-plugin.rs13
-rw-r--r--tests/ui-fulldeps/lint-plugin.stderr18
-rw-r--r--tests/ui-fulldeps/lint-tool-cmdline-allow.rs12
-rw-r--r--tests/ui-fulldeps/lint-tool-cmdline-allow.stderr30
-rw-r--r--tests/ui-fulldeps/lint-tool-test.rs36
-rw-r--r--tests/ui-fulldeps/lint-tool-test.stderr95
-rw-r--r--tests/ui-fulldeps/lto-syntax-extension.rs15
-rw-r--r--tests/ui-fulldeps/lto-syntax-extension.stderr10
-rw-r--r--tests/ui-fulldeps/macro-crate-rlib.rs8
-rw-r--r--tests/ui-fulldeps/macro-crate-rlib.stderr9
-rw-r--r--tests/ui-fulldeps/missing-rustc-driver-error.rs11
-rw-r--r--tests/ui-fulldeps/missing-rustc-driver-error.stderr24
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs40
-rw-r--r--tests/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir0
-rw-r--r--tests/ui-fulldeps/mod_dir_simple/test.rs3
-rw-r--r--tests/ui-fulldeps/multiple-plugins.rs12
-rw-r--r--tests/ui-fulldeps/multiple-plugins.stderr16
-rw-r--r--tests/ui-fulldeps/myriad-closures.rs39
-rw-r--r--tests/ui-fulldeps/outlive-expansion-phase.rs8
-rw-r--r--tests/ui-fulldeps/outlive-expansion-phase.stderr10
-rw-r--r--tests/ui-fulldeps/pathless-extern-unstable.rs10
-rw-r--r--tests/ui-fulldeps/pathless-extern-unstable.stderr12
-rw-r--r--tests/ui-fulldeps/plugin-args.rs9
-rw-r--r--tests/ui-fulldeps/plugin-args.stderr17
-rw-r--r--tests/ui-fulldeps/plugin-as-extern-crate.rs10
-rw-r--r--tests/ui-fulldeps/pprust-expr-roundtrip.rs253
-rw-r--r--tests/ui-fulldeps/regions-mock-tcx.rs139
-rw-r--r--tests/ui-fulldeps/rename-directory.rs30
-rw-r--r--tests/ui-fulldeps/rustc_encodable_hygiene.rs31
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs801
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr666
-rw-r--r--tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs24
-rw-r--r--tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr11
-rw-r--r--tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs800
-rw-r--r--tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr566
-rw-r--r--tests/ui-fulldeps/stdio-from.rs69
-rw-r--r--tests/ui-fulldeps/switch-stdout.rs51
143 files changed, 7175 insertions, 0 deletions
diff --git a/tests/ui-fulldeps/auxiliary/empty-plugin.rs b/tests/ui-fulldeps/auxiliary/empty-plugin.rs
new file mode 100644
index 000000000..c24cdc97a
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/empty-plugin.rs
@@ -0,0 +1,9 @@
+// force-host
+
+#![feature(rustc_private)]
+
+extern crate rustc_driver;
+use rustc_driver::plugin::Registry;
+
+#[no_mangle]
+fn __rustc_plugin_registrar(_: &mut Registry) {}
diff --git a/tests/ui-fulldeps/auxiliary/issue-13560-1.rs b/tests/ui-fulldeps/auxiliary/issue-13560-1.rs
new file mode 100644
index 000000000..c3a2ae679
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-13560-1.rs
@@ -0,0 +1,3 @@
+// no-prefer-dynamic
+
+#![crate_type = "dylib"]
diff --git a/tests/ui-fulldeps/auxiliary/issue-13560-2.rs b/tests/ui-fulldeps/auxiliary/issue-13560-2.rs
new file mode 100644
index 000000000..39c261e11
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-13560-2.rs
@@ -0,0 +1,3 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
diff --git a/tests/ui-fulldeps/auxiliary/issue-13560-3.rs b/tests/ui-fulldeps/auxiliary/issue-13560-3.rs
new file mode 100644
index 000000000..e991bcc1a
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-13560-3.rs
@@ -0,0 +1,6 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[macro_use] #[no_link] extern crate issue_13560_1 as t1;
+#[macro_use] extern crate issue_13560_2 as t2;
diff --git a/tests/ui-fulldeps/auxiliary/issue-16822.rs b/tests/ui-fulldeps/auxiliary/issue-16822.rs
new file mode 100644
index 000000000..9042dd391
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-16822.rs
@@ -0,0 +1,20 @@
+#![crate_type="lib"]
+
+use std::cell::RefCell;
+
+pub struct Window<Data>{
+ pub data: RefCell<Data>
+}
+
+impl<Data: Update> Window<Data> {
+ pub fn update(&self, e: i32) {
+ match e {
+ 1 => self.data.borrow_mut().update(),
+ _ => {}
+ }
+ }
+}
+
+pub trait Update {
+ fn update(&mut self);
+}
diff --git a/tests/ui-fulldeps/auxiliary/issue-18502.rs b/tests/ui-fulldeps/auxiliary/issue-18502.rs
new file mode 100644
index 000000000..4d4230607
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-18502.rs
@@ -0,0 +1,21 @@
+#![crate_type="lib"]
+
+struct Foo;
+// This is the ICE trigger
+struct Formatter;
+
+trait Show {
+ fn fmt(&self);
+}
+
+impl Show for Foo {
+ fn fmt(&self) {}
+}
+
+fn bar<T>(f: extern "Rust" fn(&T), t: &T) { }
+
+// ICE requirement: this has to be marked as inline
+#[inline]
+pub fn baz() {
+ bar(Show::fmt, &Foo);
+}
diff --git a/tests/ui-fulldeps/auxiliary/issue-24106.rs b/tests/ui-fulldeps/auxiliary/issue-24106.rs
new file mode 100644
index 000000000..2c6a60348
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-24106.rs
@@ -0,0 +1,13 @@
+#![crate_type="lib"]
+
+enum E { E0 = 0, E1 = 1 }
+const E0_U8: u8 = E::E0 as u8;
+const E1_U8: u8 = E::E1 as u8;
+
+pub fn go<T>() {
+ match 0 {
+ E0_U8 => (),
+ E1_U8 => (),
+ _ => (),
+ }
+}
diff --git a/tests/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/tests/ui-fulldeps/auxiliary/issue-40001-plugin.rs
new file mode 100644
index 000000000..c05443488
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/issue-40001-plugin.rs
@@ -0,0 +1,59 @@
+#![feature(plugin, rustc_private)]
+#![crate_type = "dylib"]
+
+extern crate rustc_ast_pretty;
+extern crate rustc_driver;
+extern crate rustc_hir;
+extern crate rustc_lint;
+#[macro_use]
+extern crate rustc_session;
+extern crate rustc_ast;
+extern crate rustc_span;
+
+use rustc_ast_pretty::pprust;
+use rustc_driver::plugin::Registry;
+use rustc_hir as hir;
+use rustc_hir::intravisit;
+use rustc_hir::Node;
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_span::source_map;
+
+#[no_mangle]
+fn __rustc_plugin_registrar(reg: &mut Registry) {
+ reg.lint_store.register_lints(&[&MISSING_ALLOWED_ATTR]);
+ reg.lint_store.register_late_pass(|_| Box::new(MissingAllowedAttrPass));
+}
+
+declare_lint! {
+ MISSING_ALLOWED_ATTR,
+ Deny,
+ "Checks for missing `allowed_attr` attribute"
+}
+
+declare_lint_pass!(MissingAllowedAttrPass => [MISSING_ALLOWED_ATTR]);
+
+impl<'tcx> LateLintPass<'tcx> for MissingAllowedAttrPass {
+ fn check_fn(
+ &mut self,
+ cx: &LateContext<'tcx>,
+ _: intravisit::FnKind<'tcx>,
+ _: &'tcx hir::FnDecl,
+ _: &'tcx hir::Body,
+ span: source_map::Span,
+ id: hir::HirId,
+ ) {
+ let item = match cx.tcx.hir().get(id) {
+ Node::Item(item) => item,
+ _ => cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(id).def_id),
+ };
+
+ let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr");
+ if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) {
+ cx.lint(
+ MISSING_ALLOWED_ATTR,
+ "Missing 'allowed_attr' attribute",
+ |lint| lint.set_span(span)
+ );
+ }
+ }
+}
diff --git a/tests/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/tests/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
new file mode 100644
index 000000000..a3b570ad8
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs
@@ -0,0 +1,80 @@
+// force-host
+
+#![feature(rustc_private)]
+
+extern crate rustc_driver;
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_span;
+#[macro_use]
+extern crate rustc_session;
+extern crate rustc_ast;
+
+use rustc_ast::attr;
+use rustc_driver::plugin::Registry;
+use rustc_lint::{LateContext, LateLintPass, LintContext, LintPass};
+use rustc_span::def_id::CRATE_DEF_ID;
+use rustc_span::symbol::Symbol;
+
+macro_rules! fake_lint_pass {
+ ($struct:ident, $($attr:expr),*) => {
+ struct $struct;
+
+ impl LintPass for $struct {
+ fn name(&self) -> &'static str {
+ stringify!($struct)
+ }
+ }
+
+ impl LateLintPass<'_> for $struct {
+ fn check_crate(&mut self, cx: &LateContext) {
+ let attrs = cx.tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
+ let span = cx.tcx.def_span(CRATE_DEF_ID);
+ $(
+ if !cx.sess().contains_name(attrs, $attr) {
+ cx.lint(CRATE_NOT_OKAY, |lint| {
+ let msg = format!("crate is not marked with #![{}]", $attr);
+ lint.build(&msg).set_span(span).emit();
+ });
+ }
+ )*
+ }
+ }
+
+ }
+}
+
+declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");
+declare_lint!(CRATE_NOT_RED, Warn, "crate not marked with #![crate_red]");
+declare_lint!(CRATE_NOT_BLUE, Warn, "crate not marked with #![crate_blue]");
+declare_lint!(CRATE_NOT_GREY, Warn, "crate not marked with #![crate_grey]");
+declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]");
+
+fake_lint_pass! {
+ PassOkay,
+ Symbol::intern("crate_okay")
+}
+
+fake_lint_pass! {
+ PassRedBlue,
+ Symbol::intern("crate_red"), Symbol::intern("crate_blue")
+}
+
+fake_lint_pass! {
+ PassGreyGreen,
+ Symbol::intern("crate_grey"), Symbol::intern("crate_green")
+}
+
+#[no_mangle]
+fn __rustc_plugin_registrar(reg: &mut Registry) {
+ reg.lint_store.register_lints(&[
+ &CRATE_NOT_OKAY,
+ &CRATE_NOT_RED,
+ &CRATE_NOT_BLUE,
+ &CRATE_NOT_GREY,
+ &CRATE_NOT_GREEN,
+ ]);
+ reg.lint_store.register_late_pass(|_| Box::new(PassOkay));
+ reg.lint_store.register_late_pass(|_| Box::new(PassRedBlue));
+ reg.lint_store.register_late_pass(|_| Box::new(PassGreyGreen));
+}
diff --git a/tests/ui-fulldeps/auxiliary/lint-for-crate.rs b/tests/ui-fulldeps/auxiliary/lint-for-crate.rs
new file mode 100644
index 000000000..073da688c
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lint-for-crate.rs
@@ -0,0 +1,45 @@
+// force-host
+
+#![feature(rustc_private)]
+
+extern crate rustc_driver;
+extern crate rustc_hir;
+#[macro_use]
+extern crate rustc_lint;
+#[macro_use]
+extern crate rustc_session;
+extern crate rustc_ast;
+extern crate rustc_span;
+
+use rustc_driver::plugin::Registry;
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_span::def_id::CRATE_DEF_ID;
+use rustc_span::symbol::Symbol;
+
+declare_lint! {
+ CRATE_NOT_OKAY,
+ Warn,
+ "crate not marked with #![crate_okay]"
+}
+
+declare_lint_pass!(Pass => [CRATE_NOT_OKAY]);
+
+impl<'tcx> LateLintPass<'tcx> for Pass {
+ fn check_crate(&mut self, cx: &LateContext) {
+ let attrs = cx.tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
+ let span = cx.tcx.def_span(CRATE_DEF_ID);
+ if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) {
+ cx.lint(
+ CRATE_NOT_OKAY,
+ "crate is not marked with #![crate_okay]",
+ |lint| lint.set_span(span)
+ );
+ }
+ }
+}
+
+#[no_mangle]
+fn __rustc_plugin_registrar(reg: &mut Registry) {
+ reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]);
+ reg.lint_store.register_late_pass(|_| Box::new(Pass));
+}
diff --git a/tests/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/tests/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
new file mode 100644
index 000000000..4a41e7fbb
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
@@ -0,0 +1,44 @@
+// force-host
+
+#![feature(rustc_private)]
+
+// Load rustc as a plugin to get macros.
+extern crate rustc_driver;
+extern crate rustc_hir;
+#[macro_use]
+extern crate rustc_lint;
+#[macro_use]
+extern crate rustc_session;
+
+use rustc_driver::plugin::Registry;
+use rustc_lint::{LateContext, LateLintPass, LintArray, LintContext, LintId, LintPass};
+
+declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
+
+declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'");
+
+declare_lint_pass!(Pass => [TEST_LINT, PLEASE_LINT]);
+
+impl<'tcx> LateLintPass<'tcx> for Pass {
+ fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) {
+ match it.ident.as_str() {
+ "lintme" => cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)),
+ "pleaselintme" => {
+ cx.lint(PLEASE_LINT, "item is named 'pleaselintme'", |lint| lint.set_span(it.span))
+ }
+ _ => {}
+ }
+ }
+}
+
+#[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::new(Pass));
+ reg.lint_store.register_group(
+ true,
+ "lint_me",
+ None,
+ vec![LintId::of(&TEST_LINT), LintId::of(&PLEASE_LINT)],
+ );
+}
diff --git a/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs b/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs
new file mode 100644
index 000000000..30956deb7
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs
@@ -0,0 +1,33 @@
+// force-host
+
+#![feature(rustc_private)]
+
+extern crate rustc_ast;
+
+// Load rustc as a plugin to get macros
+extern crate rustc_driver;
+#[macro_use]
+extern crate rustc_lint;
+#[macro_use]
+extern crate rustc_session;
+
+use rustc_driver::plugin::Registry;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
+use rustc_ast as ast;
+declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+
+impl EarlyLintPass for Pass {
+ fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
+ if it.ident.name.as_str() == "lintme" {
+ cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span));
+ }
+ }
+}
+
+#[no_mangle]
+fn __rustc_plugin_registrar(reg: &mut Registry) {
+ reg.lint_store.register_lints(&[&TEST_LINT]);
+ reg.lint_store.register_early_pass(|| Box::new(Pass));
+}
diff --git a/tests/ui-fulldeps/auxiliary/lint-tool-test.rs b/tests/ui-fulldeps/auxiliary/lint-tool-test.rs
new file mode 100644
index 000000000..c2c024865
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lint-tool-test.rs
@@ -0,0 +1,52 @@
+#![feature(rustc_private)]
+
+extern crate rustc_ast;
+
+// Load rustc as a plugin to get macros
+extern crate rustc_driver;
+#[macro_use]
+extern crate rustc_lint;
+#[macro_use]
+extern crate rustc_session;
+
+use rustc_driver::plugin::Registry;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintId, LintPass};
+use rustc_ast as ast;
+declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff");
+declare_tool_lint!(
+ /// Some docs
+ pub clippy::TEST_GROUP,
+ Warn, "Warn about other stuff"
+);
+
+declare_tool_lint!(
+ /// Some docs
+ pub rustc::TEST_RUSTC_TOOL_LINT,
+ Deny,
+ "Deny internal stuff"
+);
+
+declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP, TEST_RUSTC_TOOL_LINT]);
+
+impl EarlyLintPass for Pass {
+ fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
+ if it.ident.name.as_str() == "lintme" {
+ cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span));
+ }
+ if it.ident.name.as_str() == "lintmetoo" {
+ cx.lint(TEST_GROUP, "item is named 'lintmetoo'", |lint| lint.set_span(it.span));
+ }
+ }
+}
+
+#[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::new(Pass));
+ reg.lint_store.register_group(
+ true,
+ "clippy::group",
+ Some("clippy_group"),
+ vec![LintId::of(&TEST_LINT), LintId::of(&TEST_GROUP)],
+ );
+}
diff --git a/tests/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs b/tests/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs
new file mode 100644
index 000000000..954a1e554
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs
@@ -0,0 +1,5 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub fn foo() {}
diff --git a/tests/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs b/tests/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
new file mode 100644
index 000000000..9b075c1a5
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
@@ -0,0 +1,11 @@
+// force-host
+
+#![feature(rustc_private)]
+
+extern crate rustc_middle;
+extern crate rustc_driver;
+
+use rustc_driver::plugin::Registry;
+
+#[no_mangle]
+fn __rustc_plugin_registrar(_reg: &mut Registry) {}
diff --git a/tests/ui-fulldeps/auxiliary/multiple-plugins-1.rs b/tests/ui-fulldeps/auxiliary/multiple-plugins-1.rs
new file mode 100644
index 000000000..fd6e9e20f
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/multiple-plugins-1.rs
@@ -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) {}
diff --git a/tests/ui-fulldeps/auxiliary/multiple-plugins-2.rs b/tests/ui-fulldeps/auxiliary/multiple-plugins-2.rs
new file mode 100644
index 000000000..fd6e9e20f
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/multiple-plugins-2.rs
@@ -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) {}
diff --git a/tests/ui-fulldeps/auxiliary/outlive-expansion-phase.rs b/tests/ui-fulldeps/auxiliary/outlive-expansion-phase.rs
new file mode 100644
index 000000000..e83dfe804
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/outlive-expansion-phase.rs
@@ -0,0 +1,24 @@
+// force-host
+
+#![feature(rustc_private)]
+
+extern crate rustc_middle;
+extern crate rustc_driver;
+
+use std::any::Any;
+use std::cell::RefCell;
+use rustc_driver::plugin::Registry;
+
+struct Foo {
+ foo: isize
+}
+
+impl Drop for Foo {
+ fn drop(&mut self) {}
+}
+
+#[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::new(Foo { foo: 10 }) as Box<Any+Send>));
+}
diff --git a/tests/ui-fulldeps/auxiliary/rlib-crate-test.rs b/tests/ui-fulldeps/auxiliary/rlib-crate-test.rs
new file mode 100644
index 000000000..3ba73538e
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/rlib-crate-test.rs
@@ -0,0 +1,12 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+#![feature(rustc_private)]
+
+extern crate rustc_middle;
+extern crate rustc_driver;
+
+use rustc_driver::plugin::Registry;
+
+#[no_mangle]
+fn __rustc_plugin_registrar(_: &mut Registry) {}
diff --git a/tests/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs b/tests/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs
new file mode 100644
index 000000000..8b00fb81c
--- /dev/null
+++ b/tests/ui-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs
@@ -0,0 +1,7 @@
+// force-host
+
+#![crate_type = "dylib"]
+
+pub fn the_answer() -> isize {
+ 2
+}
diff --git a/tests/ui-fulldeps/compiler-calls.rs b/tests/ui-fulldeps/compiler-calls.rs
new file mode 100644
index 000000000..a9520b592
--- /dev/null
+++ b/tests/ui-fulldeps/compiler-calls.rs
@@ -0,0 +1,33 @@
+// run-pass
+// Test that the Callbacks interface to the compiler works.
+
+// ignore-cross-compile
+// ignore-stage1
+// ignore-remote
+
+#![feature(rustc_private)]
+
+extern crate rustc_driver;
+extern crate rustc_interface;
+
+use rustc_interface::interface;
+
+struct TestCalls<'a> {
+ count: &'a mut u32
+}
+
+impl rustc_driver::Callbacks for TestCalls<'_> {
+ fn config(&mut self, _config: &mut interface::Config) {
+ *self.count *= 2;
+ }
+}
+
+fn main() {
+ let mut count = 1;
+ let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
+ rustc_driver::catch_fatal_errors(|| {
+ rustc_driver::RunCompiler::new(&args, &mut TestCalls { count: &mut count }).run().ok();
+ })
+ .ok();
+ assert_eq!(count, 2);
+}
diff --git a/tests/ui-fulldeps/create-dir-all-bare.rs b/tests/ui-fulldeps/create-dir-all-bare.rs
new file mode 100644
index 000000000..4554680ec
--- /dev/null
+++ b/tests/ui-fulldeps/create-dir-all-bare.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+use std::env;
+use std::fs;
+use std::path::PathBuf;
+
+fn main() {
+ let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ env::set_current_dir(&path).unwrap();
+ fs::create_dir_all("create-dir-all-bare").unwrap();
+}
diff --git a/tests/ui-fulldeps/deriving-encodable-decodable-box.rs b/tests/ui-fulldeps/deriving-encodable-decodable-box.rs
new file mode 100644
index 000000000..1c376f59e
--- /dev/null
+++ b/tests/ui-fulldeps/deriving-encodable-decodable-box.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![allow(unused_imports)]
+#![feature(rustc_private)]
+
+extern crate rustc_macros;
+extern crate rustc_serialize;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_macros::{Decodable, Encodable};
+use rustc_serialize::opaque::{MemDecoder, MemEncoder};
+use rustc_serialize::{Decodable, Encodable, Encoder};
+
+#[derive(Encodable, Decodable)]
+struct A {
+ foo: Box<[bool]>,
+}
+
+fn main() {
+ let obj = A { foo: Box::new([true, false]) };
+
+ let mut encoder = MemEncoder::new();
+ obj.encode(&mut encoder);
+ let data = encoder.finish();
+
+ let mut decoder = MemDecoder::new(&data, 0);
+ let obj2 = A::decode(&mut decoder);
+
+ assert_eq!(obj.foo, obj2.foo);
+}
diff --git a/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs b/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
new file mode 100644
index 000000000..844d40f2e
--- /dev/null
+++ b/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
@@ -0,0 +1,44 @@
+// run-pass
+
+#![allow(unused_imports)]
+// This briefly tests the capability of `Cell` and `RefCell` to implement the
+// `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]`
+#![feature(rustc_private)]
+
+extern crate rustc_macros;
+extern crate rustc_serialize;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_macros::{Decodable, Encodable};
+use rustc_serialize::opaque::{MemDecoder, MemEncoder};
+use rustc_serialize::{Decodable, Encodable, Encoder};
+use std::cell::{Cell, RefCell};
+
+#[derive(Encodable, Decodable)]
+struct A {
+ baz: isize,
+}
+
+#[derive(Encodable, Decodable)]
+struct B {
+ foo: Cell<bool>,
+ bar: RefCell<A>,
+}
+
+fn main() {
+ let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
+
+ let mut encoder = MemEncoder::new();
+ obj.encode(&mut encoder);
+ let data = encoder.finish();
+
+ let mut decoder = MemDecoder::new(&data, 0);
+ let obj2 = B::decode(&mut decoder);
+
+ assert_eq!(obj.foo.get(), obj2.foo.get());
+ assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz);
+}
diff --git a/tests/ui-fulldeps/deriving-global.rs b/tests/ui-fulldeps/deriving-global.rs
new file mode 100644
index 000000000..214bb4368
--- /dev/null
+++ b/tests/ui-fulldeps/deriving-global.rs
@@ -0,0 +1,35 @@
+// run-pass
+
+#![feature(rustc_private)]
+
+extern crate rustc_macros;
+extern crate rustc_serialize;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+mod submod {
+ use rustc_macros::{Decodable, Encodable};
+
+ // if any of these are implemented without global calls for any
+ // function calls, then being in a submodule will (correctly)
+ // cause errors about unrecognised module `std` (or `extra`)
+ #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
+ enum A {
+ A1(usize),
+ A2(isize),
+ }
+
+ #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
+ struct B {
+ x: usize,
+ y: isize,
+ }
+
+ #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
+ struct C(usize, isize);
+}
+
+pub fn main() {}
diff --git a/tests/ui-fulldeps/deriving-hygiene.rs b/tests/ui-fulldeps/deriving-hygiene.rs
new file mode 100644
index 000000000..e1084a08f
--- /dev/null
+++ b/tests/ui-fulldeps/deriving-hygiene.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+#![allow(non_upper_case_globals)]
+#![feature(rustc_private)]
+extern crate rustc_macros;
+extern crate rustc_serialize;
+
+use rustc_macros::{Decodable, Encodable};
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+pub const other: u8 = 1;
+pub const f: u8 = 1;
+pub const d: u8 = 1;
+pub const s: u8 = 1;
+pub const state: u8 = 1;
+pub const cmp: u8 = 1;
+
+#[derive(Ord, Eq, PartialOrd, PartialEq, Debug, Decodable, Encodable, Hash)]
+struct Foo {}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/dropck-tarena-cycle-checked.rs b/tests/ui-fulldeps/dropck-tarena-cycle-checked.rs
new file mode 100644
index 000000000..cc97971a0
--- /dev/null
+++ b/tests/ui-fulldeps/dropck-tarena-cycle-checked.rs
@@ -0,0 +1,117 @@
+// Reject mixing cyclic structure and Drop when using TypedArena.
+//
+// (Compare against dropck-vec-cycle-checked.rs)
+//
+// (Also compare against ui-fulldeps/dropck-tarena-unsound-drop.rs,
+// which is a reduction of this code to more directly show the reason
+// for the error message we see here.)
+
+#![feature(rustc_private)]
+
+extern crate rustc_arena;
+
+use rustc_arena::TypedArena;
+use std::cell::Cell;
+use id::Id;
+
+mod s {
+ use std::sync::atomic::{AtomicUsize, Ordering};
+
+ static S_COUNT: AtomicUsize = AtomicUsize::new(0);
+
+ pub fn next_count() -> usize {
+ S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
+ }
+}
+
+mod id {
+ use s;
+ #[derive(Debug)]
+ pub struct Id {
+ orig_count: usize,
+ count: usize,
+ }
+
+ impl Id {
+ pub fn new() -> Id {
+ let c = s::next_count();
+ println!("building Id {}", c);
+ Id { orig_count: c, count: c }
+ }
+ pub fn count(&self) -> usize {
+ println!("Id::count on {} returns {}", self.orig_count, self.count);
+ self.count
+ }
+ }
+
+ impl Drop for Id {
+ fn drop(&mut self) {
+ println!("dropping Id {}", self.count);
+ self.count = 0;
+ }
+ }
+}
+
+trait HasId {
+ fn count(&self) -> usize;
+}
+
+#[derive(Debug)]
+struct CheckId<T:HasId> {
+ v: T
+}
+
+#[allow(non_snake_case)]
+fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
+
+impl<T:HasId> Drop for CheckId<T> {
+ fn drop(&mut self) {
+ assert!(self.v.count() > 0);
+ }
+}
+
+#[derive(Debug)]
+struct C<'a> {
+ id: Id,
+ v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>,
+}
+
+impl<'a> HasId for Cell<Option<&'a C<'a>>> {
+ fn count(&self) -> usize {
+ match self.get() {
+ None => 1,
+ Some(c) => c.id.count(),
+ }
+ }
+}
+
+impl<'a> C<'a> {
+ fn new() -> C<'a> {
+ C { id: Id::new(), v: Vec::new() }
+ }
+}
+
+fn f<'a>(arena: &'a TypedArena<C<'a>>) {
+ let c1 = arena.alloc(C::new());
+ let c2 = arena.alloc(C::new());
+ let c3 = arena.alloc(C::new());
+
+ c1.v.push(CheckId(Cell::new(None)));
+ c1.v.push(CheckId(Cell::new(None)));
+ c2.v.push(CheckId(Cell::new(None)));
+ c2.v.push(CheckId(Cell::new(None)));
+ c3.v.push(CheckId(Cell::new(None)));
+ c3.v.push(CheckId(Cell::new(None)));
+
+ c1.v[0].v.set(Some(c2));
+ c1.v[1].v.set(Some(c3));
+ c2.v[0].v.set(Some(c2));
+ c2.v[1].v.set(Some(c3));
+ c3.v[0].v.set(Some(c1));
+ c3.v[1].v.set(Some(c2));
+}
+
+fn main() {
+ let arena = TypedArena::default();
+ f(&arena);
+} //~^ ERROR `arena` does not live long enough
diff --git a/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr b/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr
new file mode 100644
index 000000000..429968822
--- /dev/null
+++ b/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `arena` does not live long enough
+ --> $DIR/dropck-tarena-cycle-checked.rs:116:7
+ |
+LL | f(&arena);
+ | ^^^^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `arena` dropped here while still borrowed
+ | borrow might be used here, when `arena` is dropped and runs the `Drop` code for type `TypedArena`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui-fulldeps/dropck-tarena-unsound-drop.rs b/tests/ui-fulldeps/dropck-tarena-unsound-drop.rs
new file mode 100644
index 000000000..86485a988
--- /dev/null
+++ b/tests/ui-fulldeps/dropck-tarena-unsound-drop.rs
@@ -0,0 +1,42 @@
+// Check that an arena (TypedArena) cannot carry elements whose drop
+// methods might access borrowed data of lifetime that does not
+// strictly outlive the arena itself.
+//
+// Compare against run-pass/dropck_tarena_sound_drop.rs, which shows a
+// similar setup, but loosens `f` so that the struct `C<'a>` can be
+// fed a lifetime longer than that of the arena.
+//
+// (Also compare against dropck_tarena_cycle_checked.rs, from which
+// this was reduced to better understand its error message.)
+
+#![feature(rustc_private)]
+
+extern crate rustc_arena;
+
+use rustc_arena::TypedArena;
+
+trait HasId { fn count(&self) -> usize; }
+
+struct CheckId<T:HasId> { v: T }
+
+// In the code below, the impl of HasId for `&'a usize` does not
+// actually access the borrowed data, but the point is that the
+// interface to CheckId does not (and cannot) know that, and therefore
+// when encountering a value V of type CheckId<S>, we must
+// conservatively force the type S to strictly outlive V.
+impl<T:HasId> Drop for CheckId<T> {
+ fn drop(&mut self) {
+ assert!(self.v.count() > 0);
+ }
+}
+
+struct C<'a> { v: CheckId<&'a usize>, }
+
+impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } }
+
+fn f<'a>(_arena: &'a TypedArena<C<'a>>) {}
+
+fn main() {
+ let arena: TypedArena<C> = TypedArena::default();
+ f(&arena);
+} //~^ ERROR `arena` does not live long enough
diff --git a/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr b/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr
new file mode 100644
index 000000000..ccffee9cd
--- /dev/null
+++ b/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `arena` does not live long enough
+ --> $DIR/dropck-tarena-unsound-drop.rs:41:7
+ |
+LL | f(&arena);
+ | ^^^^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `arena` dropped here while still borrowed
+ | borrow might be used here, when `arena` is dropped and runs the `Drop` code for type `TypedArena`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui-fulldeps/dropck_tarena_sound_drop.rs b/tests/ui-fulldeps/dropck_tarena_sound_drop.rs
new file mode 100644
index 000000000..ffad80171
--- /dev/null
+++ b/tests/ui-fulldeps/dropck_tarena_sound_drop.rs
@@ -0,0 +1,48 @@
+// run-pass
+
+#![allow(unknown_lints)]
+// Check that an arena (TypedArena) can carry elements whose drop
+// methods might access borrowed data, as long as the borrowed data
+// has lifetime that strictly outlives the arena itself.
+//
+// Compare against ui-fulldeps/dropck-tarena-unsound-drop.rs, which
+// shows a similar setup, but restricts `f` so that the struct `C<'a>`
+// is force-fed a lifetime equal to that of the borrowed arena.
+
+#![allow(unstable)]
+#![feature(rustc_private)]
+
+extern crate rustc_arena;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_arena::TypedArena;
+
+trait HasId { fn count(&self) -> usize; }
+
+struct CheckId<T:HasId> { v: T }
+
+// In the code below, the impl of HasId for `&'a usize` does not
+// actually access the borrowed data, but the point is that the
+// interface to CheckId does not (and cannot) know that, and therefore
+// when encountering a value V of type CheckId<S>, we must
+// conservatively force the type S to strictly outlive V.
+impl<T:HasId> Drop for CheckId<T> {
+ fn drop(&mut self) {
+ assert!(self.v.count() > 0);
+ }
+}
+
+struct C<'a> { _v: CheckId<&'a usize>, }
+
+impl<'a> HasId for &'a usize { fn count(&self) -> usize { 1 } }
+
+fn f<'a, 'b>(_arena: &'a TypedArena<C<'b>>) {}
+
+fn main() {
+ let arena: TypedArena<C> = TypedArena::default();
+ f(&arena);
+}
diff --git a/tests/ui-fulldeps/empty-struct-braces-derive.rs b/tests/ui-fulldeps/empty-struct-braces-derive.rs
new file mode 100644
index 000000000..10e8beaa7
--- /dev/null
+++ b/tests/ui-fulldeps/empty-struct-braces-derive.rs
@@ -0,0 +1,61 @@
+// run-pass
+// `#[derive(Trait)]` works for empty structs/variants with braces or parens.
+
+#![feature(rustc_private)]
+
+extern crate rustc_macros;
+extern crate rustc_serialize;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_macros::{Decodable, Encodable};
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, Encodable, Decodable)]
+struct S {}
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, Encodable, Decodable)]
+struct Z();
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
+enum E {
+ V {},
+ U,
+ W(),
+}
+
+fn main() {
+ let s = S {};
+ let s1 = s;
+ let s2 = s.clone();
+ assert_eq!(s, s1);
+ assert_eq!(s, s2);
+ assert!(!(s < s1));
+ assert_eq!(format!("{:?}", s), "S");
+
+ let z = Z();
+ let z1 = z;
+ let z2 = z.clone();
+ assert_eq!(z, z1);
+ assert_eq!(z, z2);
+ assert!(!(z < z1));
+ assert_eq!(format!("{:?}", z), "Z");
+
+ let e = E::V {};
+ let e1 = e;
+ let e2 = e.clone();
+ assert_eq!(e, e1);
+ assert_eq!(e, e2);
+ assert!(!(e < e1));
+ assert_eq!(format!("{:?}", e), "V");
+
+ let e = E::W();
+ let e1 = e;
+ let e2 = e.clone();
+ assert_eq!(e, e1);
+ assert_eq!(e, e2);
+ assert!(!(e < e1));
+ assert_eq!(format!("{:?}", e), "W");
+}
diff --git a/tests/ui-fulldeps/extern-mod-syntax.rs b/tests/ui-fulldeps/extern-mod-syntax.rs
new file mode 100644
index 000000000..230194c53
--- /dev/null
+++ b/tests/ui-fulldeps/extern-mod-syntax.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+#![allow(unused_imports)]
+#![feature(rustc_private)]
+
+extern crate libc;
+use libc::c_void;
+
+pub fn main() {
+ println!("Hello world!");
+}
diff --git a/tests/ui-fulldeps/feature-gate-plugin.rs b/tests/ui-fulldeps/feature-gate-plugin.rs
new file mode 100644
index 000000000..85eaf5336
--- /dev/null
+++ b/tests/ui-fulldeps/feature-gate-plugin.rs
@@ -0,0 +1,8 @@
+// aux-build:empty-plugin.rs
+// ignore-stage1
+
+#![plugin(empty_plugin)]
+//~^ ERROR compiler plugins are deprecated
+//~| WARN use of deprecated attribute `plugin`: compiler plugins are deprecated
+
+fn main() {}
diff --git a/tests/ui-fulldeps/feature-gate-plugin.stderr b/tests/ui-fulldeps/feature-gate-plugin.stderr
new file mode 100644
index 000000000..5e40561c7
--- /dev/null
+++ b/tests/ui-fulldeps/feature-gate-plugin.stderr
@@ -0,0 +1,20 @@
+error[E0658]: compiler plugins are deprecated
+ --> $DIR/feature-gate-plugin.rs:4:1
+ |
+LL | #![plugin(empty_plugin)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #29597 <https://github.com/rust-lang/rust/issues/29597> for more information
+ = 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:4:1
+ |
+LL | #![plugin(empty_plugin)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl b/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl
new file mode 100644
index 000000000..9407c5170
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl
@@ -0,0 +1 @@
+a_b_key = Value
diff --git a/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl b/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl
new file mode 100644
index 000000000..9407c5170
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl
@@ -0,0 +1 @@
+a_b_key = Value
diff --git a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
new file mode 100644
index 000000000..016cbeef6
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
@@ -0,0 +1,2 @@
+label_with_hyphens_some_slug = hi
+ .label-has-hyphens = test
diff --git a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl
new file mode 100644
index 000000000..9bd035c1b
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl
@@ -0,0 +1,2 @@
+with-hyphens = 1234
+test-crate_foo = abcd
diff --git a/tests/ui-fulldeps/fluent-messages/missing-message.ftl b/tests/ui-fulldeps/fluent-messages/missing-message.ftl
new file mode 100644
index 000000000..74b2aa1d4
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/missing-message.ftl
@@ -0,0 +1 @@
+missing_message =
diff --git a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
new file mode 100644
index 000000000..86ba9a268
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
@@ -0,0 +1 @@
+slug_with_hyphens_this-slug-has-hyphens = hi
diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs
new file mode 100644
index 000000000..4e8147e2b
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/test.rs
@@ -0,0 +1,98 @@
+// normalize-stderr-test "note.*" -> "note: os-specific message"
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_macros;
+use rustc_macros::fluent_messages;
+
+/// Copy of the relevant `DiagnosticMessage` variant constructed by `fluent_messages` as it
+/// expects `crate::DiagnosticMessage` to exist.
+pub enum DiagnosticMessage {
+ FluentIdentifier(std::borrow::Cow<'static, str>, Option<std::borrow::Cow<'static, str>>),
+}
+
+/// Copy of the relevant `SubdiagnosticMessage` variant constructed by `fluent_messages` as it
+/// expects `crate::SubdiagnosticMessage` to exist.
+pub enum SubdiagnosticMessage {
+ FluentAttr(std::borrow::Cow<'static, str>),
+}
+
+mod missing_absolute {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ missing_absolute => "/definitely_does_not_exist.ftl",
+//~^ ERROR could not open Fluent resource
+ }
+}
+
+mod missing_relative {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ missing_relative => "../definitely_does_not_exist.ftl",
+//~^ ERROR could not open Fluent resource
+ }
+}
+
+mod missing_message {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ missing_message => "./missing-message.ftl",
+//~^ ERROR could not parse Fluent resource
+ }
+}
+
+mod duplicate {
+ use super::fluent_messages;
+
+ fluent_messages! {
+//~^ ERROR the name `a_b_key` is defined multiple times
+ a => "./duplicate-a.ftl",
+ a_b => "./duplicate-a-b.ftl",
+//~^ ERROR overrides existing message: `a_b_key`
+ }
+}
+
+mod slug_with_hyphens {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ slug_with_hyphens => "./slug-with-hyphens.ftl",
+//~^ ERROR name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character
+ }
+}
+
+mod label_with_hyphens {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ label_with_hyphens => "./label-with-hyphens.ftl",
+//~^ ERROR attribute `label-has-hyphens` contains a '-' character
+ }
+}
+
+mod valid {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ valid => "./valid.ftl",
+ }
+
+ use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, valid_key};
+}
+
+mod missing_crate_name {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ test_crate => "./missing-crate-name.ftl",
+//~^ ERROR name `test-crate_foo` contains a '-' character
+//~| ERROR name `with-hyphens` contains a '-' character
+//~| ERROR name `with-hyphens` does not start with the crate name
+ }
+
+ use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens};
+}
diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr
new file mode 100644
index 000000000..d1cd4fe26
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/test.stderr
@@ -0,0 +1,98 @@
+error: could not open Fluent resource
+ --> $DIR/test.rs:25:29
+ |
+LL | missing_absolute => "/definitely_does_not_exist.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: os-specific message
+
+error: could not open Fluent resource
+ --> $DIR/test.rs:34:29
+ |
+LL | missing_relative => "../definitely_does_not_exist.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: os-specific message
+
+error: could not parse Fluent resource
+ --> $DIR/test.rs:43:28
+ |
+LL | missing_message => "./missing-message.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: see additional errors emitted
+
+error: expected a message field for "missing_message"
+ --> ./missing-message.ftl:1:1
+ |
+1 | missing_message =
+ | ^^^^^^^^^^^^^^^^^
+ |
+
+error: overrides existing message: `a_b_key`
+ --> $DIR/test.rs:54:16
+ |
+LL | a_b => "./duplicate-a-b.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: previously defined in this resource
+ --> $DIR/test.rs:53:14
+ |
+LL | a => "./duplicate-a.ftl",
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0428]: the name `a_b_key` is defined multiple times
+ --> $DIR/test.rs:51:5
+ |
+LL | fluent_messages! {
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | `a_b_key` redefined here
+ | previous definition of the value `a_b_key` here
+ |
+ = note: os-specific message
+ = note: os-specific message
+
+error: name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character
+ --> $DIR/test.rs:63:30
+ |
+LL | slug_with_hyphens => "./slug-with-hyphens.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: attribute `label-has-hyphens` contains a '-' character
+ --> $DIR/test.rs:72:31
+ |
+LL | label_with_hyphens => "./label-with-hyphens.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: name `with-hyphens` contains a '-' character
+ --> $DIR/test.rs:91:23
+ |
+LL | test_crate => "./missing-crate-name.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: name `with-hyphens` does not start with the crate name
+ --> $DIR/test.rs:91:23
+ |
+LL | test_crate => "./missing-crate-name.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: prepend `test_crate_` to the slug name: `test_crate_with_hyphens`
+
+error: name `test-crate_foo` contains a '-' character
+ --> $DIR/test.rs:91:23
+ |
+LL | test_crate => "./missing-crate-name.ftl",
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/tests/ui-fulldeps/fluent-messages/valid.ftl b/tests/ui-fulldeps/fluent-messages/valid.ftl
new file mode 100644
index 000000000..549274306
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/valid.ftl
@@ -0,0 +1 @@
+valid_key = Valid!
diff --git a/tests/ui-fulldeps/gated-plugin.rs b/tests/ui-fulldeps/gated-plugin.rs
new file mode 100644
index 000000000..85eaf5336
--- /dev/null
+++ b/tests/ui-fulldeps/gated-plugin.rs
@@ -0,0 +1,8 @@
+// aux-build:empty-plugin.rs
+// ignore-stage1
+
+#![plugin(empty_plugin)]
+//~^ ERROR compiler plugins are deprecated
+//~| WARN use of deprecated attribute `plugin`: compiler plugins are deprecated
+
+fn main() {}
diff --git a/tests/ui-fulldeps/gated-plugin.stderr b/tests/ui-fulldeps/gated-plugin.stderr
new file mode 100644
index 000000000..f48f1eab6
--- /dev/null
+++ b/tests/ui-fulldeps/gated-plugin.stderr
@@ -0,0 +1,20 @@
+error[E0658]: compiler plugins are deprecated
+ --> $DIR/gated-plugin.rs:4:1
+ |
+LL | #![plugin(empty_plugin)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #29597 <https://github.com/rust-lang/rust/issues/29597> for more information
+ = 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/gated-plugin.rs:4:1
+ |
+LL | #![plugin(empty_plugin)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.rs b/tests/ui-fulldeps/hash-stable-is-unstable.rs
new file mode 100644
index 000000000..11fe688f3
--- /dev/null
+++ b/tests/ui-fulldeps/hash-stable-is-unstable.rs
@@ -0,0 +1,17 @@
+// ignore-stage1
+// compile-flags: -Zdeduplicate-diagnostics=yes
+extern crate rustc_data_structures;
+//~^ use of unstable library feature 'rustc_private'
+extern crate rustc_macros;
+//~^ use of unstable library feature 'rustc_private'
+extern crate rustc_query_system;
+//~^ use of unstable library feature 'rustc_private'
+
+use rustc_macros::HashStable;
+//~^ use of unstable library feature 'rustc_private'
+
+#[derive(HashStable)]
+//~^ use of unstable library feature 'rustc_private'
+struct Test;
+
+fn main() {}
diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.stderr b/tests/ui-fulldeps/hash-stable-is-unstable.stderr
new file mode 100644
index 000000000..d25657691
--- /dev/null
+++ b/tests/ui-fulldeps/hash-stable-is-unstable.stderr
@@ -0,0 +1,49 @@
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+ --> $DIR/hash-stable-is-unstable.rs:3:1
+ |
+LL | extern crate rustc_data_structures;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
+ = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+ --> $DIR/hash-stable-is-unstable.rs:5:1
+ |
+LL | extern crate rustc_macros;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
+ = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+ --> $DIR/hash-stable-is-unstable.rs:7:1
+ |
+LL | extern crate rustc_query_system;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
+ = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+ --> $DIR/hash-stable-is-unstable.rs:10:5
+ |
+LL | use rustc_macros::HashStable;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
+ = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+ --> $DIR/hash-stable-is-unstable.rs:13:10
+ |
+LL | #[derive(HashStable)]
+ | ^^^^^^^^^^
+ |
+ = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
+ = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+ = note: this error originates in the derive macro `HashStable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui-fulldeps/internal-lints/bad_opt_access.rs b/tests/ui-fulldeps/internal-lints/bad_opt_access.rs
new file mode 100644
index 000000000..d6bd6945e
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/bad_opt_access.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Z unstable-options
+
+// Test that accessing command line options by field access triggers a lint for those fields
+// that have wrapper functions which should be used.
+
+#![crate_type = "lib"]
+#![feature(rustc_private)]
+#![deny(rustc::bad_opt_access)]
+
+extern crate rustc_session;
+use rustc_session::Session;
+
+pub fn access_bad_option(sess: Session) {
+ let _ = sess.opts.cg.split_debuginfo;
+ //~^ ERROR use `Session::split_debuginfo` instead of this field
+
+ let _ = sess.opts.crate_types;
+ //~^ ERROR use `Session::crate_types` instead of this field
+
+ let _ = sess.opts.crate_name;
+ // okay!
+}
diff --git a/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr b/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr
new file mode 100644
index 000000000..e4145bff8
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr
@@ -0,0 +1,20 @@
+error: use `Session::split_debuginfo` instead of this field
+ --> $DIR/bad_opt_access.rs:14:13
+ |
+LL | let _ = sess.opts.cg.split_debuginfo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/bad_opt_access.rs:8:9
+ |
+LL | #![deny(rustc::bad_opt_access)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: use `Session::crate_types` instead of this field
+ --> $DIR/bad_opt_access.rs:17:13
+ |
+LL | let _ = sess.opts.crate_types;
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/default_hash_types.rs b/tests/ui-fulldeps/internal-lints/default_hash_types.rs
new file mode 100644
index 000000000..795c7d2dc
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/default_hash_types.rs
@@ -0,0 +1,29 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![deny(rustc::default_hash_types)]
+
+extern crate rustc_data_structures;
+
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use std::collections::{HashMap, HashSet};
+
+mod foo {
+ pub struct HashMap;
+}
+
+fn main() {
+ let _map: HashMap<String, String> = HashMap::default();
+ //~^ ERROR prefer `FxHashMap` over `HashMap`, it has better performance
+ //~^^ ERROR prefer `FxHashMap` over `HashMap`, it has better performance
+ let _set: HashSet<String> = HashSet::default();
+ //~^ ERROR prefer `FxHashSet` over `HashSet`, it has better performance
+ //~^^ ERROR prefer `FxHashSet` over `HashSet`, it has better performance
+
+ // test that the lint doesn't also match the Fx variants themselves
+ let _fx_map: FxHashMap<String, String> = FxHashMap::default();
+ let _fx_set: FxHashSet<String> = FxHashSet::default();
+
+ // test another struct of the same name
+ let _ = foo::HashMap;
+}
diff --git a/tests/ui-fulldeps/internal-lints/default_hash_types.stderr b/tests/ui-fulldeps/internal-lints/default_hash_types.stderr
new file mode 100644
index 000000000..3cb13082f
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/default_hash_types.stderr
@@ -0,0 +1,39 @@
+error: prefer `FxHashMap` over `HashMap`, it has better performance
+ --> $DIR/default_hash_types.rs:16:41
+ |
+LL | let _map: HashMap<String, String> = HashMap::default();
+ | ^^^^^^^
+ |
+ = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
+note: the lint level is defined here
+ --> $DIR/default_hash_types.rs:4:9
+ |
+LL | #![deny(rustc::default_hash_types)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: prefer `FxHashMap` over `HashMap`, it has better performance
+ --> $DIR/default_hash_types.rs:16:15
+ |
+LL | let _map: HashMap<String, String> = HashMap::default();
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
+
+error: prefer `FxHashSet` over `HashSet`, it has better performance
+ --> $DIR/default_hash_types.rs:19:33
+ |
+LL | let _set: HashSet<String> = HashSet::default();
+ | ^^^^^^^
+ |
+ = note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
+
+error: prefer `FxHashSet` over `HashSet`, it has better performance
+ --> $DIR/default_hash_types.rs:19:15
+ |
+LL | let _set: HashSet<String> = HashSet::default();
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs
new file mode 100644
index 000000000..643e81d99
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs
@@ -0,0 +1,89 @@
+// compile-flags: -Z unstable-options
+
+#![crate_type = "lib"]
+#![feature(rustc_attrs)]
+#![feature(rustc_private)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
+extern crate rustc_errors;
+extern crate rustc_macros;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use rustc_errors::{
+ AddToDiagnostic, IntoDiagnostic, Diagnostic, DiagnosticBuilder,
+ ErrorGuaranteed, Handler, fluent, SubdiagnosticMessage,
+};
+use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_span::Span;
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct DeriveDiagnostic {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[note(compiletest_example)]
+struct Note {
+ #[primary_span]
+ span: Span,
+}
+
+pub struct UntranslatableInIntoDiagnostic;
+
+impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for UntranslatableInIntoDiagnostic {
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ handler.struct_err("untranslatable diagnostic")
+ //~^ ERROR diagnostics should be created using translatable messages
+ }
+}
+
+pub struct TranslatableInIntoDiagnostic;
+
+impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic {
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ handler.struct_err(fluent::compiletest_example)
+ }
+}
+
+pub struct UntranslatableInAddToDiagnostic;
+
+impl AddToDiagnostic for UntranslatableInAddToDiagnostic {
+ fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
+ where
+ F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+ {
+ diag.note("untranslatable diagnostic");
+ //~^ ERROR diagnostics should be created using translatable messages
+ }
+}
+
+pub struct TranslatableInAddToDiagnostic;
+
+impl AddToDiagnostic for TranslatableInAddToDiagnostic {
+ fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
+ where
+ F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+ {
+ diag.note(fluent::note);
+ }
+}
+
+pub fn make_diagnostics<'a>(handler: &'a Handler) {
+ let _diag = handler.struct_err(fluent::compiletest_example);
+ //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
+
+ let _diag = handler.struct_err("untranslatable diagnostic");
+ //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
+ //~^^ ERROR diagnostics should be created using translatable messages
+}
+
+// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted.
+
+#[rustc_lint_diagnostics]
+pub fn skipped_because_of_annotation<'a>(handler: &'a Handler) {
+ let _diag = handler.struct_err("untranslatable diagnostic"); // okay!
+}
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
new file mode 100644
index 000000000..510d6a171
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
@@ -0,0 +1,44 @@
+error: diagnostics should be created using translatable messages
+ --> $DIR/diagnostics.rs:39:17
+ |
+LL | handler.struct_err("untranslatable diagnostic")
+ | ^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/diagnostics.rs:6:9
+ |
+LL | #![deny(rustc::untranslatable_diagnostic)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostics should be created using translatable messages
+ --> $DIR/diagnostics.rs:59:14
+ |
+LL | diag.note("untranslatable diagnostic");
+ | ^^^^
+
+error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
+ --> $DIR/diagnostics.rs:76:25
+ |
+LL | let _diag = handler.struct_err(fluent::compiletest_example);
+ | ^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/diagnostics.rs:7:9
+ |
+LL | #![deny(rustc::diagnostic_outside_of_impl)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
+ --> $DIR/diagnostics.rs:79:25
+ |
+LL | let _diag = handler.struct_err("untranslatable diagnostic");
+ | ^^^^^^^^^^
+
+error: diagnostics should be created using translatable messages
+ --> $DIR/diagnostics.rs:79:25
+ |
+LL | let _diag = handler.struct_err("untranslatable diagnostic");
+ | ^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics_incorrect.rs b/tests/ui-fulldeps/internal-lints/diagnostics_incorrect.rs
new file mode 100644
index 000000000..99f99ffcd
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/diagnostics_incorrect.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_attrs)]
+
+#[rustc_lint_diagnostics]
+//~^ ERROR attribute should be applied to a function
+struct Foo;
+
+impl Foo {
+ #[rustc_lint_diagnostics(a)]
+ //~^ ERROR malformed `rustc_lint_diagnostics`
+ fn bar() {}
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr b/tests/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr
new file mode 100644
index 000000000..e849ca282
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr
@@ -0,0 +1,17 @@
+error: malformed `rustc_lint_diagnostics` attribute input
+ --> $DIR/diagnostics_incorrect.rs:10:5
+ |
+LL | #[rustc_lint_diagnostics(a)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_diagnostics]`
+
+error: attribute should be applied to a function definition
+ --> $DIR/diagnostics_incorrect.rs:5:1
+ |
+LL | #[rustc_lint_diagnostics]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct Foo;
+ | ----------- not a function definition
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.rs b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.rs
new file mode 100644
index 000000000..7783dc40f
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![feature(rustdoc_internals)]
+
+#![crate_type = "lib"]
+
+#![deny(rustc::existing_doc_keyword)]
+
+#[doc(keyword = "tadam")] //~ ERROR
+mod tadam {}
diff --git a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
new file mode 100644
index 000000000..4e296fff6
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
@@ -0,0 +1,15 @@
+error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]`
+ --> $DIR/existing_doc_keyword.rs:10:1
+ |
+LL | #[doc(keyword = "tadam")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: only existing keywords are allowed in core/std
+note: the lint level is defined here
+ --> $DIR/existing_doc_keyword.rs:8:9
+ |
+LL | #![deny(rustc::existing_doc_keyword)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
new file mode 100644
index 000000000..f6f0c0385
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
@@ -0,0 +1,46 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![deny(rustc::lint_pass_impl_without_macro)]
+
+extern crate rustc_middle;
+extern crate rustc_session;
+
+use rustc_session::lint::{LintArray, LintPass};
+use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
+
+declare_lint! {
+ pub TEST_LINT,
+ Allow,
+ "test"
+}
+
+struct Foo;
+
+impl LintPass for Foo { //~ERROR implementing `LintPass` by hand
+ fn name(&self) -> &'static str {
+ "Foo"
+ }
+}
+
+macro_rules! custom_lint_pass_macro {
+ () => {
+ struct Custom;
+
+ impl LintPass for Custom { //~ERROR implementing `LintPass` by hand
+ fn name(&self) -> &'static str {
+ "Custom"
+ }
+ }
+ };
+}
+
+custom_lint_pass_macro!();
+
+struct Bar;
+
+impl_lint_pass!(Bar => [TEST_LINT]);
+
+declare_lint_pass!(Baz => [TEST_LINT]);
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
new file mode 100644
index 000000000..ad6e93334
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
@@ -0,0 +1,27 @@
+error: implementing `LintPass` by hand
+ --> $DIR/lint_pass_impl_without_macro.rs:20:6
+ |
+LL | impl LintPass for Foo {
+ | ^^^^^^^^
+ |
+ = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
+note: the lint level is defined here
+ --> $DIR/lint_pass_impl_without_macro.rs:4:9
+ |
+LL | #![deny(rustc::lint_pass_impl_without_macro)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementing `LintPass` by hand
+ --> $DIR/lint_pass_impl_without_macro.rs:30:14
+ |
+LL | impl LintPass for Custom {
+ | ^^^^^^^^
+...
+LL | custom_lint_pass_macro!();
+ | ------------------------- in this macro invocation
+ |
+ = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
+ = note: this error originates in the macro `custom_lint_pass_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs b/tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs
new file mode 100644
index 000000000..32b987338
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs
@@ -0,0 +1,35 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![deny(rustc::usage_of_qualified_ty)]
+#![allow(unused)]
+
+extern crate rustc_middle;
+
+use rustc_middle::ty::{self, Ty, TyCtxt};
+
+macro_rules! qualified_macro {
+ ($a:ident) => {
+ fn ty_in_macro(
+ ty_q: ty::Ty<'_>,
+ ty: Ty<'_>,
+ ty_ctxt_q: ty::TyCtxt<'_>,
+ ty_ctxt: TyCtxt<'_>,
+ ) {
+ println!("{}", stringify!($a));
+ }
+ };
+}
+
+fn ty_qualified(
+ ty_q: ty::Ty<'_>, //~ ERROR usage of qualified `ty::Ty<'_>`
+ ty: Ty<'_>,
+ ty_ctxt_q: ty::TyCtxt<'_>, //~ ERROR usage of qualified `ty::TyCtxt<'_>`
+ ty_ctxt: TyCtxt<'_>,
+) {
+}
+
+
+fn main() {
+ qualified_macro!(a);
+}
diff --git a/tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr b/tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr
new file mode 100644
index 000000000..a1056cf85
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr
@@ -0,0 +1,20 @@
+error: usage of qualified `ty::Ty<'_>`
+ --> $DIR/qualified_ty_ty_ctxt.rs:25:11
+ |
+LL | ty_q: ty::Ty<'_>,
+ | ^^^^^^^^^^ help: try importing it and using it unqualified: `Ty<'_>`
+ |
+note: the lint level is defined here
+ --> $DIR/qualified_ty_ty_ctxt.rs:4:9
+ |
+LL | #![deny(rustc::usage_of_qualified_ty)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: usage of qualified `ty::TyCtxt<'_>`
+ --> $DIR/qualified_ty_ty_ctxt.rs:27:16
+ |
+LL | ty_ctxt_q: ty::TyCtxt<'_>,
+ | ^^^^^^^^^^^^^^ help: try importing it and using it unqualified: `TyCtxt<'_>`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/query_stability.rs b/tests/ui-fulldeps/internal-lints/query_stability.rs
new file mode 100644
index 000000000..560675b44
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/query_stability.rs
@@ -0,0 +1,24 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![deny(rustc::potential_query_instability)]
+
+extern crate rustc_data_structures;
+
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+
+fn main() {
+ let mut x = FxHashMap::<u32, i32>::default();
+
+ for _ in x.drain() {}
+ //~^ ERROR using `drain` can result in unstable
+
+ for _ in x.iter() {}
+ //~^ ERROR using `iter`
+
+ for _ in Some(&mut x).unwrap().iter_mut() {}
+ //~^ ERROR using `iter_mut`
+
+ for _ in x {}
+ //~^ ERROR using `into_iter`
+}
diff --git a/tests/ui-fulldeps/internal-lints/query_stability.stderr b/tests/ui-fulldeps/internal-lints/query_stability.stderr
new file mode 100644
index 000000000..ee4ef9982
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/query_stability.stderr
@@ -0,0 +1,39 @@
+error: using `drain` can result in unstable query results
+ --> $DIR/query_stability.rs:13:16
+ |
+LL | for _ in x.drain() {}
+ | ^^^^^
+ |
+ = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+note: the lint level is defined here
+ --> $DIR/query_stability.rs:4:9
+ |
+LL | #![deny(rustc::potential_query_instability)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: using `iter` can result in unstable query results
+ --> $DIR/query_stability.rs:16:16
+ |
+LL | for _ in x.iter() {}
+ | ^^^^
+ |
+ = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: using `iter_mut` can result in unstable query results
+ --> $DIR/query_stability.rs:19:36
+ |
+LL | for _ in Some(&mut x).unwrap().iter_mut() {}
+ | ^^^^^^^^
+ |
+ = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: using `into_iter` can result in unstable query results
+ --> $DIR/query_stability.rs:22:14
+ |
+LL | for _ in x {}
+ | ^
+ |
+ = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/query_stability_incorrect.rs b/tests/ui-fulldeps/internal-lints/query_stability_incorrect.rs
new file mode 100644
index 000000000..f478b7332
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/query_stability_incorrect.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_attrs)]
+
+#[rustc_lint_query_instability]
+//~^ ERROR attribute should be applied to a function
+struct Foo;
+
+impl Foo {
+ #[rustc_lint_query_instability(a)]
+ //~^ ERROR malformed `rustc_lint_query_instability`
+ fn bar() {}
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/query_stability_incorrect.stderr b/tests/ui-fulldeps/internal-lints/query_stability_incorrect.stderr
new file mode 100644
index 000000000..3f78b39ed
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/query_stability_incorrect.stderr
@@ -0,0 +1,17 @@
+error: malformed `rustc_lint_query_instability` attribute input
+ --> $DIR/query_stability_incorrect.rs:10:5
+ |
+LL | #[rustc_lint_query_instability(a)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_query_instability]`
+
+error: attribute should be applied to a function definition
+ --> $DIR/query_stability_incorrect.rs:5:1
+ |
+LL | #[rustc_lint_query_instability]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct Foo;
+ | ----------- not a function definition
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs
new file mode 100644
index 000000000..10bab2d88
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs
@@ -0,0 +1,118 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_attrs)]
+#![feature(rustc_private)]
+#![deny(rustc::pass_by_value)]
+#![allow(unused)]
+
+extern crate rustc_middle;
+
+use rustc_middle::ty::{Ty, TyCtxt};
+
+fn ty_by_ref(
+ ty_val: Ty<'_>,
+ ty_ref: &Ty<'_>, //~ ERROR passing `Ty<'_>` by reference
+ ty_ctxt_val: TyCtxt<'_>,
+ ty_ctxt_ref: &TyCtxt<'_>, //~ ERROR passing `TyCtxt<'_>` by reference
+) {
+}
+
+fn ty_multi_ref(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+//~^ ERROR passing `Ty<'_>` by reference
+//~^^ ERROR passing `TyCtxt<'_>` by reference
+
+trait T {
+ fn ty_by_ref_in_trait(
+ ty_val: Ty<'_>,
+ ty_ref: &Ty<'_>, //~ ERROR passing `Ty<'_>` by reference
+ ty_ctxt_val: TyCtxt<'_>,
+ ty_ctxt_ref: &TyCtxt<'_>, //~ ERROR passing `TyCtxt<'_>` by reference
+ );
+
+ fn ty_multi_ref_in_trait(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>);
+ //~^ ERROR passing `Ty<'_>` by reference
+ //~^^ ERROR passing `TyCtxt<'_>` by reference
+}
+
+struct Foo;
+
+impl T for Foo {
+ fn ty_by_ref_in_trait(
+ ty_val: Ty<'_>,
+ ty_ref: &Ty<'_>,
+ ty_ctxt_val: TyCtxt<'_>,
+ ty_ctxt_ref: &TyCtxt<'_>,
+ ) {
+ }
+
+ fn ty_multi_ref_in_trait(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+}
+
+impl Foo {
+ fn ty_by_ref_assoc(
+ ty_val: Ty<'_>,
+ ty_ref: &Ty<'_>, //~ ERROR passing `Ty<'_>` by reference
+ ty_ctxt_val: TyCtxt<'_>,
+ ty_ctxt_ref: &TyCtxt<'_>, //~ ERROR passing `TyCtxt<'_>` by reference
+ ) {
+ }
+
+ fn ty_multi_ref_assoc(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+ //~^ ERROR passing `Ty<'_>` by reference
+ //~^^ ERROR passing `TyCtxt<'_>` by reference
+}
+
+#[rustc_pass_by_value]
+enum CustomEnum {
+ A,
+ B,
+}
+
+impl CustomEnum {
+ fn test(
+ value: CustomEnum,
+ reference: &CustomEnum, //~ ERROR passing `CustomEnum` by reference
+ ) {
+ }
+}
+
+#[rustc_pass_by_value]
+struct CustomStruct {
+ s: u8,
+}
+
+#[rustc_pass_by_value]
+type CustomAlias<'a> = &'a CustomStruct; //~ ERROR passing `CustomStruct` by reference
+
+impl CustomStruct {
+ fn test(
+ value: CustomStruct,
+ reference: &CustomStruct, //~ ERROR passing `CustomStruct` by reference
+ ) {
+ }
+
+ fn test_alias(
+ value: CustomAlias,
+ reference: &CustomAlias, //~ ERROR passing `CustomAlias<'_>` by reference
+ ) {
+ }
+}
+
+#[rustc_pass_by_value]
+struct WithParameters<T, const N: usize, M = u32> {
+ slice: [T; N],
+ m: M,
+}
+
+impl<T> WithParameters<T, 1> {
+ fn test<'a>(
+ value: WithParameters<T, 1>,
+ reference: &'a WithParameters<T, 1>, //~ ERROR passing `WithParameters<T, 1>` by reference
+ reference_with_m: &WithParameters<T, 1, u32>, //~ ERROR passing `WithParameters<T, 1, u32>` by reference
+ ) -> &'a WithParameters<T, 1> {
+ //~^ ERROR passing `WithParameters<T, 1>` by reference
+ reference as &WithParameters<_, 1> //~ ERROR passing `WithParameters<_, 1>` by reference
+ }
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr
new file mode 100644
index 000000000..69cf20656
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr
@@ -0,0 +1,128 @@
+error: passing `Ty<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:14:13
+ |
+LL | ty_ref: &Ty<'_>,
+ | ^^^^^^^ help: try passing by value: `Ty<'_>`
+ |
+note: the lint level is defined here
+ --> $DIR/rustc_pass_by_value.rs:5:9
+ |
+LL | #![deny(rustc::pass_by_value)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: passing `TyCtxt<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:16:18
+ |
+LL | ty_ctxt_ref: &TyCtxt<'_>,
+ | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>`
+
+error: passing `Ty<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:20:28
+ |
+LL | fn ty_multi_ref(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+ | ^^^^^^^ help: try passing by value: `Ty<'_>`
+
+error: passing `TyCtxt<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:20:55
+ |
+LL | fn ty_multi_ref(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+ | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>`
+
+error: passing `Ty<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:27:17
+ |
+LL | ty_ref: &Ty<'_>,
+ | ^^^^^^^ help: try passing by value: `Ty<'_>`
+
+error: passing `TyCtxt<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:29:22
+ |
+LL | ty_ctxt_ref: &TyCtxt<'_>,
+ | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>`
+
+error: passing `Ty<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:32:41
+ |
+LL | fn ty_multi_ref_in_trait(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>);
+ | ^^^^^^^ help: try passing by value: `Ty<'_>`
+
+error: passing `TyCtxt<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:32:68
+ |
+LL | fn ty_multi_ref_in_trait(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>);
+ | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>`
+
+error: passing `Ty<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:54:17
+ |
+LL | ty_ref: &Ty<'_>,
+ | ^^^^^^^ help: try passing by value: `Ty<'_>`
+
+error: passing `TyCtxt<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:56:22
+ |
+LL | ty_ctxt_ref: &TyCtxt<'_>,
+ | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>`
+
+error: passing `Ty<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:60:38
+ |
+LL | fn ty_multi_ref_assoc(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+ | ^^^^^^^ help: try passing by value: `Ty<'_>`
+
+error: passing `TyCtxt<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:60:65
+ |
+LL | fn ty_multi_ref_assoc(ty_multi: &&Ty<'_>, ty_ctxt_multi: &&&&TyCtxt<'_>) {}
+ | ^^^^^^^^^^^ help: try passing by value: `TyCtxt<'_>`
+
+error: passing `CustomEnum` by reference
+ --> $DIR/rustc_pass_by_value.rs:74:20
+ |
+LL | reference: &CustomEnum,
+ | ^^^^^^^^^^^ help: try passing by value: `CustomEnum`
+
+error: passing `CustomStruct` by reference
+ --> $DIR/rustc_pass_by_value.rs:85:24
+ |
+LL | type CustomAlias<'a> = &'a CustomStruct;
+ | ^^^^^^^^^^^^^^^^ help: try passing by value: `CustomStruct`
+
+error: passing `CustomStruct` by reference
+ --> $DIR/rustc_pass_by_value.rs:90:20
+ |
+LL | reference: &CustomStruct,
+ | ^^^^^^^^^^^^^ help: try passing by value: `CustomStruct`
+
+error: passing `CustomAlias<'_>` by reference
+ --> $DIR/rustc_pass_by_value.rs:96:20
+ |
+LL | reference: &CustomAlias,
+ | ^^^^^^^^^^^^ help: try passing by value: `CustomAlias<'_>`
+
+error: passing `WithParameters<T, 1>` by reference
+ --> $DIR/rustc_pass_by_value.rs:110:20
+ |
+LL | reference: &'a WithParameters<T, 1>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters<T, 1>`
+
+error: passing `WithParameters<T, 1, u32>` by reference
+ --> $DIR/rustc_pass_by_value.rs:111:27
+ |
+LL | reference_with_m: &WithParameters<T, 1, u32>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters<T, 1, u32>`
+
+error: passing `WithParameters<T, 1>` by reference
+ --> $DIR/rustc_pass_by_value.rs:112:10
+ |
+LL | ) -> &'a WithParameters<T, 1> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters<T, 1>`
+
+error: passing `WithParameters<_, 1>` by reference
+ --> $DIR/rustc_pass_by_value.rs:114:22
+ |
+LL | reference as &WithParameters<_, 1>
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try passing by value: `WithParameters<_, 1>`
+
+error: aborting due to 20 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs
new file mode 100644
index 000000000..6ce67dcaf
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs
@@ -0,0 +1,54 @@
+// compile-flags: -Z unstable-options
+// NOTE: This test doesn't actually require `fulldeps`
+// so we could instead use it as a `ui` test.
+//
+// Considering that all other `internal-lints` are tested here
+// this seems like the cleaner solution though.
+#![feature(rustc_attrs)]
+#![deny(rustc::pass_by_value)]
+#![allow(unused)]
+
+#[rustc_pass_by_value]
+struct TyCtxt<'tcx> {
+ inner: &'tcx (),
+}
+
+impl<'tcx> TyCtxt<'tcx> {
+ fn by_value(self) {} // OK
+ fn by_ref(&self) {} //~ ERROR passing `TyCtxt<'tcx>` by reference
+}
+
+struct TyS<'tcx> {
+ inner: &'tcx (),
+}
+
+#[rustc_pass_by_value]
+type Ty<'tcx> = &'tcx TyS<'tcx>;
+
+impl<'tcx> TyS<'tcx> {
+ fn by_value(self: Ty<'tcx>) {}
+ fn by_ref(self: &Ty<'tcx>) {} //~ ERROR passing `Ty<'tcx>` by reference
+}
+
+#[rustc_pass_by_value]
+struct Foo;
+
+impl Foo {
+ fn with_ref(&self) {} //~ ERROR passing `Foo` by reference
+}
+
+#[rustc_pass_by_value]
+struct WithParameters<T, const N: usize, M = u32> {
+ slice: [T; N],
+ m: M,
+}
+
+impl<T> WithParameters<T, 1> {
+ fn with_ref(&self) {} //~ ERROR passing `WithParameters<T, 1>` by reference
+}
+
+impl<T> WithParameters<T, 1, u8> {
+ fn with_ref(&self) {} //~ ERROR passing `WithParameters<T, 1, u8>` by reference
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr
new file mode 100644
index 000000000..fb39ed60b
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr
@@ -0,0 +1,38 @@
+error: passing `TyCtxt<'tcx>` by reference
+ --> $DIR/rustc_pass_by_value_self.rs:18:15
+ |
+LL | fn by_ref(&self) {}
+ | ^^^^^ help: try passing by value: `TyCtxt<'tcx>`
+ |
+note: the lint level is defined here
+ --> $DIR/rustc_pass_by_value_self.rs:8:9
+ |
+LL | #![deny(rustc::pass_by_value)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: passing `Ty<'tcx>` by reference
+ --> $DIR/rustc_pass_by_value_self.rs:30:21
+ |
+LL | fn by_ref(self: &Ty<'tcx>) {}
+ | ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
+
+error: passing `Foo` by reference
+ --> $DIR/rustc_pass_by_value_self.rs:37:17
+ |
+LL | fn with_ref(&self) {}
+ | ^^^^^ help: try passing by value: `Foo`
+
+error: passing `WithParameters<T, 1>` by reference
+ --> $DIR/rustc_pass_by_value_self.rs:47:17
+ |
+LL | fn with_ref(&self) {}
+ | ^^^^^ help: try passing by value: `WithParameters<T, 1>`
+
+error: passing `WithParameters<T, 1, u8>` by reference
+ --> $DIR/rustc_pass_by_value_self.rs:51:17
+ |
+LL | fn with_ref(&self) {}
+ | ^^^^^ help: try passing by value: `WithParameters<T, 1, u8>`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs
new file mode 100644
index 000000000..3f7429a5f
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs
@@ -0,0 +1,55 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+
+extern crate rustc_middle;
+extern crate rustc_type_ir;
+
+use rustc_middle::ty::{self, Ty, TyKind};
+use rustc_type_ir::{Interner, TyKind as IrTyKind};
+
+#[deny(rustc::usage_of_ty_tykind)]
+fn main() {
+ let kind = TyKind::Bool; //~ ERROR usage of `ty::TyKind::<kind>`
+
+ match kind {
+ TyKind::Bool => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Char => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Int(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Uint(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Float(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Adt(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Foreign(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Str => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Array(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Slice(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::RawPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Ref(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::FnDef(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::FnPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Dynamic(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Closure(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Generator(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::GeneratorWitness(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Never => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Tuple(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Alias(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Param(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Bound(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Placeholder(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Infer(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ TyKind::Error(_) => (), //~ ERROR usage of `ty::TyKind::<kind>`
+ }
+
+ if let ty::Int(int_ty) = kind {}
+
+ if let TyKind::Int(int_ty) = kind {} //~ ERROR usage of `ty::TyKind::<kind>`
+
+ fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {} //~ ERROR usage of `ty::TyKind`
+
+ fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
+ //~^ ERROR usage of `ty::TyKind`
+ //~| ERROR usage of `ty::TyKind`
+ IrTyKind::Bool //~ ERROR usage of `ty::TyKind::<kind>`
+ }
+}
diff --git a/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr
new file mode 100644
index 000000000..1f49d6b64
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr
@@ -0,0 +1,208 @@
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:13:16
+ |
+LL | let kind = TyKind::Bool;
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+ |
+note: the lint level is defined here
+ --> $DIR/ty_tykind_usage.rs:11:8
+ |
+LL | #[deny(rustc::usage_of_ty_tykind)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:16:9
+ |
+LL | TyKind::Bool => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:17:9
+ |
+LL | TyKind::Char => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:18:9
+ |
+LL | TyKind::Int(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:19:9
+ |
+LL | TyKind::Uint(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:20:9
+ |
+LL | TyKind::Float(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:21:9
+ |
+LL | TyKind::Adt(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:22:9
+ |
+LL | TyKind::Foreign(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:23:9
+ |
+LL | TyKind::Str => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:24:9
+ |
+LL | TyKind::Array(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:25:9
+ |
+LL | TyKind::Slice(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:26:9
+ |
+LL | TyKind::RawPtr(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:27:9
+ |
+LL | TyKind::Ref(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:28:9
+ |
+LL | TyKind::FnDef(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:29:9
+ |
+LL | TyKind::FnPtr(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:30:9
+ |
+LL | TyKind::Dynamic(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:31:9
+ |
+LL | TyKind::Closure(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:32:9
+ |
+LL | TyKind::Generator(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:33:9
+ |
+LL | TyKind::GeneratorWitness(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:34:9
+ |
+LL | TyKind::Never => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:35:9
+ |
+LL | TyKind::Tuple(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:36:9
+ |
+LL | TyKind::Alias(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:37:9
+ |
+LL | TyKind::Param(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:38:9
+ |
+LL | TyKind::Bound(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:39:9
+ |
+LL | TyKind::Placeholder(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:40:9
+ |
+LL | TyKind::Infer(..) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:41:9
+ |
+LL | TyKind::Error(_) => (),
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:46:12
+ |
+LL | if let TyKind::Int(int_ty) = kind {}
+ | ^^^^^^ help: try using `ty::<kind>` directly: `ty`
+
+error: usage of `ty::TyKind`
+ --> $DIR/ty_tykind_usage.rs:48:24
+ |
+LL | fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
+ | ^^^^^^^^^^
+ |
+ = help: try using `Ty` instead
+
+error: usage of `ty::TyKind`
+ --> $DIR/ty_tykind_usage.rs:50:37
+ |
+LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
+ | ^^^^^^^^^^^
+ |
+ = help: try using `Ty` instead
+
+error: usage of `ty::TyKind`
+ --> $DIR/ty_tykind_usage.rs:50:53
+ |
+LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
+ | ^^^^^^^^^^^
+ |
+ = help: try using `Ty` instead
+
+error: usage of `ty::TyKind::<kind>`
+ --> $DIR/ty_tykind_usage.rs:53:9
+ |
+LL | IrTyKind::Bool
+ | --------^^^^^^
+ | |
+ | help: try using `ty::<kind>` directly: `ty`
+
+error: aborting due to 32 previous errors
+
diff --git a/tests/ui-fulldeps/issue-11881.rs b/tests/ui-fulldeps/issue-11881.rs
new file mode 100644
index 000000000..f6360db9b
--- /dev/null
+++ b/tests/ui-fulldeps/issue-11881.rs
@@ -0,0 +1,91 @@
+// run-pass
+
+#![allow(unused_must_use)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+use std::fmt;
+use std::io::prelude::*;
+use std::io::Cursor;
+use std::slice;
+use std::marker::PhantomData;
+
+trait Encoder {
+ type Error;
+}
+
+trait Encodable<S: Encoder> {
+ fn encode(&self, s: &mut S) -> Result<(), S::Error>;
+}
+
+struct JsonEncoder<'a>(PhantomData<&'a mut ()>);
+
+impl Encoder for JsonEncoder<'_> {
+ type Error = ();
+}
+
+struct AsJson<'a, T> {
+ inner: &'a T,
+}
+
+impl<'a, T: for<'r> Encodable<JsonEncoder<'r>>> fmt::Display for AsJson<'a, T> {
+ /// Encodes a json value into a string
+ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Ok(())
+ }
+}
+
+fn as_json<T>(t: &T) -> AsJson<'_, T> {
+ AsJson { inner: t }
+}
+
+struct OpaqueEncoder(Vec<u8>);
+
+impl Encoder for OpaqueEncoder {
+ type Error = ();
+}
+
+
+struct Foo {
+ baz: bool,
+}
+
+impl<S: Encoder> Encodable<S> for Foo {
+ fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
+ Ok(())
+ }
+}
+
+struct Bar {
+ froboz: usize,
+}
+
+impl<S: Encoder> Encodable<S> for Bar {
+ fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
+ Ok(())
+ }
+}
+
+enum WireProtocol {
+ JSON,
+ Opaque,
+ // ...
+}
+
+fn encode_json<T: for<'a> Encodable<JsonEncoder<'a>>>(val: &T, wr: &mut Cursor<Vec<u8>>) {
+ write!(wr, "{}", as_json(val));
+}
+
+fn encode_opaque<T: Encodable<OpaqueEncoder>>(val: &T, wr: Vec<u8>) {
+ let mut encoder = OpaqueEncoder(wr);
+ val.encode(&mut encoder);
+}
+
+pub fn main() {
+ let target = Foo { baz: false };
+ let proto = WireProtocol::JSON;
+ match proto {
+ WireProtocol::JSON => encode_json(&target, &mut Cursor::new(Vec::new())),
+ WireProtocol::Opaque => encode_opaque(&target, Vec::new()),
+ }
+}
diff --git a/tests/ui-fulldeps/issue-13560.rs b/tests/ui-fulldeps/issue-13560.rs
new file mode 100644
index 000000000..5f7d647e2
--- /dev/null
+++ b/tests/ui-fulldeps/issue-13560.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:issue-13560-1.rs
+// aux-build:issue-13560-2.rs
+// aux-build:issue-13560-3.rs
+
+// Regression test for issue #13560, the test itself is all in the dependent
+// libraries. The fail which previously failed to compile is the one numbered 3.
+
+extern crate issue_13560_2 as t2;
+extern crate issue_13560_3 as t3;
+
+fn main() {}
diff --git a/tests/ui-fulldeps/issue-14021.rs b/tests/ui-fulldeps/issue-14021.rs
new file mode 100644
index 000000000..309b5c4a0
--- /dev/null
+++ b/tests/ui-fulldeps/issue-14021.rs
@@ -0,0 +1,33 @@
+// run-pass
+
+#![allow(unused_mut)]
+#![allow(unused_imports)]
+#![feature(rustc_private)]
+
+extern crate rustc_macros;
+extern crate rustc_serialize;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_macros::{Decodable, Encodable};
+use rustc_serialize::opaque::{MemDecoder, MemEncoder};
+use rustc_serialize::{Decodable, Encodable, Encoder};
+
+#[derive(Encodable, Decodable, PartialEq, Debug)]
+struct UnitLikeStruct;
+
+pub fn main() {
+ let obj = UnitLikeStruct;
+
+ let mut encoder = MemEncoder::new();
+ obj.encode(&mut encoder);
+ let data = encoder.finish();
+
+ let mut decoder = MemDecoder::new(&data, 0);
+ let obj2 = UnitLikeStruct::decode(&mut decoder);
+
+ assert_eq!(obj, obj2);
+}
diff --git a/tests/ui-fulldeps/issue-15149.rs b/tests/ui-fulldeps/issue-15149.rs
new file mode 100644
index 000000000..064472f57
--- /dev/null
+++ b/tests/ui-fulldeps/issue-15149.rs
@@ -0,0 +1,57 @@
+// run-pass
+
+#![allow(unused_variables)]
+// no-prefer-dynamic
+// ignore-cross-compile
+
+use std::env;
+use std::ffi::OsStr;
+use std::fs;
+use std::path::PathBuf;
+use std::process;
+use std::str;
+
+fn main() {
+ // If we're the child, make sure we were invoked correctly
+ let args: Vec<String> = env::args().collect();
+ if args.len() > 1 && args[1] == "child" {
+ // FIXME: This should check the whole `args[0]` instead of just
+ // checking that it ends_with the executable name. This
+ // is needed because of Windows, which has a different behavior.
+ // See #15149 for more info.
+ let my_path = env::current_exe().unwrap();
+ return assert_eq!(my_path.file_stem(), Some(OsStr::new("mytest")));
+ }
+
+ test();
+}
+
+fn test() {
+ // If we're the parent, copy our own binary to a new directory.
+ let my_path = env::current_exe().unwrap();
+ let my_dir = my_path.parent().unwrap();
+
+ let child_dir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let child_dir = child_dir.join("issue-15140-child");
+ fs::create_dir_all(&child_dir).unwrap();
+
+ let child_path = child_dir.join(&format!("mytest{}", env::consts::EXE_SUFFIX));
+ fs::copy(&my_path, &child_path).unwrap();
+
+ // Append the new directory to our own PATH.
+ let path = {
+ let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect();
+ paths.push(child_dir.to_path_buf());
+ env::join_paths(paths).unwrap()
+ };
+
+ let child_output =
+ process::Command::new("mytest").env("PATH", &path).arg("child").output().unwrap();
+
+ assert!(
+ child_output.status.success(),
+ "child assertion failed\n child stdout:\n {}\n child stderr:\n {}",
+ str::from_utf8(&child_output.stdout).unwrap(),
+ str::from_utf8(&child_output.stderr).unwrap()
+ );
+}
diff --git a/tests/ui-fulldeps/issue-15778-fail.rs b/tests/ui-fulldeps/issue-15778-fail.rs
new file mode 100644
index 000000000..beecaadf9
--- /dev/null
+++ b/tests/ui-fulldeps/issue-15778-fail.rs
@@ -0,0 +1,9 @@
+// aux-build:lint-for-crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin)] //~ ERROR crate is not marked with #![crate_okay]
+#![plugin(lint_for_crate)]
+//~^ WARN use of deprecated attribute `plugin`
+
+pub fn main() { }
diff --git a/tests/ui-fulldeps/issue-15778-fail.stderr b/tests/ui-fulldeps/issue-15778-fail.stderr
new file mode 100644
index 000000000..a37893e12
--- /dev/null
+++ b/tests/ui-fulldeps/issue-15778-fail.stderr
@@ -0,0 +1,22 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/issue-15778-fail.rs:6:1
+ |
+LL | #![plugin(lint_for_crate)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: crate is not marked with #![crate_okay]
+ --> $DIR/issue-15778-fail.rs:5:1
+ |
+LL | / #![feature(plugin)]
+LL | | #![plugin(lint_for_crate)]
+LL | |
+LL | |
+LL | | pub fn main() { }
+ | |_________________^
+ |
+ = note: requested on the command line with `-D crate-not-okay`
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui-fulldeps/issue-15924.rs b/tests/ui-fulldeps/issue-15924.rs
new file mode 100644
index 000000000..d8b3914d0
--- /dev/null
+++ b/tests/ui-fulldeps/issue-15924.rs
@@ -0,0 +1,53 @@
+// run-pass
+
+#![allow(unused_imports)]
+#![allow(unused_must_use)]
+// pretty-expanded FIXME #23616
+
+use std::fmt;
+use std::marker::PhantomData;
+
+trait Encoder {
+ type Error;
+}
+
+trait Encodable<S: Encoder> {
+ fn encode(&self, s: &mut S) -> Result<(), S::Error>;
+}
+
+impl<S: Encoder> Encodable<S> for i32 {
+ fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
+ Ok(())
+ }
+}
+
+struct JsonEncoder<'a>(PhantomData<&'a mut ()>);
+
+impl Encoder for JsonEncoder<'_> {
+ type Error = ();
+}
+
+fn encode_json<T: for<'r> Encodable<JsonEncoder<'r>>>(
+ object: &T,
+) -> Result<String, ()> {
+ let s = String::new();
+ {
+ let mut encoder = JsonEncoder(PhantomData);
+ object.encode(&mut encoder)?;
+ }
+ Ok(s)
+}
+
+struct Foo<T: for<'a> Encodable<JsonEncoder<'a>>> {
+ v: T,
+}
+
+impl<T: for<'a> Encodable<JsonEncoder<'a>>> Drop for Foo<T> {
+ fn drop(&mut self) {
+ encode_json(&self.v);
+ }
+}
+
+fn main() {
+ let _ = Foo { v: 10 };
+}
diff --git a/tests/ui-fulldeps/issue-16822.rs b/tests/ui-fulldeps/issue-16822.rs
new file mode 100644
index 000000000..c611c33af
--- /dev/null
+++ b/tests/ui-fulldeps/issue-16822.rs
@@ -0,0 +1,22 @@
+// run-pass
+// aux-build:issue-16822.rs
+
+extern crate issue_16822 as lib;
+
+use std::cell::RefCell;
+
+struct App {
+ i: isize
+}
+
+impl lib::Update for App {
+ fn update(&mut self) {
+ self.i += 1;
+ }
+}
+
+fn main(){
+ let app = App { i: 5 };
+ let window = lib::Window { data: RefCell::new(app) };
+ window.update(1);
+}
diff --git a/tests/ui-fulldeps/issue-18502.rs b/tests/ui-fulldeps/issue-18502.rs
new file mode 100644
index 000000000..2082ae7a9
--- /dev/null
+++ b/tests/ui-fulldeps/issue-18502.rs
@@ -0,0 +1,8 @@
+// run-pass
+// aux-build:issue-18502.rs
+
+extern crate issue_18502 as fmt;
+
+fn main() {
+ ::fmt::baz();
+}
diff --git a/tests/ui-fulldeps/issue-24106.rs b/tests/ui-fulldeps/issue-24106.rs
new file mode 100644
index 000000000..45f0bd5b6
--- /dev/null
+++ b/tests/ui-fulldeps/issue-24106.rs
@@ -0,0 +1,8 @@
+// run-pass
+// aux-build:issue-24106.rs
+
+extern crate issue_24106;
+
+fn main() {
+ issue_24106::go::<()>();
+}
diff --git a/tests/ui-fulldeps/issue-2804.rs b/tests/ui-fulldeps/issue-2804.rs
new file mode 100644
index 000000000..571028c5e
--- /dev/null
+++ b/tests/ui-fulldeps/issue-2804.rs
@@ -0,0 +1,81 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+#![allow(dead_code)]
+
+use std::collections::{BTreeMap, HashMap};
+use std::option;
+
+#[derive(Clone, Debug)]
+enum Json {
+ I64(i64),
+ U64(u64),
+ F64(f64),
+ String(String),
+ Boolean(bool),
+ Array(Array),
+ Object(Object),
+ Null,
+}
+
+type Array = Vec<Json>;
+type Object = BTreeMap<String, Json>;
+
+enum object {
+ bool_value(bool),
+ int_value(i64),
+}
+
+fn lookup(table: Object, key: String, default: String) -> String
+{
+ match table.get(&key) {
+ option::Option::Some(&Json::String(ref s)) => {
+ s.to_string()
+ }
+ option::Option::Some(value) => {
+ println!("{} was expected to be a string but is a {:?}", key, value);
+ default
+ }
+ option::Option::None => {
+ default
+ }
+ }
+}
+
+fn add_interface(_store: isize, managed_ip: String, data: Json) -> (String, object)
+{
+ match &data {
+ &Json::Object(ref interface) => {
+ let name = lookup(interface.clone(),
+ "ifDescr".to_string(),
+ "".to_string());
+ let label = format!("{}-{}", managed_ip, name);
+
+ (label, object::bool_value(false))
+ }
+ _ => {
+ println!("Expected dict for {} interfaces, found {:?}", managed_ip, data);
+ ("gnos:missing-interface".to_string(), object::bool_value(true))
+ }
+ }
+}
+
+fn add_interfaces(store: isize, managed_ip: String, device: HashMap<String, Json>)
+-> Vec<(String, object)> {
+ match device["interfaces"] {
+ Json::Array(ref interfaces) =>
+ {
+ interfaces.iter().map(|interface| {
+ add_interface(store, managed_ip.clone(), (*interface).clone())
+ }).collect()
+ }
+ _ =>
+ {
+ println!("Expected list for {} interfaces, found {:?}", managed_ip,
+ device["interfaces"]);
+ Vec::new()
+ }
+ }
+}
+
+pub fn main() {}
diff --git a/tests/ui-fulldeps/issue-40001.rs b/tests/ui-fulldeps/issue-40001.rs
new file mode 100644
index 000000000..e14338fdb
--- /dev/null
+++ b/tests/ui-fulldeps/issue-40001.rs
@@ -0,0 +1,10 @@
+// run-pass
+// aux-build:issue-40001-plugin.rs
+// ignore-stage1
+
+#![feature(plugin, register_tool)]
+#![plugin(issue_40001_plugin)] //~ WARNING compiler plugins are deprecated
+#![register_tool(plugin)]
+
+#[plugin::allowed_attr]
+fn main() {}
diff --git a/tests/ui-fulldeps/issue-40001.stderr b/tests/ui-fulldeps/issue-40001.stderr
new file mode 100644
index 000000000..73ec06924
--- /dev/null
+++ b/tests/ui-fulldeps/issue-40001.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/issue-40001.rs:6:1
+ |
+LL | #![plugin(issue_40001_plugin)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs b/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs
new file mode 100644
index 000000000..fdf1150f8
--- /dev/null
+++ b/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs
@@ -0,0 +1,81 @@
+// run-fail
+// only-windows
+
+fn main() {
+ use std::fs;
+ use std::io::prelude::*;
+ use std::os::windows::prelude::*;
+ use std::ptr;
+ use std::sync::Arc;
+ use std::thread;
+ use std::time::Duration;
+
+ const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
+
+ fn create_pipe_server(path: &str) -> fs::File {
+ let mut path0 = path.as_bytes().to_owned();
+ path0.push(0);
+ extern "system" {
+ fn CreateNamedPipeA(
+ lpName: *const u8,
+ dwOpenMode: u32,
+ dwPipeMode: u32,
+ nMaxInstances: u32,
+ nOutBufferSize: u32,
+ nInBufferSize: u32,
+ nDefaultTimeOut: u32,
+ lpSecurityAttributes: *mut u8,
+ ) -> RawHandle;
+ }
+
+ unsafe {
+ let h = CreateNamedPipeA(path0.as_ptr(), 3, 0, 1, 0, 0, 0, ptr::null_mut());
+ assert_ne!(h as isize, -1);
+ fs::File::from_raw_handle(h)
+ }
+ }
+
+ let path = "\\\\.\\pipe\\repro";
+ let mut server = create_pipe_server(path);
+
+ let client = Arc::new(
+ fs::OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).read(true).open(path).unwrap(),
+ );
+
+ let spawn_read = |is_first: bool| {
+ thread::spawn({
+ let f = client.clone();
+ move || {
+ let mut buf = [0xcc; 1];
+ let mut f = f.as_ref();
+ f.read(&mut buf).unwrap();
+ if is_first {
+ assert_ne!(buf[0], 0xcc);
+ } else {
+ let b = buf[0]; // capture buf[0]
+ thread::sleep(Duration::from_millis(200));
+
+ // Check the buffer hasn't been written to after read.
+ dbg!(buf[0], b);
+ assert_eq!(buf[0], b);
+ }
+ }
+ })
+ };
+
+ let t1 = spawn_read(true);
+ thread::sleep(Duration::from_millis(20));
+ let t2 = spawn_read(false);
+ thread::sleep(Duration::from_millis(100));
+ let _ = server.write(b"x");
+ thread::sleep(Duration::from_millis(100));
+ let _ = server.write(b"y");
+
+ // This is run fail because we need to test for the `abort`.
+ // That failing to run is the success case.
+ if t1.join().is_err() || t2.join().is_err() {
+ return;
+ } else {
+ panic!("success");
+ }
+}
diff --git a/tests/ui-fulldeps/lint-group-denied-lint-allowed.rs b/tests/ui-fulldeps/lint-group-denied-lint-allowed.rs
new file mode 100644
index 000000000..7498745f2
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-denied-lint-allowed.rs
@@ -0,0 +1,7 @@
+// aux-build:lint-group-plugin-test.rs
+// check-pass
+// compile-flags: -D unused -A unused-variables
+
+fn main() {
+ let x = 1;
+}
diff --git a/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs b/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs
new file mode 100644
index 000000000..fc19bc039
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs
@@ -0,0 +1,7 @@
+// aux-build:lint-group-plugin-test.rs
+// compile-flags: -F unused -A unused
+
+fn main() {
+ let x = 1;
+ //~^ ERROR unused variable: `x`
+}
diff --git a/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr b/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr
new file mode 100644
index 000000000..6bab367b0
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr
@@ -0,0 +1,10 @@
+error: unused variable: `x`
+ --> $DIR/lint-group-forbid-always-trumps-cli.rs:5:9
+ |
+LL | let x = 1;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+ = note: `-F unused-variables` implied by `-F unused`
+
+error: aborting due to previous error
+
diff --git a/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.rs b/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
new file mode 100644
index 000000000..9f8a87960
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
@@ -0,0 +1,17 @@
+// aux-build:lint-group-plugin-test.rs
+// ignore-stage1
+// compile-flags: -D lint-me
+
+#![feature(plugin)]
+
+#![plugin(lint_group_plugin_test)]
+//~^ WARN use of deprecated attribute `plugin`
+
+fn lintme() { } //~ ERROR item is named 'lintme'
+
+fn pleaselintme() { } //~ ERROR item is named 'pleaselintme'
+
+pub fn main() {
+ lintme();
+ pleaselintme();
+}
diff --git a/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr b/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr
new file mode 100644
index 000000000..20486d596
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr
@@ -0,0 +1,26 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-group-plugin-deny-cmdline.rs:7:1
+ |
+LL | #![plugin(lint_group_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: item is named 'lintme'
+ --> $DIR/lint-group-plugin-deny-cmdline.rs:10:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: `-D test-lint` implied by `-D lint-me`
+
+error: item is named 'pleaselintme'
+ --> $DIR/lint-group-plugin-deny-cmdline.rs:12:1
+ |
+LL | fn pleaselintme() { }
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D please-lint` implied by `-D lint-me`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui-fulldeps/lint-group-plugin.rs b/tests/ui-fulldeps/lint-group-plugin.rs
new file mode 100644
index 000000000..7b74be7a9
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-plugin.rs
@@ -0,0 +1,17 @@
+// run-pass
+// aux-build:lint-group-plugin-test.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(lint_group_plugin_test)] //~ WARNING use of deprecated attribute
+#![allow(dead_code)]
+
+fn lintme() { } //~ WARNING item is named 'lintme'
+fn pleaselintme() { } //~ WARNING item is named 'pleaselintme'
+
+#[allow(lint_me)]
+pub fn main() {
+ fn lintme() { }
+
+ fn pleaselintme() { }
+}
diff --git a/tests/ui-fulldeps/lint-group-plugin.stderr b/tests/ui-fulldeps/lint-group-plugin.stderr
new file mode 100644
index 000000000..6f429dad0
--- /dev/null
+++ b/tests/ui-fulldeps/lint-group-plugin.stderr
@@ -0,0 +1,26 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-group-plugin.rs:6:1
+ |
+LL | #![plugin(lint_group_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: item is named 'lintme'
+ --> $DIR/lint-group-plugin.rs:9:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(test_lint)]` on by default
+
+warning: item is named 'pleaselintme'
+ --> $DIR/lint-group-plugin.rs:10:1
+ |
+LL | fn pleaselintme() { }
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(please_lint)]` on by default
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui-fulldeps/lint-pass-macros.rs b/tests/ui-fulldeps/lint-pass-macros.rs
new file mode 100644
index 000000000..b3c2a5427
--- /dev/null
+++ b/tests/ui-fulldeps/lint-pass-macros.rs
@@ -0,0 +1,26 @@
+// compile-flags: -Z unstable-options
+// check-pass
+
+#![feature(rustc_private)]
+
+extern crate rustc_session;
+
+use rustc_session::lint::{LintArray, LintPass};
+use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
+
+declare_lint! {
+ pub TEST_LINT,
+ Allow,
+ "test"
+}
+
+struct Foo;
+
+struct Bar<'a>(&'a u32);
+
+impl_lint_pass!(Foo => [TEST_LINT]);
+impl_lint_pass!(Bar<'_> => [TEST_LINT]);
+
+declare_lint_pass!(Baz => [TEST_LINT]);
+
+fn main() {}
diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-allow.rs b/tests/ui-fulldeps/lint-plugin-cmdline-allow.rs
new file mode 100644
index 000000000..1cc16e2fd
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-cmdline-allow.rs
@@ -0,0 +1,12 @@
+// check-pass
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+// compile-flags: -A test-lint
+
+#![feature(plugin)]
+#![plugin(lint_plugin_test)] //~ WARNING compiler plugins are deprecated
+
+fn lintme() { }
+
+pub fn main() {
+}
diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-allow.stderr b/tests/ui-fulldeps/lint-plugin-cmdline-allow.stderr
new file mode 100644
index 000000000..f06703a27
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-cmdline-allow.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-cmdline-allow.rs:7:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-load.rs b/tests/ui-fulldeps/lint-plugin-cmdline-load.rs
new file mode 100644
index 000000000..0bd95dfbd
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-cmdline-load.rs
@@ -0,0 +1,13 @@
+// check-pass
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+// compile-flags: -Z crate-attr=plugin(lint_plugin_test)
+
+#![feature(plugin)]
+
+fn lintme() { } //~ WARNING item is named 'lintme'
+
+#[allow(test_lint)]
+pub fn main() {
+ fn lintme() { }
+}
diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-load.stderr b/tests/ui-fulldeps/lint-plugin-cmdline-load.stderr
new file mode 100644
index 000000000..82679c9e1
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-cmdline-load.stderr
@@ -0,0 +1,18 @@
+warning: item is named 'lintme'
+ --> $DIR/lint-plugin-cmdline-load.rs:8:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(test_lint)]` on by default
+
+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: 2 warnings emitted
+
diff --git a/tests/ui-fulldeps/lint-plugin-deny-attr.rs b/tests/ui-fulldeps/lint-plugin-deny-attr.rs
new file mode 100644
index 000000000..04230a8e8
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-deny-attr.rs
@@ -0,0 +1,13 @@
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(lint_plugin_test)]
+//~^ WARN use of deprecated attribute `plugin`
+#![deny(test_lint)]
+
+fn lintme() { } //~ ERROR item is named 'lintme'
+
+pub fn main() {
+ lintme();
+}
diff --git a/tests/ui-fulldeps/lint-plugin-deny-attr.stderr b/tests/ui-fulldeps/lint-plugin-deny-attr.stderr
new file mode 100644
index 000000000..5e8891bf1
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-deny-attr.stderr
@@ -0,0 +1,22 @@
+error: item is named 'lintme'
+ --> $DIR/lint-plugin-deny-attr.rs:9:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-plugin-deny-attr.rs:7:9
+ |
+LL | #![deny(test_lint)]
+ | ^^^^^^^^^
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-deny-attr.rs:5:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui-fulldeps/lint-plugin-deny-cmdline.rs b/tests/ui-fulldeps/lint-plugin-deny-cmdline.rs
new file mode 100644
index 000000000..c460cfd5f
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-deny-cmdline.rs
@@ -0,0 +1,13 @@
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+// compile-flags: -D test-lint
+
+#![feature(plugin)]
+#![plugin(lint_plugin_test)]
+//~^ WARN use of deprecated attribute `plugin`
+
+fn lintme() { } //~ ERROR item is named 'lintme'
+
+pub fn main() {
+ lintme();
+}
diff --git a/tests/ui-fulldeps/lint-plugin-deny-cmdline.stderr b/tests/ui-fulldeps/lint-plugin-deny-cmdline.stderr
new file mode 100644
index 000000000..d5d6b5352
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-deny-cmdline.stderr
@@ -0,0 +1,18 @@
+error: item is named 'lintme'
+ --> $DIR/lint-plugin-deny-cmdline.rs:9:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `-D test-lint`
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-deny-cmdline.rs:6:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui-fulldeps/lint-plugin-forbid-attrs.rs b/tests/ui-fulldeps/lint-plugin-forbid-attrs.rs
new file mode 100644
index 000000000..cf31b3ec1
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-forbid-attrs.rs
@@ -0,0 +1,16 @@
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(lint_plugin_test)]
+//~^ WARN use of deprecated attribute `plugin`
+#![forbid(test_lint)]
+
+fn lintme() {} //~ ERROR item is named 'lintme'
+
+#[allow(test_lint)]
+//~^ ERROR allow(test_lint) incompatible
+//~| ERROR allow(test_lint) incompatible
+pub fn main() {
+ lintme();
+}
diff --git a/tests/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/tests/ui-fulldeps/lint-plugin-forbid-attrs.stderr
new file mode 100644
index 000000000..ae34b25cc
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-forbid-attrs.stderr
@@ -0,0 +1,41 @@
+error[E0453]: allow(test_lint) incompatible with previous forbid
+ --> $DIR/lint-plugin-forbid-attrs.rs:11:9
+ |
+LL | #![forbid(test_lint)]
+ | --------- `forbid` level set here
+...
+LL | #[allow(test_lint)]
+ | ^^^^^^^^^ overruled by previous forbid
+
+error: item is named 'lintme'
+ --> $DIR/lint-plugin-forbid-attrs.rs:9:1
+ |
+LL | fn lintme() {}
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-plugin-forbid-attrs.rs:7:11
+ |
+LL | #![forbid(test_lint)]
+ | ^^^^^^^^^
+
+error[E0453]: allow(test_lint) incompatible with previous forbid
+ --> $DIR/lint-plugin-forbid-attrs.rs:11:9
+ |
+LL | #![forbid(test_lint)]
+ | --------- `forbid` level set here
+...
+LL | #[allow(test_lint)]
+ | ^^^^^^^^^ overruled by previous forbid
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-forbid-attrs.rs:5:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/tests/ui-fulldeps/lint-plugin-forbid-cmdline.rs
new file mode 100644
index 000000000..b9d1aa85a
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-forbid-cmdline.rs
@@ -0,0 +1,15 @@
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+// compile-flags: -F test-lint
+
+#![feature(plugin)]
+#![plugin(lint_plugin_test)]
+//~^ WARN use of deprecated attribute `plugin`
+fn lintme() { } //~ ERROR item is named 'lintme'
+
+#[allow(test_lint)] //~ ERROR allow(test_lint) incompatible
+ //~| ERROR allow(test_lint) incompatible
+
+pub fn main() {
+ lintme();
+}
diff --git a/tests/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/tests/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
new file mode 100644
index 000000000..491c4d206
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
@@ -0,0 +1,35 @@
+error[E0453]: allow(test_lint) incompatible with previous forbid
+ --> $DIR/lint-plugin-forbid-cmdline.rs:10:9
+ |
+LL | #[allow(test_lint)]
+ | ^^^^^^^^^ overruled by previous forbid
+ |
+ = note: `forbid` lint level was set on command line
+
+error: item is named 'lintme'
+ --> $DIR/lint-plugin-forbid-cmdline.rs:8:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `-F test-lint`
+
+error[E0453]: allow(test_lint) incompatible with previous forbid
+ --> $DIR/lint-plugin-forbid-cmdline.rs:10:9
+ |
+LL | #[allow(test_lint)]
+ | ^^^^^^^^^ overruled by previous forbid
+ |
+ = note: `forbid` lint level was set on command line
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-forbid-cmdline.rs:6:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui-fulldeps/lint-plugin.rs b/tests/ui-fulldeps/lint-plugin.rs
new file mode 100644
index 000000000..66057eea6
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:lint-plugin-test.rs
+// ignore-stage1
+#![feature(plugin)]
+#![plugin(lint_plugin_test)] //~ WARNING use of deprecated attribute
+#![allow(dead_code)]
+
+fn lintme() { } //~ WARNING item is named 'lintme'
+
+#[allow(test_lint)]
+pub fn main() {
+ fn lintme() { }
+}
diff --git a/tests/ui-fulldeps/lint-plugin.stderr b/tests/ui-fulldeps/lint-plugin.stderr
new file mode 100644
index 000000000..dd5d3d72e
--- /dev/null
+++ b/tests/ui-fulldeps/lint-plugin.stderr
@@ -0,0 +1,18 @@
+warning: item is named 'lintme'
+ --> $DIR/lint-plugin.rs:8:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(test_lint)]` on by default
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin.rs:5:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui-fulldeps/lint-tool-cmdline-allow.rs b/tests/ui-fulldeps/lint-tool-cmdline-allow.rs
new file mode 100644
index 000000000..83a8b3e1a
--- /dev/null
+++ b/tests/ui-fulldeps/lint-tool-cmdline-allow.rs
@@ -0,0 +1,12 @@
+// check-pass
+// aux-build:lint-tool-test.rs
+// ignore-stage1
+// compile-flags: -A test-lint
+
+#![feature(plugin)]
+#![plugin(lint_tool_test)] //~ WARNING compiler plugins are deprecated
+
+fn lintme() {}
+//~^ WARNING item is named 'lintme' [clippy::test_lint]
+
+pub fn main() {}
diff --git a/tests/ui-fulldeps/lint-tool-cmdline-allow.stderr b/tests/ui-fulldeps/lint-tool-cmdline-allow.stderr
new file mode 100644
index 000000000..b060e3a3e
--- /dev/null
+++ b/tests/ui-fulldeps/lint-tool-cmdline-allow.stderr
@@ -0,0 +1,30 @@
+warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
+ |
+ = note: requested on the command line with `-A test_lint`
+
+warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
+ |
+ = note: requested on the command line with `-A test_lint`
+
+warning: item is named 'lintme'
+ --> $DIR/lint-tool-cmdline-allow.rs:9:1
+ |
+LL | fn lintme() {}
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(clippy::test_lint)]` on by default
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-tool-cmdline-allow.rs:7:1
+ |
+LL | #![plugin(lint_tool_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
+ |
+ = note: requested on the command line with `-A test_lint`
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui-fulldeps/lint-tool-test.rs b/tests/ui-fulldeps/lint-tool-test.rs
new file mode 100644
index 000000000..f92bcd213
--- /dev/null
+++ b/tests/ui-fulldeps/lint-tool-test.rs
@@ -0,0 +1,36 @@
+// aux-build:lint-tool-test.rs
+// ignore-stage1
+// compile-flags: --cfg foo
+
+#![feature(plugin)]
+#![plugin(lint_tool_test)]
+//~^ WARN use of deprecated attribute `plugin`
+#![allow(dead_code)]
+#![cfg_attr(foo, warn(test_lint))]
+//~^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future
+//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
+//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
+#![deny(clippy_group)]
+//~^ WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
+//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
+//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
+
+fn lintme() { } //~ ERROR item is named 'lintme'
+
+#[allow(clippy::group)]
+fn lintmetoo() {}
+
+#[allow(clippy::test_lint)]
+pub fn main() {
+ fn lintme() { }
+ fn lintmetoo() { } //~ ERROR item is named 'lintmetoo'
+}
+
+#[allow(test_group)]
+//~^ WARNING lint name `test_group` is deprecated and may not have an effect in the future
+//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
+//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
+#[deny(this_lint_does_not_exist)] //~ WARNING unknown lint: `this_lint_does_not_exist`
+fn hello() {
+ fn lintmetoo() { }
+}
diff --git a/tests/ui-fulldeps/lint-tool-test.stderr b/tests/ui-fulldeps/lint-tool-test.stderr
new file mode 100644
index 000000000..027cf8f80
--- /dev/null
+++ b/tests/ui-fulldeps/lint-tool-test.stderr
@@ -0,0 +1,95 @@
+warning: lint name `test_lint` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:9:23
+ |
+LL | #![cfg_attr(foo, warn(test_lint))]
+ | ^^^^^^^^^ help: change it to: `clippy::test_lint`
+ |
+ = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:13:9
+ |
+LL | #![deny(clippy_group)]
+ | ^^^^^^^^^^^^ help: change it to: `clippy::group`
+
+warning: lint name `test_group` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:29:9
+ |
+LL | #[allow(test_group)]
+ | ^^^^^^^^^^ help: change it to: `clippy::test_group`
+
+warning: lint name `test_lint` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:9:23
+ |
+LL | #![cfg_attr(foo, warn(test_lint))]
+ | ^^^^^^^^^ help: change it to: `clippy::test_lint`
+
+warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:13:9
+ |
+LL | #![deny(clippy_group)]
+ | ^^^^^^^^^^^^ help: change it to: `clippy::group`
+
+error: item is named 'lintme'
+ --> $DIR/lint-tool-test.rs:18:1
+ |
+LL | fn lintme() { }
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-tool-test.rs:13:9
+ |
+LL | #![deny(clippy_group)]
+ | ^^^^^^^^^^^^
+ = note: `#[deny(clippy::test_lint)]` implied by `#[deny(clippy::group)]`
+
+error: item is named 'lintmetoo'
+ --> $DIR/lint-tool-test.rs:26:5
+ |
+LL | fn lintmetoo() { }
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]`
+
+warning: lint name `test_group` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:29:9
+ |
+LL | #[allow(test_group)]
+ | ^^^^^^^^^^ help: change it to: `clippy::test_group`
+
+warning: unknown lint: `this_lint_does_not_exist`
+ --> $DIR/lint-tool-test.rs:33:8
+ |
+LL | #[deny(this_lint_does_not_exist)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unknown_lints)]` on by default
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-tool-test.rs:6:1
+ |
+LL | #![plugin(lint_tool_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: lint name `test_lint` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:9:23
+ |
+LL | #![cfg_attr(foo, warn(test_lint))]
+ | ^^^^^^^^^ help: change it to: `clippy::test_lint`
+
+warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:13:9
+ |
+LL | #![deny(clippy_group)]
+ | ^^^^^^^^^^^^ help: change it to: `clippy::group`
+
+warning: lint name `test_group` is deprecated and may not have an effect in the future.
+ --> $DIR/lint-tool-test.rs:29:9
+ |
+LL | #[allow(test_group)]
+ | ^^^^^^^^^^ help: change it to: `clippy::test_group`
+
+error: aborting due to 2 previous errors; 11 warnings emitted
+
diff --git a/tests/ui-fulldeps/lto-syntax-extension.rs b/tests/ui-fulldeps/lto-syntax-extension.rs
new file mode 100644
index 000000000..5964e70f1
--- /dev/null
+++ b/tests/ui-fulldeps/lto-syntax-extension.rs
@@ -0,0 +1,15 @@
+// run-pass
+// aux-build:lto-syntax-extension-lib.rs
+// aux-build:lto-syntax-extension-plugin.rs
+// compile-flags:-C lto
+// ignore-stage1
+// no-prefer-dynamic
+
+#![feature(plugin)]
+#![plugin(lto_syntax_extension_plugin)] //~ WARNING compiler plugins are deprecated
+
+extern crate lto_syntax_extension_lib;
+
+fn main() {
+ lto_syntax_extension_lib::foo();
+}
diff --git a/tests/ui-fulldeps/lto-syntax-extension.stderr b/tests/ui-fulldeps/lto-syntax-extension.stderr
new file mode 100644
index 000000000..555493f32
--- /dev/null
+++ b/tests/ui-fulldeps/lto-syntax-extension.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lto-syntax-extension.rs:9:1
+ |
+LL | #![plugin(lto_syntax_extension_plugin)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui-fulldeps/macro-crate-rlib.rs b/tests/ui-fulldeps/macro-crate-rlib.rs
new file mode 100644
index 000000000..1fd514c61
--- /dev/null
+++ b/tests/ui-fulldeps/macro-crate-rlib.rs
@@ -0,0 +1,8 @@
+// aux-build:rlib-crate-test.rs
+// ignore-cross-compile gives a different error message
+
+#![feature(plugin)]
+#![plugin(rlib_crate_test)]
+//~^ ERROR: plugin `rlib_crate_test` only found in rlib format, but must be available in dylib
+
+fn main() {}
diff --git a/tests/ui-fulldeps/macro-crate-rlib.stderr b/tests/ui-fulldeps/macro-crate-rlib.stderr
new file mode 100644
index 000000000..9c2b992b7
--- /dev/null
+++ b/tests/ui-fulldeps/macro-crate-rlib.stderr
@@ -0,0 +1,9 @@
+error[E0457]: plugin `rlib_crate_test` only found in rlib format, but must be available in dylib format
+ --> $DIR/macro-crate-rlib.rs:5:11
+ |
+LL | #![plugin(rlib_crate_test)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0457`.
diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.rs b/tests/ui-fulldeps/missing-rustc-driver-error.rs
new file mode 100644
index 000000000..654cd6f6d
--- /dev/null
+++ b/tests/ui-fulldeps/missing-rustc-driver-error.rs
@@ -0,0 +1,11 @@
+// Test that we get the following hint when trying to use a compiler crate without rustc_driver.
+// error-pattern: try adding `extern crate rustc_driver;` at the top level of this crate
+// compile-flags: --emit link
+// The exactly list of required crates depends on the target. as such only test Unix targets.
+// only-unix
+
+#![feature(rustc_private)]
+
+extern crate rustc_serialize;
+
+fn main() {}
diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.stderr b/tests/ui-fulldeps/missing-rustc-driver-error.stderr
new file mode 100644
index 000000000..ad03ba010
--- /dev/null
+++ b/tests/ui-fulldeps/missing-rustc-driver-error.stderr
@@ -0,0 +1,24 @@
+error: crate `rustc_serialize` required to be available in rlib format, but was not found in this form
+ |
+ = help: try adding `extern crate rustc_driver;` at the top level of this crate
+
+error: crate `smallvec` required to be available in rlib format, but was not found in this form
+
+error: crate `thin_vec` required to be available in rlib format, but was not found in this form
+
+error: crate `indexmap` required to be available in rlib format, but was not found in this form
+
+error: crate `hashbrown` required to be available in rlib format, but was not found in this form
+
+error: crate `ahash` required to be available in rlib format, but was not found in this form
+
+error: crate `once_cell` required to be available in rlib format, but was not found in this form
+
+error: crate `getrandom` required to be available in rlib format, but was not found in this form
+
+error: crate `cfg_if` required to be available in rlib format, but was not found in this form
+
+error: crate `libc` required to be available in rlib format, but was not found in this form
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
new file mode 100644
index 000000000..bdfd9628c
--- /dev/null
+++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -0,0 +1,40 @@
+// run-pass
+// Testing that a librustc_ast can parse modules with canonicalized base path
+// ignore-cross-compile
+// ignore-remote
+// no-remap-src-base: Reading `file!()` (expectedly) fails when enabled.
+
+#![feature(rustc_private)]
+
+extern crate rustc_ast;
+extern crate rustc_parse;
+extern crate rustc_session;
+extern crate rustc_span;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_parse::new_parser_from_file;
+use rustc_session::parse::ParseSess;
+use rustc_span::source_map::FilePathMapping;
+use std::path::Path;
+
+#[path = "mod_dir_simple/test.rs"]
+mod gravy;
+
+pub fn main() {
+ rustc_span::create_default_session_globals_then(|| parse());
+
+ assert_eq!(gravy::foo(), 10);
+}
+
+fn parse() {
+ let parse_session = ParseSess::new(FilePathMapping::empty());
+
+ let path = Path::new(file!());
+ let path = path.canonicalize().unwrap();
+ let mut parser = new_parser_from_file(&parse_session, &path, None);
+ let _ = parser.parse_crate_mod();
+}
diff --git a/tests/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir b/tests/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/ui-fulldeps/mod_dir_simple/compiletest-ignore-dir
diff --git a/tests/ui-fulldeps/mod_dir_simple/test.rs b/tests/ui-fulldeps/mod_dir_simple/test.rs
new file mode 100644
index 000000000..35e26093a
--- /dev/null
+++ b/tests/ui-fulldeps/mod_dir_simple/test.rs
@@ -0,0 +1,3 @@
+// run-pass
+
+pub fn foo() -> isize { 10 }
diff --git a/tests/ui-fulldeps/multiple-plugins.rs b/tests/ui-fulldeps/multiple-plugins.rs
new file mode 100644
index 000000000..9af3ebd57
--- /dev/null
+++ b/tests/ui-fulldeps/multiple-plugins.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:multiple-plugins-1.rs
+// aux-build:multiple-plugins-2.rs
+// ignore-stage1
+
+// 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() {}
diff --git a/tests/ui-fulldeps/multiple-plugins.stderr b/tests/ui-fulldeps/multiple-plugins.stderr
new file mode 100644
index 000000000..878ffabfc
--- /dev/null
+++ b/tests/ui-fulldeps/multiple-plugins.stderr
@@ -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:9: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:10:1
+ |
+LL | #![plugin(multiple_plugins_2)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui-fulldeps/myriad-closures.rs b/tests/ui-fulldeps/myriad-closures.rs
new file mode 100644
index 000000000..310351f50
--- /dev/null
+++ b/tests/ui-fulldeps/myriad-closures.rs
@@ -0,0 +1,39 @@
+// run-pass
+// This test case tests whether we can handle code bases that contain a high
+// number of closures, something that needs special handling in the MingGW
+// toolchain.
+// See https://github.com/rust-lang/rust/issues/34793 for more information.
+
+// Make sure we don't optimize anything away:
+// compile-flags: -C no-prepopulate-passes -Cpasses=name-anon-globals
+
+// Expand something exponentially
+macro_rules! go_bacterial {
+ ($mac:ident) => ($mac!());
+ ($mac:ident 1 $($t:tt)*) => (
+ go_bacterial!($mac $($t)*);
+ go_bacterial!($mac $($t)*);
+ )
+}
+
+macro_rules! mk_closure {
+ () => ((move || {})())
+}
+
+macro_rules! mk_fn {
+ () => {
+ {
+ fn function() {
+ // Make 16 closures
+ go_bacterial!(mk_closure 1 1 1 1);
+ }
+ let _ = function();
+ }
+ }
+}
+
+fn main() {
+ // Make 2^8 functions, each containing 16 closures,
+ // resulting in 2^12 closures overall.
+ go_bacterial!(mk_fn 1 1 1 1 1 1 1 1);
+}
diff --git a/tests/ui-fulldeps/outlive-expansion-phase.rs b/tests/ui-fulldeps/outlive-expansion-phase.rs
new file mode 100644
index 000000000..fb22888d9
--- /dev/null
+++ b/tests/ui-fulldeps/outlive-expansion-phase.rs
@@ -0,0 +1,8 @@
+// run-pass
+// aux-build:outlive-expansion-phase.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(outlive_expansion_phase)] //~ WARNING compiler plugins are deprecated
+
+pub fn main() {}
diff --git a/tests/ui-fulldeps/outlive-expansion-phase.stderr b/tests/ui-fulldeps/outlive-expansion-phase.stderr
new file mode 100644
index 000000000..e40a08ae7
--- /dev/null
+++ b/tests/ui-fulldeps/outlive-expansion-phase.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/outlive-expansion-phase.rs:6:1
+ |
+LL | #![plugin(outlive_expansion_phase)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui-fulldeps/pathless-extern-unstable.rs b/tests/ui-fulldeps/pathless-extern-unstable.rs
new file mode 100644
index 000000000..524b0c2f7
--- /dev/null
+++ b/tests/ui-fulldeps/pathless-extern-unstable.rs
@@ -0,0 +1,10 @@
+// ignore-stage1
+// edition:2018
+// compile-flags:--extern rustc_middle
+
+// Test that `--extern rustc_middle` fails with `rustc_private`.
+
+pub use rustc_middle;
+//~^ ERROR use of unstable library feature 'rustc_private'
+
+fn main() {}
diff --git a/tests/ui-fulldeps/pathless-extern-unstable.stderr b/tests/ui-fulldeps/pathless-extern-unstable.stderr
new file mode 100644
index 000000000..dcc3cddd3
--- /dev/null
+++ b/tests/ui-fulldeps/pathless-extern-unstable.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+ --> $DIR/pathless-extern-unstable.rs:7:9
+ |
+LL | pub use rustc_middle;
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
+ = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui-fulldeps/plugin-args.rs b/tests/ui-fulldeps/plugin-args.rs
new file mode 100644
index 000000000..488f2b775
--- /dev/null
+++ b/tests/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/tests/ui-fulldeps/plugin-args.stderr b/tests/ui-fulldeps/plugin-args.stderr
new file mode 100644
index 000000000..177f33005
--- /dev/null
+++ b/tests/ui-fulldeps/plugin-args.stderr
@@ -0,0 +1,17 @@
+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; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0498`.
diff --git a/tests/ui-fulldeps/plugin-as-extern-crate.rs b/tests/ui-fulldeps/plugin-as-extern-crate.rs
new file mode 100644
index 000000000..4d26e08d8
--- /dev/null
+++ b/tests/ui-fulldeps/plugin-as-extern-crate.rs
@@ -0,0 +1,10 @@
+// check-pass
+// aux-build:empty-plugin.rs
+// ignore-cross-compile
+//
+// empty_plugin will not compile on a cross-compiled target because
+// librustc_ast is not compiled for it.
+
+extern crate empty_plugin; // OK, plugin crates are still crates
+
+fn main() {}
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
new file mode 100644
index 000000000..7a91dcf0d
--- /dev/null
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -0,0 +1,253 @@
+// run-pass
+// ignore-cross-compile
+
+// The general idea of this test is to enumerate all "interesting" expressions and check that
+// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test:
+//
+// 1. The test focuses on expression nesting, because interactions between different expression
+// types are harder to test manually than single expression types in isolation.
+//
+// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x +
+// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct
+// handling of an expression might depend on the expression's parent, but doesn't depend on its
+// siblings or any more distant ancestors.
+//
+// 3. The test only checks certain expression kinds. The assumption is that similar expression
+// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer
+// and parser. So if all combinations of exprs involving `if` work correctly, then combinations
+// using `while`, `if let`, and so on will likely work as well.
+
+#![feature(rustc_private)]
+
+extern crate rustc_ast;
+extern crate rustc_ast_pretty;
+extern crate rustc_data_structures;
+extern crate rustc_parse;
+extern crate rustc_session;
+extern crate rustc_span;
+extern crate thin_vec;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
+use rustc_ast::ptr::P;
+use rustc_ast::*;
+use rustc_ast_pretty::pprust;
+use rustc_parse::new_parser_from_source_str;
+use rustc_session::parse::ParseSess;
+use rustc_span::source_map::FilePathMapping;
+use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
+use rustc_span::symbol::Ident;
+use thin_vec::thin_vec;
+
+fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
+ let src_as_string = src.to_string();
+
+ let mut p =
+ new_parser_from_source_str(ps, FileName::Custom(src_as_string.clone()), src_as_string);
+ p.parse_expr().map_err(|e| e.cancel()).ok()
+}
+
+// Helper functions for building exprs
+fn expr(kind: ExprKind) -> P<Expr> {
+ P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None })
+}
+
+fn make_x() -> P<Expr> {
+ let seg = PathSegment::from_ident(Ident::from_str("x"));
+ let path = Path { segments: thin_vec![seg], span: DUMMY_SP, tokens: None };
+ expr(ExprKind::Path(None, path))
+}
+
+/// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting"
+/// combinations of expression nesting. For example, we explore combinations using `if`, but not
+/// `while` or `match`, since those should print and parse in much the same way as `if`.
+fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
+ if depth == 0 {
+ f(make_x());
+ return;
+ }
+
+ let mut g = |e| f(expr(e));
+
+ for kind in 0..=19 {
+ match kind {
+ 0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))),
+ 1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
+ 2 => {
+ let seg = PathSegment::from_ident(Ident::from_str("x"));
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::MethodCall(Box::new(MethodCall {
+ seg: seg.clone(), receiver: e, args: vec![make_x()], span: DUMMY_SP
+ }))
+ )});
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::MethodCall(Box::new(MethodCall {
+ seg: seg.clone(), receiver: make_x(), args: vec![e], span: DUMMY_SP
+ }))
+ )});
+ }
+ 3..=8 => {
+ let op = Spanned {
+ span: DUMMY_SP,
+ node: match kind {
+ 3 => BinOpKind::Add,
+ 4 => BinOpKind::Mul,
+ 5 => BinOpKind::Shl,
+ 6 => BinOpKind::And,
+ 7 => BinOpKind::Or,
+ 8 => BinOpKind::Lt,
+ _ => unreachable!(),
+ },
+ };
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
+ }
+ 9 => {
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
+ }
+ 10 => {
+ let block = P(Block {
+ stmts: Vec::new(),
+ id: DUMMY_NODE_ID,
+ rules: BlockCheckMode::Default,
+ span: DUMMY_SP,
+ tokens: None,
+ could_be_bare_literal: false,
+ });
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
+ }
+ 11 => {
+ let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::Closure(Box::new(Closure {
+ binder: ClosureBinder::NotPresent,
+ capture_clause: CaptureBy::Value,
+ constness: Const::No,
+ asyncness: Async::No,
+ movability: Movability::Movable,
+ fn_decl: decl.clone(),
+ body: e,
+ fn_decl_span: DUMMY_SP,
+ fn_arg_span: DUMMY_SP,
+ })))
+ });
+ }
+ 12 => {
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x(), DUMMY_SP)));
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e, DUMMY_SP)));
+ }
+ 13 => {
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f"))));
+ }
+ 14 => {
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::Range(Some(e), Some(make_x()), RangeLimits::HalfOpen))
+ });
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::Range(Some(make_x()), Some(e), RangeLimits::HalfOpen))
+ });
+ }
+ 15 => {
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, e))
+ });
+ }
+ 16 => {
+ g(ExprKind::Ret(None));
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e))));
+ }
+ 17 => {
+ let path = Path::from_ident(Ident::from_str("S"));
+ g(ExprKind::Struct(P(StructExpr {
+ qself: None,
+ path,
+ fields: vec![],
+ rest: StructRest::Base(make_x()),
+ })));
+ }
+ 18 => {
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
+ }
+ 19 => {
+ let pat =
+ P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Wild, span: DUMMY_SP, tokens: None });
+ iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e, DUMMY_SP)))
+ }
+ _ => panic!("bad counter value in iter_exprs"),
+ }
+ }
+}
+
+// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed.
+
+/// `MutVisitor` that removes all `ExprKind::Paren` nodes.
+struct RemoveParens;
+
+impl MutVisitor for RemoveParens {
+ fn visit_expr(&mut self, e: &mut P<Expr>) {
+ match e.kind.clone() {
+ ExprKind::Paren(inner) => *e = inner,
+ _ => {}
+ };
+ mut_visit::noop_visit_expr(e, self);
+ }
+}
+
+/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`.
+struct AddParens;
+
+impl MutVisitor for AddParens {
+ fn visit_expr(&mut self, e: &mut P<Expr>) {
+ mut_visit::noop_visit_expr(e, self);
+ visit_clobber(e, |e| {
+ P(Expr {
+ id: DUMMY_NODE_ID,
+ kind: ExprKind::Paren(e),
+ span: DUMMY_SP,
+ attrs: AttrVec::new(),
+ tokens: None,
+ })
+ });
+ }
+}
+
+fn main() {
+ rustc_span::create_default_session_globals_then(|| run());
+}
+
+fn run() {
+ let ps = ParseSess::new(FilePathMapping::empty());
+
+ iter_exprs(2, &mut |mut e| {
+ // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,
+ // modulo placement of `Paren` nodes.
+ let printed = pprust::expr_to_string(&e);
+ println!("printed: {}", printed);
+
+ // Ignore expressions with chained comparisons that fail to parse
+ if let Some(mut parsed) = parse_expr(&ps, &printed) {
+ // We want to know if `parsed` is structurally identical to `e`, ignoring trivial
+ // differences like placement of `Paren`s or the exact ranges of node spans.
+ // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s
+ // everywhere we can, then pretty-print. This should give an unambiguous representation
+ // of each `Expr`, and it bypasses nearly all of the parenthesization logic, so we
+ // aren't relying on the correctness of the very thing we're testing.
+ RemoveParens.visit_expr(&mut e);
+ AddParens.visit_expr(&mut e);
+ let text1 = pprust::expr_to_string(&e);
+ RemoveParens.visit_expr(&mut parsed);
+ AddParens.visit_expr(&mut parsed);
+ let text2 = pprust::expr_to_string(&parsed);
+ assert!(
+ text1 == text2,
+ "exprs are not equal:\n e = {:?}\n parsed = {:?}",
+ text1,
+ text2
+ );
+ }
+ });
+}
diff --git a/tests/ui-fulldeps/regions-mock-tcx.rs b/tests/ui-fulldeps/regions-mock-tcx.rs
new file mode 100644
index 000000000..63975ef62
--- /dev/null
+++ b/tests/ui-fulldeps/regions-mock-tcx.rs
@@ -0,0 +1,139 @@
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+// Test a sample usage pattern for regions. Makes use of the
+// following features:
+//
+// - Multiple lifetime parameters
+// - Arenas
+
+#![feature(rustc_private, libc)]
+
+extern crate rustc_arena;
+extern crate libc;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use TypeStructure::{TypeInt, TypeFunction};
+use AstKind::{ExprInt, ExprVar, ExprLambda};
+use rustc_arena::TypedArena;
+use std::collections::HashMap;
+use std::mem;
+
+type Type<'tcx> = &'tcx TypeStructure<'tcx>;
+
+#[derive(Copy, Clone, Debug)]
+enum TypeStructure<'tcx> {
+ TypeInt,
+ TypeFunction(Type<'tcx>, Type<'tcx>),
+}
+
+impl<'tcx> PartialEq for TypeStructure<'tcx> {
+ fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
+ match (*self, *other) {
+ (TypeInt, TypeInt) => true,
+ (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b,
+ _ => false
+ }
+ }
+}
+
+impl<'tcx> Eq for TypeStructure<'tcx> {}
+
+type TyArena<'tcx> = TypedArena<TypeStructure<'tcx>>;
+type AstArena<'ast> = TypedArena<AstStructure<'ast>>;
+
+struct TypeContext<'tcx, 'ast> {
+ ty_arena: &'tcx TyArena<'tcx>,
+ types: Vec<Type<'tcx>> ,
+ type_table: HashMap<NodeId, Type<'tcx>>,
+
+ ast_arena: &'ast AstArena<'ast>,
+ ast_counter: usize,
+}
+
+impl<'tcx,'ast> TypeContext<'tcx, 'ast> {
+ fn new(ty_arena: &'tcx TyArena<'tcx>, ast_arena: &'ast AstArena<'ast>)
+ -> TypeContext<'tcx, 'ast> {
+ TypeContext { ty_arena: ty_arena,
+ types: Vec::new(),
+ type_table: HashMap::new(),
+
+ ast_arena: ast_arena,
+ ast_counter: 0 }
+ }
+
+ fn add_type(&mut self, s: TypeStructure<'tcx>) -> Type<'tcx> {
+ for &ty in &self.types {
+ if *ty == s {
+ return ty;
+ }
+ }
+
+ let ty = self.ty_arena.alloc(s);
+ self.types.push(ty);
+ ty
+ }
+
+ fn set_type(&mut self, id: NodeId, ty: Type<'tcx>) -> Type<'tcx> {
+ self.type_table.insert(id, ty);
+ ty
+ }
+
+ fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> {
+ let id = self.ast_counter;
+ self.ast_counter += 1;
+ self.ast_arena.alloc(AstStructure { id: NodeId {id:id}, kind: a })
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+struct NodeId {
+ id: usize
+}
+
+type Ast<'ast> = &'ast AstStructure<'ast>;
+
+#[derive(Copy, Clone)]
+struct AstStructure<'ast> {
+ id: NodeId,
+ kind: AstKind<'ast>
+}
+
+#[derive(Copy, Clone)]
+enum AstKind<'ast> {
+ ExprInt,
+ ExprVar(usize),
+ ExprLambda(Ast<'ast>),
+}
+
+fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>,
+ ast: Ast<'ast>) -> Type<'tcx>
+{
+ match ast.kind {
+ ExprInt | ExprVar(_) => {
+ let ty = tcx.add_type(TypeInt);
+ tcx.set_type(ast.id, ty)
+ }
+ ExprLambda(ast) => {
+ let arg_ty = tcx.add_type(TypeInt);
+ let body_ty = compute_types(tcx, ast);
+ let lambda_ty = tcx.add_type(TypeFunction(arg_ty, body_ty));
+ tcx.set_type(ast.id, lambda_ty)
+ }
+ }
+}
+
+pub fn main() {
+ let ty_arena = TypedArena::default();
+ let ast_arena = TypedArena::default();
+ let mut tcx = TypeContext::new(&ty_arena, &ast_arena);
+ let ast = tcx.ast(ExprInt);
+ let ty = compute_types(&mut tcx, ast);
+ assert_eq!(*ty, TypeInt);
+}
diff --git a/tests/ui-fulldeps/rename-directory.rs b/tests/ui-fulldeps/rename-directory.rs
new file mode 100644
index 000000000..8fc340cb9
--- /dev/null
+++ b/tests/ui-fulldeps/rename-directory.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+#![allow(unused_must_use)]
+#![allow(unused_imports)]
+// This test can't be a unit test in std,
+// because it needs TempDir, which is in extra
+
+// ignore-cross-compile
+
+use std::env;
+use std::ffi::CString;
+use std::fs::{self, File};
+use std::path::PathBuf;
+
+fn rename_directory() {
+ let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let old_path = tmpdir.join("foo/bar/baz");
+ fs::create_dir_all(&old_path).unwrap();
+ let test_file = &old_path.join("temp.txt");
+
+ File::create(test_file).unwrap();
+
+ let new_path = tmpdir.join("quux/blat");
+ fs::create_dir_all(&new_path).unwrap();
+ fs::rename(&old_path, &new_path.join("newdir"));
+ assert!(new_path.join("newdir").is_dir());
+ assert!(new_path.join("newdir/temp.txt").exists());
+}
+
+pub fn main() { rename_directory() }
diff --git a/tests/ui-fulldeps/rustc_encodable_hygiene.rs b/tests/ui-fulldeps/rustc_encodable_hygiene.rs
new file mode 100644
index 000000000..509a6b1d2
--- /dev/null
+++ b/tests/ui-fulldeps/rustc_encodable_hygiene.rs
@@ -0,0 +1,31 @@
+// run-pass
+
+#![feature(rustc_private)]
+
+extern crate rustc_macros;
+#[allow(dead_code)]
+extern crate rustc_serialize;
+
+// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
+// files.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
+
+use rustc_macros::{Decodable, Encodable};
+
+#[derive(Decodable, Encodable, Debug)]
+struct A {
+ a: String,
+}
+
+trait Trait {
+ fn encode(&self);
+}
+
+impl<T> Trait for T {
+ fn encode(&self) {
+ unimplemented!()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
new file mode 100644
index 000000000..65d9601e7
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -0,0 +1,801 @@
+// check-fail
+// Tests error conditions for specifying diagnostics using #[derive(Diagnostic)]
+
+// normalize-stderr-test "the following other types implement trait `IntoDiagnosticArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr"
+// normalize-stderr-test "diagnostic_builder\.rs:[0-9]+:[0-9]+" -> "diagnostic_builder.rs:LL:CC"
+// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
+// changing the output of this test. Since Diagnostic is strictly internal to the compiler
+// the test is just ignored on stable and beta:
+// ignore-beta
+// ignore-stable
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_span;
+use rustc_span::symbol::Ident;
+use rustc_span::Span;
+
+extern crate rustc_macros;
+use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
+
+extern crate rustc_middle;
+use rustc_middle::ty::Ty;
+
+extern crate rustc_errors;
+use rustc_errors::{Applicability, MultiSpan};
+
+extern crate rustc_session;
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct Hello {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct HelloWarn {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+//~^ ERROR unsupported type attribute for diagnostic derive enum
+enum DiagnosticOnEnum {
+ Foo,
+ //~^ ERROR diagnostic slug not specified
+ Bar,
+ //~^ ERROR diagnostic slug not specified
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[diag = "E0123"]
+//~^ ERROR `#[diag = ...]` is not a valid attribute
+struct WrongStructAttrStyle {}
+
+#[derive(Diagnostic)]
+#[nonsense(compiletest_example, code = "E0123")]
+//~^ ERROR `#[nonsense(...)]` is not a valid attribute
+//~^^ ERROR diagnostic slug not specified
+//~^^^ ERROR cannot find attribute `nonsense` in this scope
+struct InvalidStructAttr {}
+
+#[derive(Diagnostic)]
+#[diag("E0123")]
+//~^ ERROR `#[diag("...")]` is not a valid attribute
+//~^^ ERROR diagnostic slug not specified
+struct InvalidLitNestedAttr {}
+
+#[derive(Diagnostic)]
+#[diag(nonsense, code = "E0123")]
+//~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
+struct InvalidNestedStructAttr {}
+
+#[derive(Diagnostic)]
+#[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense(...))]` is not a valid attribute
+//~^^ ERROR diagnostic slug not specified
+struct InvalidNestedStructAttr1 {}
+
+#[derive(Diagnostic)]
+#[diag(nonsense = "...", code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
+//~| ERROR `#[diag(slug = ...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+struct InvalidNestedStructAttr2 {}
+
+#[derive(Diagnostic)]
+#[diag(nonsense = 4, code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
+//~| ERROR `#[diag(slug = ...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+struct InvalidNestedStructAttr3 {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(slug = ...)]` is not a valid attribute
+struct InvalidNestedStructAttr4 {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct WrongPlaceField {
+ #[suggestion = "bar"]
+ //~^ ERROR `#[suggestion = ...]` is not a valid attribute
+ sp: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[diag(compiletest_example, code = "E0456")]
+//~^ ERROR specified multiple times
+//~^^ ERROR specified multiple times
+struct DiagSpecifiedTwice {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0456", code = "E0457")]
+//~^ ERROR specified multiple times
+struct CodeSpecifiedTwice {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, compiletest_example, code = "E0456")]
+//~^ ERROR `#[diag(compiletest_example)]` is not a valid attribute
+struct SlugSpecifiedTwice {}
+
+#[derive(Diagnostic)]
+struct KindNotProvided {} //~ ERROR diagnostic slug not specified
+
+#[derive(Diagnostic)]
+#[diag(code = "E0456")]
+//~^ ERROR diagnostic slug not specified
+struct SlugNotProvided {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct CodeNotProvided {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct MessageWrongType {
+ #[primary_span]
+ //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ foo: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct InvalidPathFieldAttr {
+ #[nonsense]
+ //~^ ERROR `#[nonsense]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `nonsense` in this scope
+ foo: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithField {
+ name: String,
+ #[label(label)]
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithMessageAppliedToField {
+ #[label(label)]
+ //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ name: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithNonexistentField {
+ #[suggestion(suggestion, code = "{name}")]
+ //~^ ERROR `name` doesn't refer to a field on this type
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+//~^ ERROR invalid format string: expected `'}'`
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorMissingClosingBrace {
+ #[suggestion(suggestion, code = "{name")]
+ suggestion: (Span, Applicability),
+ name: String,
+ val: usize,
+}
+
+#[derive(Diagnostic)]
+//~^ ERROR invalid format string: unmatched `}`
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorMissingOpeningBrace {
+ #[suggestion(suggestion, code = "name}")]
+ suggestion: (Span, Applicability),
+ name: String,
+ val: usize,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct LabelOnSpan {
+ #[label(label)]
+ sp: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct LabelOnNonSpan {
+ #[label(label)]
+ //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ id: u32,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct Suggest {
+ #[suggestion(suggestion, code = "This is the suggested code")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "normal")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "short")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "hidden")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "verbose")]
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithoutCode {
+ #[suggestion(suggestion)]
+ //~^ ERROR suggestion without `code = "..."`
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithBadKey {
+ #[suggestion(nonsense = "bar")]
+ //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
+ //~| ERROR suggestion without `code = "..."`
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithShorthandMsg {
+ #[suggestion(msg = "bar")]
+ //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
+ //~| ERROR suggestion without `code = "..."`
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithoutMsg {
+ #[suggestion(code = "bar")]
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithTypesSwapped {
+ #[suggestion(suggestion, code = "This is suggested code")]
+ suggestion: (Applicability, Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithWrongTypeApplicabilityOnly {
+ #[suggestion(suggestion, code = "This is suggested code")]
+ //~^ ERROR wrong field type for suggestion
+ suggestion: Applicability,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithSpanOnly {
+ #[suggestion(suggestion, code = "This is suggested code")]
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithDuplicateSpanAndApplicability {
+ #[suggestion(suggestion, code = "This is suggested code")]
+ suggestion: (Span, Span, Applicability),
+ //~^ ERROR specified multiple times
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct SuggestWithDuplicateApplicabilityAndSpan {
+ #[suggestion(suggestion, code = "This is suggested code")]
+ suggestion: (Applicability, Applicability, Span),
+ //~^ ERROR specified multiple times
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct WrongKindOfAnnotation {
+ #[label = "bar"]
+ //~^ ERROR `#[label = ...]` is not a valid attribute
+ z: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct OptionsInErrors {
+ #[label(label)]
+ label: Option<Span>,
+ #[suggestion(suggestion, code = "...")]
+ opt_sugg: Option<(Span, Applicability)>,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0456")]
+struct MoveOutOfBorrowError<'tcx> {
+ name: Ident,
+ ty: Ty<'tcx>,
+ #[primary_span]
+ #[label(label)]
+ span: Span,
+ #[label(label)]
+ other_span: Span,
+ #[suggestion(suggestion, code = "{name}.clone()")]
+ opt_sugg: Option<(Span, Applicability)>,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithLifetime<'a> {
+ #[label(label)]
+ span: Span,
+ name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithDefaultLabelAttr<'a> {
+ #[label]
+ span: Span,
+ name: &'a str,
+}
+
+#[derive(Diagnostic)]
+//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
+#[diag(compiletest_example, code = "E0123")]
+struct ArgFieldWithoutSkip {
+ #[primary_span]
+ span: Span,
+ other: Hello,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ArgFieldWithSkip {
+ #[primary_span]
+ span: Span,
+ // `Hello` does not implement `IntoDiagnosticArg` so this would result in an error if
+ // not for `#[skip_arg]`.
+ #[skip_arg]
+ other: Hello,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithSpannedNote {
+ #[note]
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithSpannedNoteCustom {
+ #[note(note)]
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[note]
+struct ErrorWithNote {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[note(note)]
+struct ErrorWithNoteCustom {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithSpannedHelp {
+ #[help]
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithSpannedHelpCustom {
+ #[help(help)]
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[help]
+struct ErrorWithHelp {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[help(help)]
+struct ErrorWithHelpCustom {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[help]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithHelpWrongOrder {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[help(help)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithHelpCustomWrongOrder {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[note]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithNoteWrongOrder {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[note(note)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithNoteCustomWrongOrder {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ApplicabilityInBoth {
+ #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
+ //~^ ERROR specified multiple times
+ suggestion: (Span, Applicability),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct InvalidApplicability {
+ #[suggestion(suggestion, code = "...", applicability = "batman")]
+ //~^ ERROR invalid applicability
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ValidApplicability {
+ #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct NoApplicability {
+ #[suggestion(suggestion, code = "...")]
+ suggestion: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[note(parse_add_paren)]
+struct Note;
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct Subdiagnostic {
+ #[subdiagnostic]
+ note: Note,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct VecField {
+ #[primary_span]
+ #[label]
+ spans: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct UnitField {
+ #[primary_span]
+ spans: Span,
+ #[help]
+ foo: (),
+ #[help(help)]
+ bar: (),
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct OptUnitField {
+ #[primary_span]
+ spans: Span,
+ #[help]
+ foo: Option<()>,
+ #[help(help)]
+ bar: Option<()>,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct LabelWithTrailingPath {
+ #[label(label, foo)]
+ //~^ ERROR `#[label(foo)]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct LabelWithTrailingNameValue {
+ #[label(label, foo = "...")]
+ //~^ ERROR `#[label(foo = ...)]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct LabelWithTrailingList {
+ #[label(label, foo("..."))]
+ //~^ ERROR `#[label(foo(...))]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(compiletest_example)]
+struct LintsGood {}
+
+#[derive(LintDiagnostic)]
+#[diag(compiletest_example)]
+struct PrimarySpanOnLint {
+ #[primary_span]
+ //~^ ERROR `#[primary_span]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct ErrorWithMultiSpan {
+ #[primary_span]
+ span: MultiSpan,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[warning]
+struct ErrorWithWarn {
+ val: String,
+}
+
+#[derive(Diagnostic)]
+#[error(compiletest_example, code = "E0123")]
+//~^ ERROR `#[error(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `error` in this scope
+struct ErrorAttribute {}
+
+#[derive(Diagnostic)]
+#[warn_(compiletest_example, code = "E0123")]
+//~^ ERROR `#[warn_(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `warn_` in this scope
+struct WarnAttribute {}
+
+#[derive(Diagnostic)]
+#[lint(compiletest_example, code = "E0123")]
+//~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `lint` in this scope
+struct LintAttributeOnSessionDiag {}
+
+#[derive(LintDiagnostic)]
+#[lint(compiletest_example, code = "E0123")]
+//~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `lint` in this scope
+struct LintAttributeOnLintDiag {}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct DuplicatedSuggestionCode {
+ #[suggestion(suggestion, code = "...", code = ",,,")]
+ //~^ ERROR specified multiple times
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct InvalidTypeInSuggestionTuple {
+ #[suggestion(suggestion, code = "...")]
+ suggestion: (Span, usize),
+ //~^ ERROR wrong types for suggestion
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct MissingApplicabilityInSuggestionTuple {
+ #[suggestion(suggestion, code = "...")]
+ suggestion: (Span,),
+ //~^ ERROR wrong types for suggestion
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct MissingCodeInSuggestion {
+ #[suggestion(suggestion)]
+ //~^ ERROR suggestion without `code = "..."`
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[multipart_suggestion(suggestion)]
+//~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
+//~| ERROR cannot find attribute `multipart_suggestion` in this scope
+#[multipart_suggestion()]
+//~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
+//~| ERROR cannot find attribute `multipart_suggestion` in this scope
+struct MultipartSuggestion {
+ #[multipart_suggestion(suggestion)]
+ //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
+ //~| ERROR cannot find attribute `multipart_suggestion` in this scope
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[suggestion(suggestion, code = "...")]
+//~^ ERROR `#[suggestion(...)]` is not a valid attribute
+struct SuggestionOnStruct {
+ #[primary_span]
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+#[label]
+//~^ ERROR `#[label]` is not a valid attribute
+struct LabelOnStruct {
+ #[primary_span]
+ suggestion: Span,
+}
+
+#[derive(Diagnostic)]
+enum ExampleEnum {
+ #[diag(compiletest_example)]
+ Foo {
+ #[primary_span]
+ sp: Span,
+ #[note]
+ note_sp: Span,
+ },
+ #[diag(compiletest_example)]
+ Bar {
+ #[primary_span]
+ sp: Span,
+ },
+ #[diag(compiletest_example)]
+ Baz,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct RawIdentDiagnosticArg {
+ pub r#type: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticBad {
+ #[subdiagnostic(bad)]
+ //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+ note: Note,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticBadStr {
+ #[subdiagnostic = "bad"]
+ //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute
+ note: Note,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticBadTwice {
+ #[subdiagnostic(bad, bad)]
+ //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+ note: Note,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticBadLitStr {
+ #[subdiagnostic("bad")]
+ //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+ note: Note,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticEagerLint {
+ #[subdiagnostic(eager)]
+ //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+ note: Note,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticEagerCorrect {
+ #[subdiagnostic(eager)]
+ note: Note,
+}
+
+// Check that formatting of `correct` in suggestion doesn't move the binding for that field, making
+// the `set_arg` call a compile error; and that isn't worked around by moving the `set_arg` call
+// after the `span_suggestion` call - which breaks eager translation.
+
+#[derive(Subdiagnostic)]
+#[suggestion(use_instead, applicability = "machine-applicable", code = "{correct}")]
+pub(crate) struct SubdiagnosticWithSuggestion {
+ #[primary_span]
+ span: Span,
+ invalid: String,
+ correct: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SubdiagnosticEagerSuggestion {
+ #[subdiagnostic(eager)]
+ sub: SubdiagnosticWithSuggestion,
+}
+
+/// with a doc comment on the type..
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+struct WithDocComment {
+ /// ..and the field
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionsGood {
+ #[suggestion(code("foo", "bar"))]
+ sub: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionsSingleItem {
+ #[suggestion(code("foo"))]
+ sub: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionsNoItem {
+ #[suggestion(code())]
+ //~^ ERROR expected at least one string literal for `code(...)`
+ sub: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionsInvalidItem {
+ #[suggestion(code(foo))]
+ //~^ ERROR `code(...)` must contain only string literals
+ sub: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionsInvalidLiteral {
+ #[suggestion(code = 3)]
+ //~^ ERROR `code = "..."`/`code(...)` must contain only string literals
+ sub: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionStyleGood {
+ #[suggestion(code = "", style = "hidden")]
+ sub: Span,
+}
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
new file mode 100644
index 000000000..13e806a43
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -0,0 +1,666 @@
+error: unsupported type attribute for diagnostic derive enum
+ --> $DIR/diagnostic-derive.rs:39:1
+ |
+LL | #[diag(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:42:5
+ |
+LL | Foo,
+ | ^^^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:44:5
+ |
+LL | Bar,
+ | ^^^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[diag = ...]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:50:1
+ |
+LL | #[diag = "E0123"]
+ | ^^^^^^^^^^^^^^^^^
+
+error: `#[nonsense(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:55:1
+ |
+LL | #[nonsense(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:55:1
+ |
+LL | / #[nonsense(compiletest_example, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct InvalidStructAttr {}
+ | |___________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[diag("...")]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:62:8
+ |
+LL | #[diag("E0123")]
+ | ^^^^^^^
+ |
+ = help: a diagnostic slug is required as the first argument
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:62:1
+ |
+LL | / #[diag("E0123")]
+LL | |
+LL | |
+LL | | struct InvalidLitNestedAttr {}
+ | |______________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[diag(nonsense(...))]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:73:8
+ |
+LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: a diagnostic slug is required as the first argument
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:73:1
+ |
+LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | |
+LL | |
+LL | | struct InvalidNestedStructAttr1 {}
+ | |__________________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[diag(nonsense = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:79:8
+ |
+LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: only `code` is a valid nested attributes following the slug
+
+error: `#[diag(slug = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:79:42
+ |
+LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
+ |
+ = help: only `code` is a valid nested attributes following the slug
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:79:1
+ |
+LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+LL | |
+LL | |
+LL | |
+LL | | struct InvalidNestedStructAttr2 {}
+ | |__________________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[diag(nonsense = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:86:8
+ |
+LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
+
+error: `#[diag(slug = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:86:38
+ |
+LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
+ |
+ = help: only `code` is a valid nested attributes following the slug
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:86:1
+ |
+LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+LL | |
+LL | |
+LL | |
+LL | | struct InvalidNestedStructAttr3 {}
+ | |__________________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[diag(slug = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:93:45
+ |
+LL | #[diag(compiletest_example, code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
+ |
+ = help: only `code` is a valid nested attributes following the slug
+
+error: `#[suggestion = ...]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:100:5
+ |
+LL | #[suggestion = "bar"]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:107:8
+ |
+LL | #[diag(compiletest_example, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:106:8
+ |
+LL | #[diag(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:107:36
+ |
+LL | #[diag(compiletest_example, code = "E0456")]
+ | ^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:106:36
+ |
+LL | #[diag(compiletest_example, code = "E0123")]
+ | ^^^^^^^
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:113:52
+ |
+LL | #[diag(compiletest_example, code = "E0456", code = "E0457")]
+ | ^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:113:36
+ |
+LL | #[diag(compiletest_example, code = "E0456", code = "E0457")]
+ | ^^^^^^^
+
+error: `#[diag(compiletest_example)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:118:29
+ |
+LL | #[diag(compiletest_example, compiletest_example, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: diagnostic slug must be the first argument
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:123:1
+ |
+LL | struct KindNotProvided {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:126:1
+ |
+LL | / #[diag(code = "E0456")]
+LL | |
+LL | | struct SlugNotProvided {}
+ | |_________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/diagnostic-derive.rs:137:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+
+error: `#[nonsense]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:145:5
+ |
+LL | #[nonsense]
+ | ^^^^^^^^^^^
+
+error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/diagnostic-derive.rs:162:5
+ |
+LL | #[label(label)]
+ | ^^^^^^^^^^^^^^^
+
+error: `name` doesn't refer to a field on this type
+ --> $DIR/diagnostic-derive.rs:170:37
+ |
+LL | #[suggestion(suggestion, code = "{name}")]
+ | ^^^^^^^^
+
+error: invalid format string: expected `'}'` but string was terminated
+ --> $DIR/diagnostic-derive.rs:175:10
+ |
+LL | #[derive(Diagnostic)]
+ | ^^^^^^^^^^ expected `'}'` in format string
+ |
+ = note: if you intended to print `{`, you can escape it using `{{`
+ = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: invalid format string: unmatched `}` found
+ --> $DIR/diagnostic-derive.rs:185:10
+ |
+LL | #[derive(Diagnostic)]
+ | ^^^^^^^^^^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+ = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/diagnostic-derive.rs:205:5
+ |
+LL | #[label(label)]
+ | ^^^^^^^^^^^^^^^
+
+error: suggestion without `code = "..."`
+ --> $DIR/diagnostic-derive.rs:224:5
+ |
+LL | #[suggestion(suggestion)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion(nonsense = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:232:18
+ |
+LL | #[suggestion(nonsense = "bar")]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: only `style`, `code` and `applicability` are valid nested attributes
+
+error: suggestion without `code = "..."`
+ --> $DIR/diagnostic-derive.rs:232:5
+ |
+LL | #[suggestion(nonsense = "bar")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion(msg = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:241:18
+ |
+LL | #[suggestion(msg = "bar")]
+ | ^^^^^^^^^^^
+ |
+ = help: only `style`, `code` and `applicability` are valid nested attributes
+
+error: suggestion without `code = "..."`
+ --> $DIR/diagnostic-derive.rs:241:5
+ |
+LL | #[suggestion(msg = "bar")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: wrong field type for suggestion
+ --> $DIR/diagnostic-derive.rs:264:5
+ |
+LL | / #[suggestion(suggestion, code = "This is suggested code")]
+LL | |
+LL | | suggestion: Applicability,
+ | |_____________________________^
+ |
+ = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:280:24
+ |
+LL | suggestion: (Span, Span, Applicability),
+ | ^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:280:18
+ |
+LL | suggestion: (Span, Span, Applicability),
+ | ^^^^
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:288:33
+ |
+LL | suggestion: (Applicability, Applicability, Span),
+ | ^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:288:18
+ |
+LL | suggestion: (Applicability, Applicability, Span),
+ | ^^^^^^^^^^^^^
+
+error: `#[label = ...]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:295:5
+ |
+LL | #[label = "bar"]
+ | ^^^^^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:446:44
+ |
+LL | #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:448:24
+ |
+LL | suggestion: (Span, Applicability),
+ | ^^^^^^^^^^^^^
+
+error: invalid applicability
+ --> $DIR/diagnostic-derive.rs:454:44
+ |
+LL | #[suggestion(suggestion, code = "...", applicability = "batman")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[label(foo)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:517:20
+ |
+LL | #[label(label, foo)]
+ | ^^^
+ |
+ = help: a diagnostic slug must be the first argument to the attribute
+
+error: `#[label(foo = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:525:20
+ |
+LL | #[label(label, foo = "...")]
+ | ^^^^^^^^^^^
+
+error: `#[label(foo(...))]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:533:20
+ |
+LL | #[label(label, foo("..."))]
+ | ^^^^^^^^^^
+
+error: `#[primary_span]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:545:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: the `primary_span` field attribute is not valid for lint diagnostics
+
+error: `#[error(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:565:1
+ |
+LL | #[error(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:565:1
+ |
+LL | / #[error(compiletest_example, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct ErrorAttribute {}
+ | |________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[warn_(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:572:1
+ |
+LL | #[warn_(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:572:1
+ |
+LL | / #[warn_(compiletest_example, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct WarnAttribute {}
+ | |_______________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[lint(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:579:1
+ |
+LL | #[lint(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:579:1
+ |
+LL | / #[lint(compiletest_example, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct LintAttributeOnSessionDiag {}
+ | |____________________________________^
+ |
+ = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
+
+error: `#[lint(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:586:1
+ |
+LL | #[lint(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[lint(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:586:1
+ |
+LL | #[lint(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:586:1
+ |
+LL | / #[lint(compiletest_example, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | |
+LL | | struct LintAttributeOnLintDiag {}
+ | |_________________________________^
+ |
+ = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]`
+
+error: specified multiple times
+ --> $DIR/diagnostic-derive.rs:596:44
+ |
+LL | #[suggestion(suggestion, code = "...", code = ",,,")]
+ | ^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/diagnostic-derive.rs:596:30
+ |
+LL | #[suggestion(suggestion, code = "...", code = ",,,")]
+ | ^^^^^^^^^^^^
+
+error: wrong types for suggestion
+ --> $DIR/diagnostic-derive.rs:605:24
+ |
+LL | suggestion: (Span, usize),
+ | ^^^^^
+ |
+ = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
+
+error: wrong types for suggestion
+ --> $DIR/diagnostic-derive.rs:613:17
+ |
+LL | suggestion: (Span,),
+ | ^^^^^^^
+ |
+ = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
+
+error: suggestion without `code = "..."`
+ --> $DIR/diagnostic-derive.rs:620:5
+ |
+LL | #[suggestion(suggestion)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[multipart_suggestion(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:627:1
+ |
+LL | #[multipart_suggestion(suggestion)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider creating a `Subdiagnostic` instead
+
+error: `#[multipart_suggestion(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:630:1
+ |
+LL | #[multipart_suggestion()]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider creating a `Subdiagnostic` instead
+
+error: `#[multipart_suggestion(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:634:5
+ |
+LL | #[multipart_suggestion(suggestion)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider creating a `Subdiagnostic` instead
+
+error: `#[suggestion(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:642:1
+ |
+LL | #[suggestion(suggestion, code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `#[label]` and `#[suggestion]` can only be applied to fields
+
+error: `#[label]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:651:1
+ |
+LL | #[label]
+ | ^^^^^^^^
+ |
+ = help: `#[label]` and `#[suggestion]` can only be applied to fields
+
+error: `#[subdiagnostic(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:685:5
+ |
+LL | #[subdiagnostic(bad)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `eager` is the only supported nested attribute for `subdiagnostic`
+
+error: `#[subdiagnostic = ...]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:693:5
+ |
+LL | #[subdiagnostic = "bad"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[subdiagnostic(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:701:5
+ |
+LL | #[subdiagnostic(bad, bad)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `eager` is the only supported nested attribute for `subdiagnostic`
+
+error: `#[subdiagnostic(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:709:5
+ |
+LL | #[subdiagnostic("bad")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `eager` is the only supported nested attribute for `subdiagnostic`
+
+error: `#[subdiagnostic(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:717:5
+ |
+LL | #[subdiagnostic(eager)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: eager subdiagnostics are not supported on lints
+
+error: expected at least one string literal for `code(...)`
+ --> $DIR/diagnostic-derive.rs:775:18
+ |
+LL | #[suggestion(code())]
+ | ^^^^^^
+
+error: `code(...)` must contain only string literals
+ --> $DIR/diagnostic-derive.rs:783:23
+ |
+LL | #[suggestion(code(foo))]
+ | ^^^
+
+error: `code = "..."`/`code(...)` must contain only string literals
+ --> $DIR/diagnostic-derive.rs:791:18
+ |
+LL | #[suggestion(code = 3)]
+ | ^^^^^^^^
+
+error: cannot find attribute `nonsense` in this scope
+ --> $DIR/diagnostic-derive.rs:55:3
+ |
+LL | #[nonsense(compiletest_example, code = "E0123")]
+ | ^^^^^^^^
+
+error: cannot find attribute `nonsense` in this scope
+ --> $DIR/diagnostic-derive.rs:145:7
+ |
+LL | #[nonsense]
+ | ^^^^^^^^
+
+error: cannot find attribute `error` in this scope
+ --> $DIR/diagnostic-derive.rs:565:3
+ |
+LL | #[error(compiletest_example, code = "E0123")]
+ | ^^^^^
+
+error: cannot find attribute `warn_` in this scope
+ --> $DIR/diagnostic-derive.rs:572:3
+ |
+LL | #[warn_(compiletest_example, code = "E0123")]
+ | ^^^^^ help: a built-in attribute with a similar name exists: `warn`
+
+error: cannot find attribute `lint` in this scope
+ --> $DIR/diagnostic-derive.rs:579:3
+ |
+LL | #[lint(compiletest_example, code = "E0123")]
+ | ^^^^ help: a built-in attribute with a similar name exists: `link`
+
+error: cannot find attribute `lint` in this scope
+ --> $DIR/diagnostic-derive.rs:586:3
+ |
+LL | #[lint(compiletest_example, code = "E0123")]
+ | ^^^^ help: a built-in attribute with a similar name exists: `link`
+
+error: cannot find attribute `multipart_suggestion` in this scope
+ --> $DIR/diagnostic-derive.rs:627:3
+ |
+LL | #[multipart_suggestion(suggestion)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `multipart_suggestion` in this scope
+ --> $DIR/diagnostic-derive.rs:630:3
+ |
+LL | #[multipart_suggestion()]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `multipart_suggestion` in this scope
+ --> $DIR/diagnostic-derive.rs:634:7
+ |
+LL | #[multipart_suggestion(suggestion)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
+ --> $DIR/diagnostic-derive.rs:68:8
+ |
+LL | #[diag(nonsense, code = "E0123")]
+ | ^^^^^^^^ not found in `rustc_errors::fluent`
+
+error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
+ --> $DIR/diagnostic-derive.rs:339:10
+ |
+LL | #[derive(Diagnostic)]
+ | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
+ |
+ = help: normalized in stderr
+note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
+ --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
+ = note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 83 previous errors
+
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
new file mode 100644
index 000000000..a0a8114e0
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
@@ -0,0 +1,24 @@
+// rustc-env:CARGO_CRATE_NAME=rustc_dummy
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_span;
+use rustc_span::symbol::Ident;
+use rustc_span::Span;
+
+extern crate rustc_macros;
+use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
+
+extern crate rustc_middle;
+use rustc_middle::ty::Ty;
+
+extern crate rustc_errors;
+use rustc_errors::{Applicability, MultiSpan};
+
+extern crate rustc_session;
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+//~^ ERROR diagnostic slug and crate name do not match
+struct Hello {}
diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
new file mode 100644
index 000000000..dcf4af5df
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
@@ -0,0 +1,11 @@
+error: diagnostic slug and crate name do not match
+ --> $DIR/enforce_slug_naming.rs:22:8
+ |
+LL | #[diag(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: slug is `compiletest_example` but the crate name is `rustc_dummy`
+ = help: expected a slug starting with `dummy_...`
+
+error: aborting due to previous error
+
diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
new file mode 100644
index 000000000..61ac456a6
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
@@ -0,0 +1,800 @@
+// check-fail
+// Tests error conditions for specifying subdiagnostics using #[derive(Subdiagnostic)]
+
+// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
+// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler
+// the test is just ignored on stable and beta:
+// ignore-beta
+// ignore-stable
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_errors;
+extern crate rustc_macros;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use rustc_errors::Applicability;
+use rustc_macros::Subdiagnostic;
+use rustc_span::Span;
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct A {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+enum B {
+ #[label(parse_add_paren)]
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+ #[label(parse_add_paren)]
+ B {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+//~^ ERROR label without `#[primary_span]` field
+struct C {
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label]
+//~^ ERROR diagnostic slug must be first argument
+struct D {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[foo]
+//~^ ERROR `#[foo]` is not a valid attribute
+//~^^ ERROR cannot find attribute `foo` in this scope
+struct E {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label = "..."]
+//~^ ERROR `#[label = ...]` is not a valid attribute
+struct F {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(bug = "...")]
+//~^ ERROR `#[label(bug = ...)]` is not a valid attribute
+//~| ERROR diagnostic slug must be first argument
+struct G {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label("...")]
+//~^ ERROR `#[label("...")]` is not a valid attribute
+//~| ERROR diagnostic slug must be first argument
+struct H {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(slug = 4)]
+//~^ ERROR `#[label(slug = ...)]` is not a valid attribute
+//~| ERROR diagnostic slug must be first argument
+struct J {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(slug("..."))]
+//~^ ERROR `#[label(slug(...))]` is not a valid attribute
+//~| ERROR diagnostic slug must be first argument
+struct K {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(slug)]
+//~^ ERROR cannot find value `slug` in module `rustc_errors::fluent`
+//~^^ NOTE not found in `rustc_errors::fluent`
+struct L {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label()]
+//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
+struct M {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren, code = "...")]
+//~^ ERROR `#[label(code = ...)]` is not a valid attribute
+struct N {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren, applicability = "machine-applicable")]
+//~^ ERROR `#[label(applicability = ...)]` is not a valid attribute
+struct O {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[foo]
+//~^ ERROR cannot find attribute `foo` in this scope
+//~^^ ERROR unsupported type attribute for subdiagnostic enum
+enum P {
+ #[label(parse_add_paren)]
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum Q {
+ #[bar]
+ //~^ ERROR `#[bar]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum R {
+ #[bar = "..."]
+ //~^ ERROR `#[bar = ...]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum S {
+ #[bar = 4]
+ //~^ ERROR `#[bar = ...]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum T {
+ #[bar("...")]
+ //~^ ERROR `#[bar(...)]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum U {
+ #[label(code = "...")]
+ //~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
+ //~| ERROR `#[label(code = ...)]` is not a valid attribute
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum V {
+ #[label(parse_add_paren)]
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+ B {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+//~^ ERROR label without `#[primary_span]` field
+struct W {
+ #[primary_span]
+ //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ span: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct X {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ //~^ ERROR `#[applicability]` is only valid on suggestions
+ applicability: Applicability,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct Y {
+ #[primary_span]
+ span: Span,
+ #[bar]
+ //~^ ERROR `#[bar]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ bar: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct Z {
+ #[primary_span]
+ span: Span,
+ #[bar = "..."]
+ //~^ ERROR `#[bar = ...]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ bar: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct AA {
+ #[primary_span]
+ span: Span,
+ #[bar("...")]
+ //~^ ERROR `#[bar(...)]` is not a valid attribute
+ //~^^ ERROR cannot find attribute `bar` in this scope
+ bar: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct AB {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ z: Z,
+}
+
+#[derive(Subdiagnostic)]
+union AC {
+ //~^ ERROR unexpected unsupported untagged union
+ span: u32,
+ b: u64,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+#[label(parse_add_paren)]
+struct AD {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren, parse_add_paren)]
+//~^ ERROR `#[label(parse_add_paren)]` is not a valid attribute
+struct AE {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct AF {
+ #[primary_span]
+ //~^ NOTE previously specified here
+ span_a: Span,
+ #[primary_span]
+ //~^ ERROR specified multiple times
+ span_b: Span,
+}
+
+#[derive(Subdiagnostic)]
+struct AG {
+ //~^ ERROR subdiagnostic kind not specified
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...")]
+struct AH {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ applicability: Applicability,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+enum AI {
+ #[suggestion(parse_add_paren, code = "...")]
+ A {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ applicability: Applicability,
+ var: String,
+ },
+ #[suggestion(parse_add_paren, code = "...")]
+ B {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ applicability: Applicability,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...", code = "...")]
+//~^ ERROR specified multiple times
+//~^^ NOTE previously specified here
+struct AJ {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ applicability: Applicability,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...")]
+struct AK {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ //~^ NOTE previously specified here
+ applicability_a: Applicability,
+ #[applicability]
+ //~^ ERROR specified multiple times
+ applicability_b: Applicability,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...")]
+struct AL {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ //~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability`
+ applicability: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...")]
+struct AM {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren)]
+//~^ ERROR suggestion without `code = "..."`
+struct AN {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ applicability: Applicability,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...", applicability = "foo")]
+//~^ ERROR invalid applicability
+struct AO {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[help(parse_add_paren)]
+struct AP {
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[note(parse_add_paren)]
+struct AQ;
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...")]
+//~^ ERROR suggestion without `#[primary_span]` field
+struct AR {
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+struct AS {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label]
+//~^ ERROR unsupported type attribute for subdiagnostic enum
+enum AT {
+ #[label(parse_add_paren)]
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+struct AU {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+//~^ ERROR `var` doesn't refer to a field on this type
+struct AV {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+enum AW {
+ #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+ A {
+ #[primary_span]
+ span: Span,
+ var: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+enum AX {
+ #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+ //~^ ERROR `var` doesn't refer to a field on this type
+ A {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[warning(parse_add_paren)]
+struct AY {}
+
+#[derive(Subdiagnostic)]
+#[warning(parse_add_paren)]
+struct AZ {
+ #[primary_span]
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "...")]
+//~^ ERROR suggestion without `#[primary_span]` field
+struct BA {
+ #[suggestion_part]
+ //~^ ERROR `#[suggestion_part]` is not a valid attribute
+ span: Span,
+ #[suggestion_part(code = "...")]
+ //~^ ERROR `#[suggestion_part(...)]` is not a valid attribute
+ span2: Span,
+ #[applicability]
+ applicability: Applicability,
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
+//~| ERROR `#[multipart_suggestion(code = ...)]` is not a valid attribute
+struct BBa {
+ var: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+struct BBb {
+ #[suggestion_part]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span1: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+struct BBc {
+ #[suggestion_part()]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span1: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
+struct BC {
+ #[primary_span]
+ //~^ ERROR `#[primary_span]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BD {
+ #[suggestion_part]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span1: Span,
+ #[suggestion_part()]
+ //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
+ span2: Span,
+ #[suggestion_part(foo = "bar")]
+ //~^ ERROR `#[suggestion_part(foo = ...)]` is not a valid attribute
+ span4: Span,
+ #[suggestion_part(code = "...")]
+ //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ s1: String,
+ #[suggestion_part()]
+ //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ s2: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+struct BE {
+ #[suggestion_part(code = "...", code = ",,,")]
+ //~^ ERROR specified multiple times
+ //~| NOTE previously specified here
+ span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+struct BF {
+ #[suggestion_part(code = "(")]
+ first: Span,
+ #[suggestion_part(code = ")")]
+ second: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BG {
+ #[applicability]
+ appl: Applicability,
+ #[suggestion_part(code = "(")]
+ first: Span,
+ #[suggestion_part(code = ")")]
+ second: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+struct BH {
+ #[applicability]
+ //~^ ERROR `#[applicability]` has no effect
+ appl: Applicability,
+ #[suggestion_part(code = "(")]
+ first: Span,
+ #[suggestion_part(code = ")")]
+ second: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+struct BI {
+ #[suggestion_part(code = "")]
+ spans: Vec<Span>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct BJ {
+ #[primary_span]
+ span: Span,
+ r#type: String,
+}
+
+/// with a doc comment on the type..
+#[derive(Subdiagnostic)]
+#[label(parse_add_paren)]
+struct BK {
+ /// ..and the field
+ #[primary_span]
+ span: Span,
+}
+
+/// with a doc comment on the type..
+#[derive(Subdiagnostic)]
+enum BL {
+ /// ..and the variant..
+ #[label(parse_add_paren)]
+ Foo {
+ /// ..and the field
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BM {
+ #[suggestion_part(code("foo"))]
+ //~^ ERROR expected exactly one string literal for `code = ...`
+ span: Span,
+ r#type: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BN {
+ #[suggestion_part(code("foo", "bar"))]
+ //~^ ERROR expected exactly one string literal for `code = ...`
+ span: Span,
+ r#type: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BO {
+ #[suggestion_part(code(3))]
+ //~^ ERROR expected exactly one string literal for `code = ...`
+ span: Span,
+ r#type: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BP {
+ #[suggestion_part(code())]
+ //~^ ERROR expected exactly one string literal for `code = ...`
+ span: Span,
+ r#type: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_add_paren)]
+struct BQ {
+ #[suggestion_part(code = 3)]
+ //~^ ERROR `code = "..."`/`code(...)` must contain only string literals
+ span: Span,
+ r#type: String,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "")]
+struct SuggestionStyleDefault {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "short")]
+struct SuggestionStyleShort {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "hidden")]
+struct SuggestionStyleHidden {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "verbose")]
+struct SuggestionStyleVerbose {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "tool-only")]
+struct SuggestionStyleToolOnly {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+//~^ ERROR specified multiple times
+//~| NOTE previously specified here
+struct SuggestionStyleTwice {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion_hidden(parse_add_paren, code = "")]
+//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
+struct SuggestionStyleOldSyntax {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion_hidden(parse_add_paren, code = "", style = "normal")]
+//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
+struct SuggestionStyleOldAndNewSyntax {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "foo")]
+//~^ ERROR invalid suggestion style
+struct SuggestionStyleInvalid1 {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = 42)]
+//~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute
+struct SuggestionStyleInvalid2 {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style)]
+//~^ ERROR `#[suggestion(style)]` is not a valid attribute
+struct SuggestionStyleInvalid3 {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style("foo"))]
+//~^ ERROR `#[suggestion(style(...))]` is not a valid attribute
+struct SuggestionStyleInvalid4 {
+ #[primary_span]
+ sub: Span,
+}
diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
new file mode 100644
index 000000000..b594fa6cd
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
@@ -0,0 +1,566 @@
+error: label without `#[primary_span]` field
+ --> $DIR/subdiagnostic-derive.rs:47:1
+ |
+LL | / #[label(parse_add_paren)]
+LL | |
+LL | | struct C {
+LL | | var: String,
+LL | | }
+ | |_^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:54:1
+ |
+LL | #[label]
+ | ^^^^^^^^
+
+error: `#[foo]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:63:1
+ |
+LL | #[foo]
+ | ^^^^^^
+
+error: `#[label = ...]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:73:1
+ |
+LL | #[label = "..."]
+ | ^^^^^^^^^^^^^^^^
+
+error: `#[label(bug = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:82:9
+ |
+LL | #[label(bug = "...")]
+ | ^^^^^^^^^^^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:82:1
+ |
+LL | #[label(bug = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[label("...")]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:92:9
+ |
+LL | #[label("...")]
+ | ^^^^^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:92:1
+ |
+LL | #[label("...")]
+ | ^^^^^^^^^^^^^^^
+
+error: `#[label(slug = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:102:9
+ |
+LL | #[label(slug = 4)]
+ | ^^^^^^^^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:102:1
+ |
+LL | #[label(slug = 4)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: `#[label(slug(...))]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:112:9
+ |
+LL | #[label(slug("..."))]
+ | ^^^^^^^^^^^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:112:1
+ |
+LL | #[label(slug("..."))]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:132:1
+ |
+LL | #[label()]
+ | ^^^^^^^^^^
+
+error: `#[label(code = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:141:26
+ |
+LL | #[label(parse_add_paren, code = "...")]
+ | ^^^^^^^^^^^^
+
+error: `#[label(applicability = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:150:26
+ |
+LL | #[label(parse_add_paren, applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unsupported type attribute for subdiagnostic enum
+ --> $DIR/subdiagnostic-derive.rs:159:1
+ |
+LL | #[foo]
+ | ^^^^^^
+
+error: `#[bar]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:173:5
+ |
+LL | #[bar]
+ | ^^^^^^
+
+error: `#[bar = ...]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:185:5
+ |
+LL | #[bar = "..."]
+ | ^^^^^^^^^^^^^^
+
+error: `#[bar = ...]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:197:5
+ |
+LL | #[bar = 4]
+ | ^^^^^^^^^^
+
+error: `#[bar(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:209:5
+ |
+LL | #[bar("...")]
+ | ^^^^^^^^^^^^^
+
+error: `#[label(code = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:221:13
+ |
+LL | #[label(code = "...")]
+ | ^^^^^^^^^^^^
+
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:221:5
+ |
+LL | #[label(code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/subdiagnostic-derive.rs:250:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+
+error: label without `#[primary_span]` field
+ --> $DIR/subdiagnostic-derive.rs:247:1
+ |
+LL | / #[label(parse_add_paren)]
+LL | |
+LL | | struct W {
+LL | | #[primary_span]
+LL | |
+LL | | span: String,
+LL | | }
+ | |_^
+
+error: `#[applicability]` is only valid on suggestions
+ --> $DIR/subdiagnostic-derive.rs:260:5
+ |
+LL | #[applicability]
+ | ^^^^^^^^^^^^^^^^
+
+error: `#[bar]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:270:5
+ |
+LL | #[bar]
+ | ^^^^^^
+ |
+ = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
+
+error: `#[bar = ...]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:281:5
+ |
+LL | #[bar = "..."]
+ | ^^^^^^^^^^^^^^
+
+error: `#[bar(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:292:5
+ |
+LL | #[bar("...")]
+ | ^^^^^^^^^^^^^
+ |
+ = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
+
+error: unexpected unsupported untagged union
+ --> $DIR/subdiagnostic-derive.rs:308:1
+ |
+LL | / union AC {
+LL | |
+LL | | span: u32,
+LL | | b: u64,
+LL | | }
+ | |_^
+
+error: `#[label(parse_add_paren)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:323:26
+ |
+LL | #[label(parse_add_paren, parse_add_paren)]
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: a diagnostic slug must be the first argument to the attribute
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:336:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:333:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+
+error: subdiagnostic kind not specified
+ --> $DIR/subdiagnostic-derive.rs:342:8
+ |
+LL | struct AG {
+ | ^^
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:379:45
+ |
+LL | #[suggestion(parse_add_paren, code = "...", code = "...")]
+ | ^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:379:31
+ |
+LL | #[suggestion(parse_add_paren, code = "...", code = "...")]
+ | ^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:397:5
+ |
+LL | #[applicability]
+ | ^^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:394:5
+ |
+LL | #[applicability]
+ | ^^^^^^^^^^^^^^^^
+
+error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
+ --> $DIR/subdiagnostic-derive.rs:407:5
+ |
+LL | #[applicability]
+ | ^^^^^^^^^^^^^^^^
+
+error: suggestion without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:420:1
+ |
+LL | #[suggestion(parse_add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: invalid applicability
+ --> $DIR/subdiagnostic-derive.rs:430:45
+ |
+LL | #[suggestion(parse_add_paren, code = "...", applicability = "foo")]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: suggestion without `#[primary_span]` field
+ --> $DIR/subdiagnostic-derive.rs:448:1
+ |
+LL | / #[suggestion(parse_add_paren, code = "...")]
+LL | |
+LL | | struct AR {
+LL | | var: String,
+LL | | }
+ | |_^
+
+error: unsupported type attribute for subdiagnostic enum
+ --> $DIR/subdiagnostic-derive.rs:462:1
+ |
+LL | #[label]
+ | ^^^^^^^^
+
+error: `var` doesn't refer to a field on this type
+ --> $DIR/subdiagnostic-derive.rs:482:38
+ |
+LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+ | ^^^^^^^
+
+error: `var` doesn't refer to a field on this type
+ --> $DIR/subdiagnostic-derive.rs:501:42
+ |
+LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+ | ^^^^^^^
+
+error: `#[suggestion_part]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:524:5
+ |
+LL | #[suggestion_part]
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
+
+error: `#[suggestion_part(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:527:5
+ |
+LL | #[suggestion_part(code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: `#[suggestion_part(...)]` is only valid in multipart suggestions
+
+error: suggestion without `#[primary_span]` field
+ --> $DIR/subdiagnostic-derive.rs:521:1
+ |
+LL | / #[suggestion(parse_add_paren, code = "...")]
+LL | |
+LL | | struct BA {
+LL | | #[suggestion_part]
+... |
+LL | | var: String,
+LL | | }
+ | |_^
+
+error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:536:41
+ |
+LL | #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^
+ |
+ = help: only `style` and `applicability` are valid nested attributes
+
+error: multipart suggestion without any `#[suggestion_part(...)]` fields
+ --> $DIR/subdiagnostic-derive.rs:536:1
+ |
+LL | / #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+LL | |
+LL | |
+LL | | struct BBa {
+LL | | var: String,
+LL | | }
+ | |_^
+
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:546:5
+ |
+LL | #[suggestion_part]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:554:5
+ |
+LL | #[suggestion_part()]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: `#[primary_span]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:563:5
+ |
+LL | #[primary_span]
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
+
+error: multipart suggestion without any `#[suggestion_part(...)]` fields
+ --> $DIR/subdiagnostic-derive.rs:560:1
+ |
+LL | / #[multipart_suggestion(parse_add_paren)]
+LL | |
+LL | | struct BC {
+LL | | #[primary_span]
+LL | |
+LL | | span: Span,
+LL | | }
+ | |_^
+
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:571:5
+ |
+LL | #[suggestion_part]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_part(...)]` attribute without `code = "..."`
+ --> $DIR/subdiagnostic-derive.rs:574:5
+ |
+LL | #[suggestion_part()]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_part(foo = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:577:23
+ |
+LL | #[suggestion_part(foo = "bar")]
+ | ^^^^^^^^^^^
+ |
+ = help: `code` is the only valid nested attribute
+
+error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/subdiagnostic-derive.rs:580:5
+ |
+LL | #[suggestion_part(code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
+ --> $DIR/subdiagnostic-derive.rs:583:5
+ |
+LL | #[suggestion_part()]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:591:37
+ |
+LL | #[suggestion_part(code = "...", code = ",,,")]
+ | ^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:591:23
+ |
+LL | #[suggestion_part(code = "...", code = ",,,")]
+ | ^^^^^^^^^^^^
+
+error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."`
+ --> $DIR/subdiagnostic-derive.rs:620:5
+ |
+LL | #[applicability]
+ | ^^^^^^^^^^^^^^^^
+
+error: expected exactly one string literal for `code = ...`
+ --> $DIR/subdiagnostic-derive.rs:668:23
+ |
+LL | #[suggestion_part(code("foo"))]
+ | ^^^^^^^^^^^
+
+error: expected exactly one string literal for `code = ...`
+ --> $DIR/subdiagnostic-derive.rs:677:23
+ |
+LL | #[suggestion_part(code("foo", "bar"))]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: expected exactly one string literal for `code = ...`
+ --> $DIR/subdiagnostic-derive.rs:686:23
+ |
+LL | #[suggestion_part(code(3))]
+ | ^^^^^^^
+
+error: expected exactly one string literal for `code = ...`
+ --> $DIR/subdiagnostic-derive.rs:695:23
+ |
+LL | #[suggestion_part(code())]
+ | ^^^^^^
+
+error: `code = "..."`/`code(...)` must contain only string literals
+ --> $DIR/subdiagnostic-derive.rs:704:23
+ |
+LL | #[suggestion_part(code = 3)]
+ | ^^^^^^^^
+
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:746:60
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+ | ^^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:746:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+ | ^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_hidden(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:755:1
+ |
+LL | #[suggestion_hidden(parse_add_paren, code = "")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: Use `#[suggestion(..., style = "hidden")]` instead
+
+error: `#[suggestion_hidden(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:763:1
+ |
+LL | #[suggestion_hidden(parse_add_paren, code = "", style = "normal")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: Use `#[suggestion(..., style = "hidden")]` instead
+
+error: invalid suggestion style
+ --> $DIR/subdiagnostic-derive.rs:771:50
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = "foo")]
+ | ^^^^^
+ |
+ = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only`
+
+error: `#[suggestion(style = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:779:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = 42)]
+ | ^^^^^^^^^^
+
+error: `#[suggestion(style)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:787:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style)]
+ | ^^^^^
+ |
+ = help: a diagnostic slug must be the first argument to the attribute
+
+error: `#[suggestion(style(...))]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:795:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style("foo"))]
+ | ^^^^^^^^^^^^
+
+error: cannot find attribute `foo` in this scope
+ --> $DIR/subdiagnostic-derive.rs:63:3
+ |
+LL | #[foo]
+ | ^^^
+
+error: cannot find attribute `foo` in this scope
+ --> $DIR/subdiagnostic-derive.rs:159:3
+ |
+LL | #[foo]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:173:7
+ |
+LL | #[bar]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:185:7
+ |
+LL | #[bar = "..."]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:197:7
+ |
+LL | #[bar = 4]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:209:7
+ |
+LL | #[bar("...")]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:270:7
+ |
+LL | #[bar]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:281:7
+ |
+LL | #[bar = "..."]
+ | ^^^
+
+error: cannot find attribute `bar` in this scope
+ --> $DIR/subdiagnostic-derive.rs:292:7
+ |
+LL | #[bar("...")]
+ | ^^^
+
+error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
+ --> $DIR/subdiagnostic-derive.rs:122:9
+ |
+LL | #[label(slug)]
+ | ^^^^ not found in `rustc_errors::fluent`
+
+error: aborting due to 79 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui-fulldeps/stdio-from.rs b/tests/ui-fulldeps/stdio-from.rs
new file mode 100644
index 000000000..fef9f27fc
--- /dev/null
+++ b/tests/ui-fulldeps/stdio-from.rs
@@ -0,0 +1,69 @@
+// run-pass
+// ignore-cross-compile
+
+use std::env;
+use std::fs::File;
+use std::io;
+use std::io::{Read, Write};
+use std::process::{Command, Stdio};
+use std::path::PathBuf;
+
+fn main() {
+ if env::args().len() > 1 {
+ child().unwrap()
+ } else {
+ parent().unwrap()
+ }
+}
+
+fn parent() -> io::Result<()> {
+ let td = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let input = td.join("stdio-from-input");
+ let output = td.join("stdio-from-output");
+
+ File::create(&input)?.write_all(b"foo\n")?;
+
+ // Set up this chain:
+ // $ me <file | me | me >file
+ // ... to duplicate each line 8 times total.
+
+ let mut child1 = Command::new(env::current_exe()?)
+ .arg("first")
+ .stdin(File::open(&input)?) // tests File::into()
+ .stdout(Stdio::piped())
+ .spawn()?;
+
+ let mut child3 = Command::new(env::current_exe()?)
+ .arg("third")
+ .stdin(Stdio::piped())
+ .stdout(File::create(&output)?) // tests File::into()
+ .spawn()?;
+
+ // Started out of order so we can test both `ChildStdin` and `ChildStdout`.
+ let mut child2 = Command::new(env::current_exe()?)
+ .arg("second")
+ .stdin(child1.stdout.take().unwrap()) // tests ChildStdout::into()
+ .stdout(child3.stdin.take().unwrap()) // tests ChildStdin::into()
+ .spawn()?;
+
+ assert!(child1.wait()?.success());
+ assert!(child2.wait()?.success());
+ assert!(child3.wait()?.success());
+
+ let mut data = String::new();
+ File::open(&output)?.read_to_string(&mut data)?;
+ for line in data.lines() {
+ assert_eq!(line, "foo");
+ }
+ assert_eq!(data.lines().count(), 8);
+ Ok(())
+}
+
+fn child() -> io::Result<()> {
+ // double everything
+ let mut input = vec![];
+ io::stdin().read_to_end(&mut input)?;
+ io::stdout().write_all(&input)?;
+ io::stdout().write_all(&input)?;
+ Ok(())
+}
diff --git a/tests/ui-fulldeps/switch-stdout.rs b/tests/ui-fulldeps/switch-stdout.rs
new file mode 100644
index 000000000..e9501a809
--- /dev/null
+++ b/tests/ui-fulldeps/switch-stdout.rs
@@ -0,0 +1,51 @@
+// run-pass
+
+use std::env;
+use std::fs::File;
+use std::io::{Read, Write};
+use std::path::PathBuf;
+
+#[cfg(unix)]
+fn switch_stdout_to(file: File) {
+ use std::os::unix::prelude::*;
+
+ extern "C" {
+ fn dup2(old: i32, new: i32) -> i32;
+ }
+
+ unsafe {
+ assert_eq!(dup2(file.as_raw_fd(), 1), 1);
+ }
+}
+
+#[cfg(windows)]
+fn switch_stdout_to(file: File) {
+ use std::os::windows::prelude::*;
+
+ extern "system" {
+ fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32;
+ }
+
+ const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32;
+
+ unsafe {
+ let rc = SetStdHandle(STD_OUTPUT_HANDLE, file.into_raw_handle() as *mut _);
+ assert!(rc != 0);
+ }
+}
+
+fn main() {
+ let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let path = path.join("switch-stdout-output");
+ let f = File::create(&path).unwrap();
+
+ println!("foo");
+ std::io::stdout().flush().unwrap();
+ switch_stdout_to(f);
+ println!("bar");
+ std::io::stdout().flush().unwrap();
+
+ let mut contents = String::new();
+ File::open(&path).unwrap().read_to_string(&mut contents).unwrap();
+ assert_eq!(contents, "bar\n");
+}