diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
commit | 64d98f8ee037282c35007b64c2649055c56af1db (patch) | |
tree | 5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui-fulldeps | |
parent | Adding debian version 1.67.1+dfsg1-1. (diff) | |
download | rustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui-fulldeps')
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"); +} |