diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs index 2ed6cd5283b10..a2d875f669b19 100644 --- a/src/librustc/lint.rs +++ b/src/librustc/lint.rs @@ -19,10 +19,10 @@ pub enum LintSource { Default, /// Lint level was set by an attribute. - Node(Symbol, Span, Option /* RFC 2383 reason */), + Node(Symbol, Option, Span, Option /* RFC 2383 reason */), /// Lint level was set by a command-line flag. - CommandLine(Symbol), + CommandLine(Symbol, Option), } pub type LevelSource = (Level, LintSource); @@ -63,16 +63,26 @@ impl LintLevelSets { // lint. let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition())); + // Ensure we don't go below the minimum level of the lint. + // Note that we allow `--cap-lints` to cap `WARNINGS`, + // but we will never allow `--cap-lints` to cap the lint itself. + let warn_level = cmp::max(level, lint.min_level); + // If we're about to issue a warning, check at the last minute for any // directives against the warnings "lint". If, for example, there's an // `allow(warnings)` in scope then we want to respect that instead. - if level == Level::Warn { + if warn_level == Level::Warn { let (warnings_level, warnings_src) = self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux); if let Some(configured_warning_level) = warnings_level { if configured_warning_level != Level::Warn { + let orig_level = Some(level); level = configured_warning_level; - src = warnings_src; + src = match warnings_src { + LintSource::CommandLine(s, _) => LintSource::CommandLine(s, orig_level), + LintSource::Node(n, _, s, r) => LintSource::Node(n, orig_level, s, r), + other => other, + }; } } } @@ -174,14 +184,25 @@ impl<'a> HashStable> for LintLevelMap { } } +fn hyphenate(s: &str) -> String { + s.replace("_", "-") +} + pub fn struct_lint_level<'a>( sess: &'a Session, lint: &'static Lint, - level: Level, + orig_level: Level, src: LintSource, span: Option, msg: &str, ) -> DiagnosticBuilder<'a> { + // Pick the highest level of the given one and the minimum. + // The effect of this is that if e.g. `min_level == Warn` and + // you have `#[allow({lint.name})]` then a warning will still + // be emitted. + let min_level = lint.min_level; + let level = cmp::max(orig_level, min_level); + let mut err = match (level, span) { (Level::Allow, _) => return sess.diagnostic().struct_dummy(), (Level::Warn, Some(span)) => sess.struct_span_warn(span, msg), @@ -191,7 +212,6 @@ pub fn struct_lint_level<'a>( }; // Check for future incompatibility lints and issue a stronger warning. - let lint_id = LintId::of(lint); let future_incompatible = lint.future_incompatible; // If this code originates in a foreign macro, aka something that this crate @@ -214,92 +234,122 @@ pub fn struct_lint_level<'a>( } let name = lint.name_lower(); - match src { + let diag_msg_id = DiagnosticMessageId::from(lint); + let pre_warn_level = match src { LintSource::Default => { - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!("`#[{}({})]` on by default", level.as_str(), name), - ); + let msg = &format!("`#[{}({})]` on by default", orig_level.as_str(), name); + sess.diag_note_once(&mut err, diag_msg_id, msg); + None } - LintSource::CommandLine(lint_flag_val) => { - let flag = match level { - Level::Warn => "-W", - Level::Deny => "-D", - Level::Forbid => "-F", - Level::Allow => panic!(), - }; - let hyphen_case_lint_name = name.replace("_", "-"); - if lint_flag_val.as_str() == name { - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "requested on the command line with `{} {}`", - flag, hyphen_case_lint_name - ), - ); + LintSource::CommandLine(lint_flag_val, pre_warn_level) => { + let flag = orig_level.level_to_flag(); + let lint_name = hyphenate(&name); + let msg = if lint_flag_val.as_str() == name { + format!("requested on the command line with `{} {}`", flag, lint_name) } else { - let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-"); - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "`{} {}` implied by `{} {}`", - flag, hyphen_case_lint_name, flag, hyphen_case_flag_val - ), - ); - } + let flag_val = hyphenate(&lint_flag_val.as_str()); + format!("`{} {}` implied by `{} {}`", flag, lint_name, flag, flag_val) + }; + sess.diag_note_once(&mut err, diag_msg_id, &msg); + pre_warn_level } - LintSource::Node(lint_attr_name, src, reason) => { - if let Some(rationale) = reason { - err.note(&rationale.as_str()); + LintSource::Node(lint_attr_name, pre_warn_level, src, reason) => { + if orig_level >= level || pre_warn_level.is_some() { + if let Some(rationale) = reason { + err.note(&rationale.as_str()); + } } - sess.diag_span_note_once( - &mut err, - DiagnosticMessageId::from(lint), - src, - "lint level defined here", - ); + + sess.diag_span_note_once(&mut err, diag_msg_id, src, "lint level defined here"); if lint_attr_name.as_str() != name { - let level_str = level.as_str(); - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "`#[{}({})]` implied by `#[{}({})]`", - level_str, name, level_str, lint_attr_name - ), + let level_str = orig_level.as_str(); + let msg = format!( + "`#[{}({})]` implied by `#[{}({})]`", + level_str, name, level_str, lint_attr_name ); + sess.diag_note_once(&mut err, diag_msg_id, &msg); } + + pre_warn_level } + }; + + // Highlight the minimum as cause of the lint iff it was raised due to the minimum. + let orig_level = pre_warn_level.map(|pwl| cmp::min(pwl, orig_level)).unwrap_or(orig_level); + if orig_level < min_level { + let min_msg = format!("#[{}({})] is the minimum lint level", min_level.as_str(), name); + let rem_msg = format!("the lint level cannot be reduced to `{}`", orig_level.as_str()); + sess.diag_note_once(&mut err, diag_msg_id, &min_msg); + sess.diag_note_once(&mut err, diag_msg_id, &rem_msg) } err.code(DiagnosticId::Lint(name)); - if let Some(future_incompatible) = future_incompatible { - const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \ - it will become a hard error"; + check_future_compatibility(sess, lint, &mut err, Option::<&str>::None); - let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) { - "once this method is added to the standard library, \ - the ambiguity may cause an error or change in behavior!" - .to_owned() + return err; +} + +/// Check for future incompatibility lints and issue a stronger warning. +pub fn check_future_compatibility<'a>( + sess: &'a Session, + lint: &'static Lint, + err: &mut DiagnosticBuilder<'_>, + name: Option, +) { + // Check for future incompatibility lints and issue a stronger warning. + let lint_id = LintId::of(lint); + let future_incompatible = lint.future_incompatible; + if let Some(future_incompatible) = future_incompatible { + if lint_id == LintId::of(crate::lint::builtin::UNSTABLE_NAME_COLLISIONS) { + err.warn( + "once this method is added to the standard library, \ + the ambiguity may cause an error or change in behavior!", + ); } else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) { - "this borrowing pattern was not meant to be accepted, \ - and may become a hard error in the future" - .to_owned() - } else if let Some(edition) = future_incompatible.edition { - format!("{} in the {} edition!", STANDARD_MESSAGE, edition) + err.warn( + "this borrowing pattern was not meant to be accepted, \ + and may become a hard error in the future", + ); } else { - format!("{} in a future release!", STANDARD_MESSAGE) - }; - let citation = format!("for more information, see {}", future_incompatible.reference); - err.warn(&explanation); - err.note(&citation); + let hard_err_msg = if let Some(edition) = future_incompatible.edition { + format!("it will become a hard error in the {} edition!", edition) + } else { + format!("it will become a hard error in a future release!") + }; + + let previously_msg = if let Some(n) = name { + format!( + "`{}` was previously accepted by the compiler but is being phased out; {}", + n, hard_err_msg + ) + } else { + format!( + "this was previously accepted by the compiler but is being phased out; {}", + hard_err_msg + ) + }; + err.warn(&previously_msg); + } + + err.note(&format!("for more information, see {}", future_incompatible.reference)); } - return err; + // If this code originates in a foreign macro, aka something that this crate + // did not itself author, then it's likely that there's nothing this crate + // can do about it. We probably want to skip the lint entirely. + if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) { + // Any suggestions made here are likely to be incorrect, so anything we + // emit shouldn't be automatically fixed by rustfix. + err.allow_suggestions(false); + + // If this is a future incompatible lint it'll become a hard error, so + // we have to emit *something*. Also allow lints to whitelist themselves + // on a case-by-case basis for emission in a foreign macro. + if future_incompatible.is_none() && !lint.report_in_external_macro { + err.cancel() + } + } } /// Returns whether `span` originates in a foreign crate's external macro. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c8d3d5f9c83d8..1c6e5e3c07c62 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1050,7 +1050,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { } } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` TYPE_ALIAS_BOUNDS, Warn, "bounds in type aliases are not enforced" diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs index d5bbdc53160f6..5c862e6075b83 100644 --- a/src/librustc_lint/levels.rs +++ b/src/librustc_lint/levels.rs @@ -11,7 +11,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; -use rustc_session::lint::{builtin, Level, Lint}; +use rustc_session::lint::{builtin, Level, Lint, LintId}; use rustc_session::Session; use rustc_span::{sym, MultiSpan, Symbol}; use syntax::ast; @@ -85,7 +85,7 @@ impl<'a> LintLevelsBuilder<'a> { Err(_) => continue, // errors handled in check_lint_name_cmdline above }; for id in ids { - let src = LintSource::CommandLine(lint_flag_val); + let src = LintSource::CommandLine(lint_flag_val, None); specs.insert(id, (level, src)); } } @@ -211,7 +211,7 @@ impl<'a> LintLevelsBuilder<'a> { let name = meta_item.path.segments.last().expect("empty lint name").ident.name; match store.check_lint_name(&name.as_str(), tool_name) { CheckLintNameResult::Ok(ids) => { - let src = LintSource::Node(name, li.span(), reason); + let src = LintSource::Node(name, None, li.span(), reason); for id in ids { specs.insert(*id, (level, src)); } @@ -223,6 +223,7 @@ impl<'a> LintLevelsBuilder<'a> { let complete_name = &format!("{}::{}", tool_name.unwrap(), name); let src = LintSource::Node( Symbol::intern(complete_name), + None, li.span(), reason, ); @@ -258,6 +259,7 @@ impl<'a> LintLevelsBuilder<'a> { let src = LintSource::Node( Symbol::intern(&new_lint_name), + None, li.span(), reason, ); @@ -328,6 +330,8 @@ impl<'a> LintLevelsBuilder<'a> { } for (id, &(level, ref src)) in specs.iter() { + self.lint_higher_minimum_attr_lint(id.lint, level, src, &specs); + if level == Level::Forbid { continue; } @@ -337,11 +341,11 @@ impl<'a> LintLevelsBuilder<'a> { }; let forbidden_lint_name = match forbid_src { LintSource::Default => id.to_string(), - LintSource::Node(name, _, _) => name.to_string(), - LintSource::CommandLine(name) => name.to_string(), + LintSource::Node(name, _, _, _) => name.to_string(), + LintSource::CommandLine(name, _) => name.to_string(), }; let (lint_attr_name, lint_attr_span) = match *src { - LintSource::Node(name, span, _) => (name, span), + LintSource::Node(name, _, span, _) => (name, span), _ => continue, }; let mut diag_builder = struct_span_err!( @@ -356,13 +360,13 @@ impl<'a> LintLevelsBuilder<'a> { diag_builder.span_label(lint_attr_span, "overruled by previous forbid"); match forbid_src { LintSource::Default => {} - LintSource::Node(_, forbid_source_span, reason) => { + LintSource::Node(_, _, forbid_source_span, reason) => { diag_builder.span_label(forbid_source_span, "`forbid` level set here"); if let Some(rationale) = reason { diag_builder.note(&rationale.as_str()); } } - LintSource::CommandLine(_) => { + LintSource::CommandLine(_, _) => { diag_builder.note("`forbid` lint level was set on command line"); } } @@ -380,6 +384,43 @@ impl<'a> LintLevelsBuilder<'a> { BuilderPush { prev: prev, changed: prev != self.cur } } + /// If we have e.g. `#[allow($some_future_compat_lint)]` this will have + /// no effect as `min_level > Allow`. We want to tell the user about this. + fn lint_higher_minimum_attr_lint( + &self, + lint: &'static Lint, + level: Level, + src: &LintSource, + specs: &FxHashMap, + ) { + let min_level = lint.min_level; + if min_level <= level { + return; + } + + if let LintSource::Node(name, _, span, _) = src { + // Get the `unused_attributes` lint specs: + let unused = builtin::UNUSED_ATTRIBUTES; + let (lvl, src) = self.sets.get_lint_level(unused, self.cur, Some(&specs), &self.sess); + + // Construct base diagnostic for `unused_attributes`: + let level_str = level.as_str(); + let msg = format!("#[{}({})] has no effect", level_str, name); + let multi_span = Some((*span).into()); + let mut err = struct_lint_level(self.sess, unused, lvl, src, multi_span, &msg); + + // Add notes about minimum levels and what the user should do here: + err.note(&format!("the minimum lint level for `{}` is `{}`", name, min_level.as_str())) + .note(&format!("the lint level cannot be reduced to `{}`", level_str)) + .help(&format!("remove the #[{}({})] directive", level_str, name)); + + // If it is a future compat lint, warn the user about it. + rustc::lint::check_future_compatibility(self.sess, lint, &mut err, Some(name)); + + err.emit(); + } + } + /// Called after `push` when the scope of a set of attributes are exited. pub fn pop(&mut self, push: BuilderPush) { self.cur = push.prev; diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index 2ba3932c7d97e..138d9e44dbd0e 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -49,6 +49,15 @@ impl Level { _ => None, } } + + pub fn level_to_flag(self) -> &'static str { + match self { + Level::Warn => "-W", + Level::Deny => "-D", + Level::Forbid => "-F", + Level::Allow => "-A", + } + } } /// Specification of a single lint. @@ -69,6 +78,11 @@ pub struct Lint { /// Default level for the lint. pub default_level: Level, + /// The minimum level this lint can be loosened to. + /// For example, suppose we have `#[allow(my_lint)]` and `min_level == Warn`. + /// In that case, a warning will still be emitted. + pub min_level: Level, + /// Description of the lint or the issue it detects. /// /// e.g., "imports that are never used" @@ -101,6 +115,7 @@ impl Lint { Lint { name: "", default_level: Level::Forbid, + min_level: Level::Allow, desc: "", edition_lint_opts: None, is_plugin: false, @@ -277,6 +292,7 @@ macro_rules! declare_lint { $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, + min_level: $crate::lint::Allow, desc: $desc, edition_lint_opts: None, is_plugin: false, @@ -291,6 +307,7 @@ macro_rules! declare_lint { $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, + min_level: $crate::lint::Allow, desc: $desc, edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)), report_in_external_macro: false, @@ -299,6 +316,49 @@ macro_rules! declare_lint { ); } +/// Declares a static item of type `&'static Lint` that is unsuppressable. +/// +/// This means that the lint will have `Warn` as the minimum lint level. +/// Therefore, it cannot be `#[allow(..)]`ed. +/// +/// This lint should be used for C-future-compatibility lints on an opt-in +/// case-by-case basis. +/// +/// Note that the default is to use `declare_lint!`. It is recommended that +/// a lint spend at least one release cycle using `declare_lint!` before +/// moving to `declare_unsuppressable_lint!`. +/// +/// Before moving the C-future-compatibility lint into a hard error, +/// it is also recommended that `declare_unsuppressable_lint!` be used +/// at least one release cycle. +#[macro_export] +macro_rules! declare_unsuppressable_lint { + ($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, + min_level: $crate::lint::Warn, + desc: $desc, + edition_lint_opts: None, + report_in_external_macro: false, + }; + }; + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, + $(@future_incompatible = $fi:expr;)? $($v:ident),*) => ( + $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { + name: stringify!($NAME), + default_level: $crate::lint::$Level, + min_level: $crate::lint::Warn, + desc: $desc, + edition_lint_opts: None, + is_plugin: false, + $($v: true,)* + $(future_incompatible: Some($fi),)* + ..$crate::lint::Lint::default_fields_for_macro() + }; + ); +} + #[macro_export] macro_rules! declare_tool_lint { ( @@ -320,6 +380,7 @@ macro_rules! declare_tool_lint { $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: &concat!(stringify!($tool), "::", stringify!($NAME)), default_level: $crate::lint::$Level, + min_level: $crate::lint::Allow, desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 3e8503ef661f0..c4e69da3a2611 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -5,10 +5,10 @@ //! lints are all available in `rustc_lint::builtin`. use crate::lint::FutureIncompatibleInfo; -use crate::{declare_lint, declare_lint_pass}; +use crate::{declare_lint, declare_lint_pass, declare_unsuppressable_lint}; use rustc_span::edition::Edition; -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub ILL_FORMED_ATTRIBUTE_INPUT, Deny, "ill-formed attribute inputs that were previously accepted and used in practice", @@ -158,7 +158,7 @@ declare_lint! { "detects trivial casts of numeric types which could be removed" } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub PRIVATE_IN_PUBLIC, Warn, "detect private items in public interfaces not caught by the old implementation", @@ -184,7 +184,7 @@ declare_lint! { }; } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub INVALID_TYPE_PARAM_DEFAULT, Deny, "type parameter default erroneously allowed in invalid location", @@ -200,7 +200,7 @@ declare_lint! { "lints that have been renamed or removed" } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub SAFE_PACKED_BORROWS, Warn, "safe borrows of fields of packed structs were was erroneously allowed", @@ -210,7 +210,7 @@ declare_lint! { }; } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub PATTERNS_IN_FNS_WITHOUT_BODY, Deny, "patterns in functions without body were erroneously allowed", @@ -220,7 +220,7 @@ declare_lint! { }; } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub MISSING_FRAGMENT_SPECIFIER, Deny, "detects missing fragment specifiers in unused `macro_rules!` patterns", @@ -230,7 +230,7 @@ declare_lint! { }; } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub LATE_BOUND_LIFETIME_ARGUMENTS, Warn, "detects generic lifetime arguments in path segments with late bound lifetime parameters", @@ -240,7 +240,7 @@ declare_lint! { }; } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub ORDER_DEPENDENT_TRAIT_OBJECTS, Deny, "trait-object types were treated as different depending on marker-trait order", @@ -287,7 +287,7 @@ declare_lint! { "detects lifetime parameters that are never used" } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub TYVAR_BEHIND_RAW_POINTER, Warn, "raw pointer to an inference variable", @@ -320,7 +320,7 @@ declare_lint! { }; } -declare_lint! { +declare_unsuppressable_lint! { pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, Warn, "floating-point literals cannot be used in patterns", @@ -372,7 +372,7 @@ declare_lint! { "detects code samples in docs of private items not documented by rustdoc" } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, "checks the object safety of where clauses", @@ -434,7 +434,7 @@ declare_lint! { report_in_external_macro } -declare_lint! { +declare_lint! { // FIXME(centril): consider using `declare_unsuppressable_lint` pub AMBIGUOUS_ASSOCIATED_ITEMS, Deny, "ambiguous associated items", diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr index 26d0cf9e9ecba..c04297f0d3f0d 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr @@ -1,3 +1,19 @@ +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-exhaustive-fail.rs:16:14 + | +LL | m!(0f32, core::f32::NEG_INFINITY..); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/half-open-range-pats-exhaustive-fail.rs:5:10 + | +LL | #![allow(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: #[warn(illegal_floating_point_literal_pattern)] is the minimum lint level + = note: the lint level cannot be reduced to `allow` + = 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 #41620 + error[E0004]: non-exhaustive patterns: `_` not covered --> $DIR/half-open-range-pats-exhaustive-fail.rs:16:8 | @@ -6,6 +22,15 @@ LL | m!(0f32, core::f32::NEG_INFINITY..); | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-exhaustive-fail.rs:17:16 + | +LL | m!(0f32, ..core::f32::INFINITY); + | ^^^^^^^^^^^^^^^^^^^ + | + = 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 #41620 + error[E0004]: non-exhaustive patterns: `_` not covered --> $DIR/half-open-range-pats-exhaustive-fail.rs:17:8 | @@ -542,6 +567,24 @@ LL | m!(0, ..VAL_1 | VAL_2..); | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-exhaustive-fail.rs:16:14 + | +LL | m!(0f32, core::f32::NEG_INFINITY..); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-exhaustive-fail.rs:17:16 + | +LL | m!(0f32, ..core::f32::INFINITY); + | ^^^^^^^^^^^^^^^^^^^ + | + = 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 #41620 + error: aborting due to 68 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr index b536e1b5548d0..acbd379878358 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr @@ -58,12 +58,37 @@ error[E0579]: lower range bound must be less than upper LL | m!(0, ..core::i128::MIN); | ^^^^^^^^^^^^^^^^^ +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:16 + | +LL | m!(0f32, ..core::f32::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/half-open-range-pats-hair-lower-empty.rs:3:10 + | +LL | #![allow(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: #[warn(illegal_floating_point_literal_pattern)] is the minimum lint level + = note: the lint level cannot be reduced to `allow` + = 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 #41620 + error[E0579]: lower range bound must be less than upper --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:14 | LL | m!(0f32, ..core::f32::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:16 + | +LL | m!(0f64, ..core::f64::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #41620 + error[E0579]: lower range bound must be less than upper --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:14 | @@ -136,12 +161,30 @@ error[E0579]: lower range bound must be less than upper LL | m!(0, ..core::i128::MIN); | ^^^^^^^^^^^^^^^^^ +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:16 + | +LL | m!(0f32, ..core::f32::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #41620 + error[E0579]: lower range bound must be less than upper --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:14 | LL | m!(0f32, ..core::f32::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: floating-point types cannot be used in patterns + --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:16 + | +LL | m!(0f64, ..core::f64::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #41620 + error[E0579]: lower range bound must be less than upper --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:14 | diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr index 6de615c3de4fd..38fafb1774983 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr @@ -1,3 +1,46 @@ +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:6:7 + | +LL | 0.0..=1.0 => {} + | ^^^ + | +note: lint level defined here + --> $DIR/non-exhaustive-float-range-match.rs:1:10 + | +LL | #![allow(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: #[warn(illegal_floating_point_literal_pattern)] is the minimum lint level + = note: the lint level cannot be reduced to `allow` + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:6:13 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:11:7 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:11:13 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + error[E0004]: non-exhaustive patterns: `_` not covered --> $DIR/non-exhaustive-float-range-match.rs:10:11 | @@ -6,6 +49,42 @@ LL | match 0.0 { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:6:7 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:6:13 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:11:7 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-float-range-match.rs:11:13 + | +LL | 0.0..=1.0 => {} + | ^^^ + | + = 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 #41620 + error: aborting due to previous error For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index a06ad5788515c..899f2db0640d0 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -66,6 +66,67 @@ LL | match *vec { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:47:10 + | +LL | [0.1, 0.2, 0.3] => (), + | ^^^ + | +note: lint level defined here + --> $DIR/non-exhaustive-match.rs:1:10 + | +LL | #![allow(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: #[warn(illegal_floating_point_literal_pattern)] is the minimum lint level + = note: the lint level cannot be reduced to `allow` + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:47:15 + | +LL | [0.1, 0.2, 0.3] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:47:20 + | +LL | [0.1, 0.2, 0.3] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:48:10 + | +LL | [0.1, 0.2] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:48:15 + | +LL | [0.1, 0.2] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:49:10 + | +LL | [0.1] => (), + | ^^^ + | + = 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 #41620 + error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered --> $DIR/non-exhaustive-match.rs:46:11 | @@ -74,6 +135,60 @@ LL | match *vec { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:47:10 + | +LL | [0.1, 0.2, 0.3] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:47:15 + | +LL | [0.1, 0.2, 0.3] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:47:20 + | +LL | [0.1, 0.2, 0.3] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:48:10 + | +LL | [0.1, 0.2] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:48:15 + | +LL | [0.1, 0.2] => (), + | ^^^ + | + = 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 #41620 + +warning: floating-point types cannot be used in patterns + --> $DIR/non-exhaustive-match.rs:49:10 + | +LL | [0.1] => (), + | ^^^ + | + = 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 #41620 + error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0004`.