diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 486ea93588cc6..9e15420171160 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -69,6 +69,7 @@ #![feature(catch_expr)] #![feature(test)] #![feature(in_band_lifetimes)] +#![feature(macro_at_most_once_rep)] #![recursion_limit="512"] diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 5c9f7f4768641..56b7da4c5da8c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -77,8 +77,9 @@ pub struct Lint { /// e.g. "imports that are never used" pub desc: &'static str, - /// Deny lint after this edition - pub edition_deny: Option, + /// Starting at the given edition, default to the given lint level. If this is `None`, then use + /// `default_level`. + pub edition_lint_opts: Option<(Edition, Level)>, } impl Lint { @@ -88,32 +89,32 @@ impl Lint { } pub fn default_level(&self, session: &Session) -> Level { - if let Some(edition_deny) = self.edition_deny { - if session.edition() >= edition_deny { - return Level::Deny - } - } - self.default_level + self.edition_lint_opts + .filter(|(e, _)| *e <= session.edition()) + .map(|(_, l)| l) + .unwrap_or(self.default_level) } } /// Declare a static item of type `&'static Lint`. #[macro_export] macro_rules! declare_lint { - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $edition: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - edition_deny: Some($edition) + edition_lint_opts: None, }; ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, + $lint_edition: expr => $edition_level: ident $(,)? + ) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - edition_deny: None, + edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)), }; ); } @@ -121,8 +122,7 @@ macro_rules! declare_lint { /// Declare a static `LintArray` and return it as an expression. #[macro_export] macro_rules! lint_array { - ($( $lint:expr ),*,) => { lint_array!( $( $lint ),* ) }; - ($( $lint:expr ),*) => {{ + ($( $lint:expr ),* $(,)?) => {{ static ARRAY: LintArray = &[ $( &$lint ),* ]; ARRAY }} diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5951fd478d89f..8a0850595c889 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -43,6 +43,7 @@ use std::collections::HashSet; use syntax::ast; use syntax::attr; +use syntax::edition::Edition; use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes}; use syntax_pos::{BytePos, Span, SyntaxContext}; use syntax::symbol::keywords; @@ -616,7 +617,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { declare_lint! { pub ANONYMOUS_PARAMETERS, Allow, - "detects anonymous parameters" + "detects anonymous parameters", + Edition::Edition2018 => Warn, } /// Checks for use of anonymous parameters (RFC 1685) @@ -637,9 +639,29 @@ impl EarlyLintPass for AnonymousParameters { match arg.pat.node { ast::PatKind::Ident(_, ident, None) => { if ident.name == keywords::Invalid.name() { - cx.span_lint(ANONYMOUS_PARAMETERS, - arg.pat.span, - "use of deprecated anonymous parameter"); + let ty_snip = cx + .sess + .codemap() + .span_to_snippet(arg.ty.span); + + let (ty_snip, appl) = if let Ok(snip) = ty_snip { + (snip, Applicability::MachineApplicable) + } else { + ("".to_owned(), Applicability::HasPlaceholders) + }; + + cx.struct_span_lint( + ANONYMOUS_PARAMETERS, + arg.pat.span, + "anonymous parameters are deprecated and will be \ + removed in the next edition." + ).span_suggestion_with_applicability( + arg.pat.span, + "Try naming the parameter or explicitly \ + ignoring it", + format!("_: {}", ty_snip), + appl + ).emit(); } } _ => (), diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 07bb7b5276441..c5994d0536ee0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -29,6 +29,7 @@ #![feature(macro_vis_matcher)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] +#![feature(macro_at_most_once_rep)] extern crate syntax; #[macro_use] diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs index d3f921e0878ae..7303af73cac9e 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs @@ -13,6 +13,7 @@ #![feature(plugin_registrar, rustc_private)] #![feature(box_syntax)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] #[macro_use] extern crate rustc; extern crate rustc_plugin; diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs index a0c72243d4821..3f3997726c939 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -13,6 +13,7 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] // Load rustc as a plugin to get macros #[macro_use] diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs index cbbfbd8060360..ab39709c529dc 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs @@ -13,6 +13,7 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] extern crate syntax; diff --git a/src/test/compile-fail/anon-params-deprecated.rs b/src/test/compile-fail/anon-params-deprecated.rs index 76edae17dc104..4d37ba920f3d6 100644 --- a/src/test/compile-fail/anon-params-deprecated.rs +++ b/src/test/compile-fail/anon-params-deprecated.rs @@ -12,13 +12,13 @@ // Test for the anonymous_parameters deprecation lint (RFC 1685) trait T { - fn foo(i32); //~ ERROR use of deprecated anonymous parameter + fn foo(i32); //~ ERROR anonymous parameters are deprecated //~| WARNING hard error fn bar_with_default_impl(String, String) {} - //~^ ERROR use of deprecated anonymous parameter + //~^ ERROR anonymous parameters are deprecated //~| WARNING hard error - //~| ERROR use of deprecated anonymous parameter + //~| ERROR anonymous parameters are deprecated //~| WARNING hard error } diff --git a/src/test/compile-fail/future-incompatible-lint-group.rs b/src/test/compile-fail/future-incompatible-lint-group.rs index e6a39f95e660d..5f320135edfd1 100644 --- a/src/test/compile-fail/future-incompatible-lint-group.rs +++ b/src/test/compile-fail/future-incompatible-lint-group.rs @@ -11,7 +11,7 @@ #![deny(future_incompatible)] trait Tr { - fn f(u8) {} //~ ERROR use of deprecated anonymous parameter + fn f(u8) {} //~ ERROR anonymous parameters are deprecated //~^ WARN this was previously accepted } diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs index 878d64c3473b1..e3246673fabaf 100644 --- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs @@ -13,6 +13,7 @@ #![feature(plugin_registrar, rustc_private)] #![feature(box_syntax)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] #[macro_use] extern crate rustc; extern crate rustc_plugin; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs index 0433b11f7c127..63b4a6a1c62df 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(box_syntax, plugin, plugin_registrar, rustc_private)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] #![crate_type = "dylib"] #[macro_use] diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs index a0c72243d4821..3f3997726c939 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -13,6 +13,7 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] // Load rustc as a plugin to get macros #[macro_use] diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs index cbbfbd8060360..ab39709c529dc 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs @@ -13,6 +13,7 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] #![feature(macro_vis_matcher)] +#![feature(macro_at_most_once_rep)] extern crate syntax; diff --git a/src/test/ui/lint-anon-param-edition.fixed b/src/test/ui/lint-anon-param-edition.fixed new file mode 100644 index 0000000000000..de223d9ccf7b6 --- /dev/null +++ b/src/test/ui/lint-anon-param-edition.fixed @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// tests that the anonymous_parameters lint is warn-by-default on the 2018 edition + +// compile-pass +// compile-flags: --edition=2018 +// run-rustfix + +trait Foo { + fn foo(_: u8); + //^ WARN anonymous parameters are deprecated + //| WARN this was previously accepted +} + +fn main() {} diff --git a/src/test/ui/lint-anon-param-edition.rs b/src/test/ui/lint-anon-param-edition.rs new file mode 100644 index 0000000000000..35406806df99c --- /dev/null +++ b/src/test/ui/lint-anon-param-edition.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// tests that the anonymous_parameters lint is warn-by-default on the 2018 edition + +// compile-pass +// compile-flags: --edition=2018 +// run-rustfix + +trait Foo { + fn foo(u8); + //^ WARN anonymous parameters are deprecated + //| WARN this was previously accepted +} + +fn main() {} diff --git a/src/test/ui/lint-anon-param-edition.stderr b/src/test/ui/lint-anon-param-edition.stderr new file mode 100644 index 0000000000000..de347770aec77 --- /dev/null +++ b/src/test/ui/lint-anon-param-edition.stderr @@ -0,0 +1,10 @@ +warning: anonymous parameters are deprecated and will be removed in the next edition. + --> $DIR/lint-anon-param-edition.rs:18:12 + | +LL | fn foo(u8); + | ^^ help: Try naming the parameter or explicitly ignoring it: `_: u8` + | + = note: #[warn(anonymous_parameters)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41686 +