提交 2a042d61 编写于 作者: D Devin Ragotzy 提交者: Devin Ragotzy

Filter unstable and doc hidden variants in usefulness checking

Add test cases for unstable variants
Add test cases for doc hidden variants
Move is_doc_hidden to method on TyCtxt
Add unstable variants test to reachable-patterns ui test
Rename reachable-patterns -> omitted-patterns
上级 02f2b31e
......@@ -38,7 +38,7 @@
use rustc_query_system::ich::StableHashingContext;
use rustc_session::cstore::CrateStoreDyn;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::Span;
use rustc_span::{sym, Span};
use rustc_target::abi::Align;
use std::cmp::Ordering;
......@@ -1900,6 +1900,14 @@ pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
self.sess.contains_name(&self.get_attrs(did), attr)
}
/// Determines whether an item is annotated with `doc(hidden)`.
pub fn is_doc_hidden(self, did: DefId) -> bool {
self.get_attrs(did)
.iter()
.filter_map(|attr| if attr.has_name(sym::doc) { attr.meta_item_list() } else { None })
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
}
/// Returns `true` if this is an `auto trait`.
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).has_auto_impl
......
......@@ -52,11 +52,11 @@
use rustc_index::vec::Idx;
use rustc_hir::{HirId, RangeEnd};
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::mir::Field;
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{self, Const, Ty, TyCtxt, VariantDef};
use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue};
use rustc_session::lint;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Integer, Size, VariantIdx};
......@@ -675,6 +675,36 @@ fn as_slice(&self) -> Option<Slice> {
}
}
/// Checks if the `Constructor` is a variant and `TyCtxt::eval_stability` returns
/// `EvalResult::Deny { .. }`.
///
/// This means that the variant has a stdlib unstable feature marking it.
pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
if let Constructor::Variant(idx) = self {
if let ty::Adt(adt, _) = pcx.ty.kind() {
let variant_def_id = adt.variants[*idx].def_id;
// Filter variants that depend on a disabled unstable feature.
return matches!(
pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None),
EvalResult::Deny { .. }
);
}
}
false
}
/// Checks if the `Constructor` is a `Constructor::Variant` with a `#[doc(hidden)]`
/// attribute.
pub(super) fn is_doc_hidden_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
if let Constructor::Variant(idx) = self {
if let ty::Adt(adt, _) = pcx.ty.kind() {
let variant_def_id = adt.variants[*idx].def_id;
return pcx.cx.tcx.is_doc_hidden(variant_def_id);
}
}
false
}
fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx {
match *self {
Variant(idx) => idx,
......@@ -929,36 +959,33 @@ pub(super) fn new<'p>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Self {
// witness.
let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty);
let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns;
// If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
// as though it had an "unknown" constructor to avoid exposing its emptiness. The
// exception is if the pattern is at the top level, because we want empty matches to be
// considered exhaustive.
let is_secretly_empty = def.variants.is_empty()
&& !cx.tcx.features().exhaustive_patterns
&& !pcx.is_top_level;
if is_secretly_empty {
smallvec![NonExhaustive]
} else if is_declared_nonexhaustive {
def.variants
.indices()
.map(|idx| Variant(idx))
.chain(Some(NonExhaustive))
.collect()
} else if cx.tcx.features().exhaustive_patterns {
// If `exhaustive_patterns` is enabled, we exclude variants known to be
// uninhabited.
def.variants
.iter_enumerated()
.filter(|(_, v)| {
!v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
.contains(cx.tcx, cx.module)
})
.map(|(idx, _)| Variant(idx))
.collect()
} else {
def.variants.indices().map(|idx| Variant(idx)).collect()
let is_secretly_empty =
def.variants.is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
let mut ctors: SmallVec<[_; 1]> = def
.variants
.iter_enumerated()
.filter(|(_, v)| {
// If `exhaustive_patterns` is enabled, we exclude variants known to be
// uninhabited.
let is_uninhabited = is_exhaustive_pat_feature
&& v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
.contains(cx.tcx, cx.module);
!is_uninhabited
})
.map(|(idx, _)| Variant(idx))
.collect();
if is_secretly_empty || is_declared_nonexhaustive {
ctors.push(NonExhaustive);
}
ctors
}
ty::Char => {
smallvec![
......@@ -1068,7 +1095,7 @@ pub(super) fn iter_missing<'a, 'p>(
Missing {
nonexhaustive_enum_missing_real_variants: self
.iter_missing(pcx)
.any(|c| !c.is_non_exhaustive()),
.any(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx))),
}
} else {
Missing { nonexhaustive_enum_missing_real_variants: false }
......@@ -1222,9 +1249,9 @@ pub(super) fn iter_patterns<'a>(
/// Values and patterns can be represented as a constructor applied to some fields. This represents
/// a pattern in this form.
/// This also keeps track of whether the pattern has been foundreachable during analysis. For this
/// This also keeps track of whether the pattern has been found reachable during analysis. For this
/// reason we should be careful not to clone patterns for which we care about that. Use
/// `clone_and_forget_reachability` is you're sure.
/// `clone_and_forget_reachability` if you're sure.
pub(crate) struct DeconstructedPat<'p, 'tcx> {
ctor: Constructor<'tcx>,
fields: Fields<'p, 'tcx>,
......
......@@ -585,15 +585,33 @@ fn apply_constructor(
} else {
let mut split_wildcard = SplitWildcard::new(pcx);
split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor));
// This lets us know if we skipped any variants because they are marked
// `doc(hidden)` or they are unstable feature gate (only stdlib types).
let mut hide_variant_show_wild = false;
// Construct for each missing constructor a "wild" version of this
// constructor, that matches everything that can be built with
// it. For example, if `ctor` is a `Constructor::Variant` for
// `Option::Some`, we get the pattern `Some(_)`.
split_wildcard
let mut new: Vec<DeconstructedPat<'_, '_>> = split_wildcard
.iter_missing(pcx)
.cloned()
.map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor))
.collect()
.filter_map(|missing_ctor| {
// Check if this variant is marked `doc(hidden)`
if missing_ctor.is_doc_hidden_variant(pcx)
|| missing_ctor.is_unstable_variant(pcx)
{
hide_variant_show_wild = true;
return None;
}
Some(DeconstructedPat::wild_from_ctor(pcx, missing_ctor.clone()))
})
.collect();
if hide_variant_show_wild {
new.push(DeconstructedPat::wildcard(pcx.ty));
}
new
};
witnesses
......@@ -851,8 +869,10 @@ fn is_useful<'p, 'tcx>(
split_wildcard
.iter_missing(pcx)
// Filter out the `NonExhaustive` because we want to list only real
// variants.
.filter(|c| !c.is_non_exhaustive())
// variants. Also remove any unstable feature gated variants.
// Because of how we computed `nonexhaustive_enum_missing_real_variants`,
// this will not return an empty `Vec`.
.filter(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx)))
.cloned()
.map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor))
.collect::<Vec<_>>()
......
pub enum Foo {
A,
B,
#[doc(hidden)]
C,
}
#![feature(staged_api)]
#![stable(feature = "stable_test_feature", since = "1.0.0")]
#[stable(feature = "stable_test_feature", since = "1.0.0")]
pub enum Foo {
#[stable(feature = "stable_test_feature", since = "1.0.0")]
Stable,
#[stable(feature = "stable_test_feature", since = "1.0.0")]
Stable2,
#[unstable(feature = "unstable_test_feature", issue = "none")]
Unstable,
}
// aux-build:hidden.rs
extern crate hidden;
use hidden::Foo;
fn main() {
match Foo::A {
Foo::A => {}
Foo::B => {}
}
//~^^^^ non-exhaustive patterns: `_` not covered
match Foo::A {
Foo::A => {}
Foo::C => {}
}
//~^^^^ non-exhaustive patterns: `B` not covered
match Foo::A {
Foo::A => {}
}
//~^^^ non-exhaustive patterns: `B` and `_` not covered
match None {
None => {}
Some(Foo::A) => {}
}
//~^^^^ non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
}
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:8:11
|
LL | match Foo::A {
| ^^^^^^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Foo`
error[E0004]: non-exhaustive patterns: `B` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:14:11
|
LL | match Foo::A {
| ^^^^^^ pattern `B` not covered
|
::: $DIR/auxiliary/hidden.rs:3:5
|
LL | B,
| - not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Foo`
error[E0004]: non-exhaustive patterns: `B` and `_` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:20:11
|
LL | match Foo::A {
| ^^^^^^ patterns `B` and `_` not covered
|
::: $DIR/auxiliary/hidden.rs:3:5
|
LL | B,
| - not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Foo`
error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:25:11
|
LL | match None {
| ^^^^ patterns `Some(B)` and `Some(_)` not covered
|
::: $SRC_DIR/core/src/option.rs:LL:COL
|
LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
| ---- not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Option<Foo>`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0004`.
// aux-build:unstable.rs
extern crate unstable;
use unstable::Foo;
fn main() {
match Foo::Stable {
Foo::Stable => {}
}
//~^^^ non-exhaustive patterns: `Stable2` and `_` not covered
match Foo::Stable {
Foo::Stable => {}
Foo::Stable2 => {}
}
//~^^^^ non-exhaustive patterns: `_` not covered
}
error[E0004]: non-exhaustive patterns: `Stable2` and `_` not covered
--> $DIR/stable-gated-patterns.rs:8:11
|
LL | match Foo::Stable {
| ^^^^^^^^^^^ patterns `Stable2` and `_` not covered
|
::: $DIR/auxiliary/unstable.rs:9:5
|
LL | Stable2,
| ------- not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Foo`
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/stable-gated-patterns.rs:13:11
|
LL | match Foo::Stable {
| ^^^^^^^^^^^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Foo`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0004`.
#![feature(unstable_test_feature)]
// aux-build:unstable.rs
extern crate unstable;
use unstable::Foo;
fn main() {
match Foo::Stable {
Foo::Stable => {}
Foo::Stable2 => {}
}
//~^^^^ non-exhaustive patterns: `Unstable` not covered
// Ok: all variants are explicitly matched
match Foo::Stable {
Foo::Stable => {}
Foo::Stable2 => {}
Foo::Unstable => {}
}
}
error[E0004]: non-exhaustive patterns: `Unstable` not covered
--> $DIR/unstable-gated-patterns.rs:10:11
|
LL | match Foo::Stable {
| ^^^^^^^^^^^ pattern `Unstable` not covered
|
::: $DIR/auxiliary/unstable.rs:11:5
|
LL | Unstable,
| -------- not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
= note: the matched value is of type `Foo`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0004`.
#![feature(staged_api)]
#![stable(feature = "stable_test_feature", since = "1.0.0")]
#[stable(feature = "stable_test_feature", since = "1.0.0")]
#[non_exhaustive]
pub enum UnstableEnum {
#[stable(feature = "stable_test_feature", since = "1.0.0")]
Stable,
#[stable(feature = "stable_test_feature", since = "1.0.0")]
Stable2,
#[unstable(feature = "unstable_test_feature", issue = "none")]
Unstable,
}
#[stable(feature = "stable_test_feature", since = "1.0.0")]
#[non_exhaustive]
pub enum OnlyUnstableEnum {
#[unstable(feature = "unstable_test_feature", issue = "none")]
Unstable,
#[unstable(feature = "unstable_test_feature", issue = "none")]
Unstable2,
}
impl OnlyUnstableEnum {
#[stable(feature = "stable_test_feature", since = "1.0.0")]
pub fn new() -> Self {
Self::Unstable
}
}
// Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly.
#![feature(non_exhaustive_omitted_patterns_lint)]
#![feature(non_exhaustive_omitted_patterns_lint, unstable_test_feature)]
// aux-build:enums.rs
extern crate enums;
// aux-build:unstable.rs
extern crate unstable;
// aux-build:structs.rs
extern crate structs;
......@@ -12,6 +13,7 @@
EmptyNonExhaustiveEnum, NestedNonExhaustive, NonExhaustiveEnum, NonExhaustiveSingleVariant,
VariantNonExhaustive,
};
use unstable::{UnstableEnum, OnlyUnstableEnum};
use structs::{FunctionalRecord, MixedVisFields, NestedStruct, NormalStruct};
#[non_exhaustive]
......@@ -94,35 +96,6 @@ fn main() {
//~^^ some variants are not matched explicitly
//~^^^^^ some variants are not matched explicitly
// The io::ErrorKind has many `unstable` fields how do they interact with this
// lint
#[deny(non_exhaustive_omitted_patterns)]
match std::io::ErrorKind::Other {
std::io::ErrorKind::NotFound => {}
std::io::ErrorKind::PermissionDenied => {}
std::io::ErrorKind::ConnectionRefused => {}
std::io::ErrorKind::ConnectionReset => {}
std::io::ErrorKind::ConnectionAborted => {}
std::io::ErrorKind::NotConnected => {}
std::io::ErrorKind::AddrInUse => {}
std::io::ErrorKind::AddrNotAvailable => {}
std::io::ErrorKind::BrokenPipe => {}
std::io::ErrorKind::AlreadyExists => {}
std::io::ErrorKind::WouldBlock => {}
std::io::ErrorKind::InvalidInput => {}
std::io::ErrorKind::InvalidData => {}
std::io::ErrorKind::TimedOut => {}
std::io::ErrorKind::WriteZero => {}
std::io::ErrorKind::Interrupted => {}
std::io::ErrorKind::Other => {}
std::io::ErrorKind::UnexpectedEof => {}
std::io::ErrorKind::Unsupported => {}
std::io::ErrorKind::OutOfMemory => {}
// All stable variants are above and unstable in `_`
_ => {}
}
//~^^ some variants are not matched explicitly
#[warn(non_exhaustive_omitted_patterns)]
match VariantNonExhaustive::Baz(1, 2) {
VariantNonExhaustive::Baz(_, _) => {}
......@@ -163,4 +136,35 @@ fn main() {
// Ok: we don't lint on `if let` expressions
#[deny(non_exhaustive_omitted_patterns)]
if let NonExhaustiveEnum::Tuple(_) = non_enum {}
match UnstableEnum::Stable {
UnstableEnum::Stable => {}
UnstableEnum::Stable2 => {}
#[deny(non_exhaustive_omitted_patterns)]
_ => {}
}
//~^^ some variants are not matched explicitly
#[deny(non_exhaustive_omitted_patterns)]
match UnstableEnum::Stable {
UnstableEnum::Stable => {}
UnstableEnum::Stable2 => {}
UnstableEnum::Unstable => {}
_ => {}
}
// Ok: the feature is on and both variants are matched
#[deny(non_exhaustive_omitted_patterns)]
match OnlyUnstableEnum::Unstable {
OnlyUnstableEnum::Unstable => {}
OnlyUnstableEnum::Unstable2 => {}
_ => {}
}
#[deny(non_exhaustive_omitted_patterns)]
match OnlyUnstableEnum::Unstable {
OnlyUnstableEnum::Unstable => {}
_ => {}
}
//~^^ some variants are not matched explicitly
}
warning: some fields are not explicitly listed
--> $DIR/reachable-patterns.rs:129:9
--> $DIR/omitted-patterns.rs:102:9
|
LL | VariantNonExhaustive::Bar { x, .. } => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:126:12
--> $DIR/omitted-patterns.rs:99:12
|
LL | #[warn(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -13,13 +13,13 @@ LL | #[warn(non_exhaustive_omitted_patterns)]
= note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
warning: some fields are not explicitly listed
--> $DIR/reachable-patterns.rs:134:9
--> $DIR/omitted-patterns.rs:107:9
|
LL | let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:133:12
--> $DIR/omitted-patterns.rs:106:12
|
LL | #[warn(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -27,13 +27,13 @@ LL | #[warn(non_exhaustive_omitted_patterns)]
= note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
warning: some fields are not explicitly listed
--> $DIR/reachable-patterns.rs:142:29
--> $DIR/omitted-patterns.rs:115:29
|
LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:141:12
--> $DIR/omitted-patterns.rs:114:12
|
LL | #[warn(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -41,7 +41,7 @@ LL | #[warn(non_exhaustive_omitted_patterns)]
= note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
warning: some fields are not explicitly listed
--> $DIR/reachable-patterns.rs:142:9
--> $DIR/omitted-patterns.rs:115:9
|
LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed
......@@ -50,13 +50,13 @@ LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested
= note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:56:9
--> $DIR/omitted-patterns.rs:58:9
|
LL | _ => {}
| ^ pattern `Struct { .. }` not covered
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:55:16
--> $DIR/omitted-patterns.rs:57:16
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -64,13 +64,13 @@ LL | #[deny(non_exhaustive_omitted_patterns)]
= note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:63:9
--> $DIR/omitted-patterns.rs:65:9
|
LL | _ => {}
| ^ pattern `Tuple(_)` not covered
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:62:16
--> $DIR/omitted-patterns.rs:64:16
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -78,13 +78,13 @@ LL | #[deny(non_exhaustive_omitted_patterns)]
= note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:73:9
--> $DIR/omitted-patterns.rs:75:9
|
LL | _ => {}
| ^ pattern `Unit` not covered
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:72:16
--> $DIR/omitted-patterns.rs:74:16
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -92,13 +92,13 @@ LL | #[deny(non_exhaustive_omitted_patterns)]
= note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:90:32
--> $DIR/omitted-patterns.rs:92:32
|
LL | NestedNonExhaustive::A(_) => {}
| ^ patterns `Tuple(_)` and `Struct { .. }` not covered
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:87:12
--> $DIR/omitted-patterns.rs:89:12
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -106,7 +106,7 @@ LL | #[deny(non_exhaustive_omitted_patterns)]
= note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:92:9
--> $DIR/omitted-patterns.rs:94:9
|
LL | _ => {}
| ^ pattern `C` not covered
......@@ -115,32 +115,46 @@ LL | _ => {}
= note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:122:9
--> $DIR/omitted-patterns.rs:132:9
|
LL | _ => {}
| ^ patterns `HostUnreachable`, `NetworkUnreachable`, `NetworkDown` and 18 more not covered
| ^ pattern `A(_)` not covered
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:99:12
--> $DIR/omitted-patterns.rs:130:12
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: ensure that all variants are matched explicitly by adding the suggested match arms
= note: the matched value is of type `ErrorKind` and the `non_exhaustive_omitted_patterns` attribute was found
= note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/reachable-patterns.rs:159:9
--> $DIR/omitted-patterns.rs:144:9
|
LL | _ => {}
| ^ pattern `A(_)` not covered
| ^ pattern `Unstable` not covered
|
note: the lint level is defined here
--> $DIR/omitted-patterns.rs:143:16
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: ensure that all variants are matched explicitly by adding the suggested match arms
= note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: some variants are not matched explicitly
--> $DIR/omitted-patterns.rs:167:9
|
LL | _ => {}
| ^ pattern `Unstable2` not covered
|
note: the lint level is defined here
--> $DIR/reachable-patterns.rs:157:12
--> $DIR/omitted-patterns.rs:164:12
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: ensure that all variants are matched explicitly by adding the suggested match arms
= note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
= note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: aborting due to 7 previous errors; 4 warnings emitted
error: aborting due to 8 previous errors; 4 warnings emitted
// Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly with variants
// marked stable and unstable.
#![feature(non_exhaustive_omitted_patterns_lint)]
// aux-build:unstable.rs
extern crate unstable;
use unstable::{UnstableEnum, OnlyUnstableEnum};
fn main() {
// OK: this matches all the stable variants
match UnstableEnum::Stable {
UnstableEnum::Stable => {}
UnstableEnum::Stable2 => {}
#[deny(non_exhaustive_omitted_patterns)]
_ => {}
}
match UnstableEnum::Stable {
UnstableEnum::Stable => {}
#[deny(non_exhaustive_omitted_patterns)]
_ => {}
}
//~^^ some variants are not matched explicitly
// Ok: although this is a bit odd, we don't have anything to report
// since there is no stable variants and the feature is off
#[deny(non_exhaustive_omitted_patterns)]
match OnlyUnstableEnum::new() {
_ => {}
}
}
error: some variants are not matched explicitly
--> $DIR/stable-omitted-patterns.rs:23:9
|
LL | _ => {}
| ^ pattern `Stable2` not covered
|
note: the lint level is defined here
--> $DIR/stable-omitted-patterns.rs:22:16
|
LL | #[deny(non_exhaustive_omitted_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: ensure that all variants are matched explicitly by adding the suggested match arms
= note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
error: aborting due to previous error
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册