Rollup merge of #60529 - davidtwco:rfc-2008-uninhabited, r=petrochenkov
RFC 2008: Uninhabitedness fixes for enum variants and tests Part of #44109. At the request of @Centril, this PR adds tests asserting that uninhabited non-exhaustive types are considered inhabited in extern crates. In adding these tests, I fixed an oversight in the implementation of RFC 2008 on enum variants that resulted in non-exhaustive enum variants being considered uninhabited in extern crates. Before this PR, these lines would error: ```rust // extern crate pub enum UninhabitedVariants { #[non_exhaustive] Tuple(!), #[non_exhaustive] Struct { x: ! } } pub enum PartiallyInhabitedVariants { Tuple(u8), #[non_exhaustive] Struct { x: ! } } // current crate match uninhabited_variant() /* fn() -> Option<UninhabitedVariants> */ { Some(_x) => (), //~ ERROR unreachable pattern None => (), } while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() /* fn() -> PartiallyInhabitedVariants */ { //~^ ERROR unreachable pattern } ``` cc @Centril r? @petrochenkov
This commit is contained in:
commit
d94cb9f2ea
@ -113,9 +113,14 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
substs: SubstsRef<'tcx>) -> DefIdForest
|
||||
{
|
||||
DefIdForest::intersection(tcx, self.variants.iter().map(|v| {
|
||||
v.uninhabited_from(tcx, substs, self.adt_kind())
|
||||
}))
|
||||
// Non-exhaustive ADTs from other crates are always considered inhabited.
|
||||
if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
|
||||
DefIdForest::empty()
|
||||
} else {
|
||||
DefIdForest::intersection(tcx, self.variants.iter().map(|v| {
|
||||
v.uninhabited_from(tcx, substs, self.adt_kind())
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,9 +139,14 @@ impl<'a, 'gcx, 'tcx> VariantDef {
|
||||
AdtKind::Enum => true,
|
||||
AdtKind::Struct => false,
|
||||
};
|
||||
DefIdForest::union(tcx, self.fields.iter().map(|f| {
|
||||
f.uninhabited_from(tcx, substs, is_enum)
|
||||
}))
|
||||
// Non-exhaustive variants from other crates are always considered inhabited.
|
||||
if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
|
||||
DefIdForest::empty()
|
||||
} else {
|
||||
DefIdForest::union(tcx, self.fields.iter().map(|f| {
|
||||
f.uninhabited_from(tcx, substs, is_enum)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,6 +388,18 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_non_exhaustive_variant<'p>(&self, pattern: &'p Pattern<'tcx>) -> bool
|
||||
where 'a: 'p
|
||||
{
|
||||
match *pattern.kind {
|
||||
PatternKind::Variant { adt_def, variant_index, .. } => {
|
||||
let ref variant = adt_def.variants[variant_index];
|
||||
variant.is_field_list_non_exhaustive()
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
|
||||
match ty.sty {
|
||||
ty::Adt(adt_def, ..) => adt_def.is_variant_list_non_exhaustive(),
|
||||
@ -1097,10 +1109,17 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v[0]);
|
||||
|
||||
if let Some(constructors) = pat_constructors(cx, v[0], pcx) {
|
||||
debug!("is_useful - expanding constructors: {:#?}", constructors);
|
||||
split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
|
||||
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
|
||||
).find(|result| result.is_useful()).unwrap_or(NotUseful)
|
||||
let is_declared_nonexhaustive = cx.is_non_exhaustive_variant(v[0]) && !cx.is_local(pcx.ty);
|
||||
debug!("is_useful - expanding constructors: {:#?}, is_declared_nonexhaustive: {:?}",
|
||||
constructors, is_declared_nonexhaustive);
|
||||
|
||||
if is_declared_nonexhaustive {
|
||||
Useful
|
||||
} else {
|
||||
split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
|
||||
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
|
||||
).find(|result| result.is_useful()).unwrap_or(NotUseful)
|
||||
}
|
||||
} else {
|
||||
debug!("is_useful - expanding wildcard");
|
||||
|
||||
|
@ -208,7 +208,11 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
|
||||
.map(|variant| variant.ident)
|
||||
.collect();
|
||||
}
|
||||
def.variants.is_empty()
|
||||
|
||||
let is_non_exhaustive_and_non_local =
|
||||
def.is_variant_list_non_exhaustive() && !def.did.is_local();
|
||||
|
||||
!(is_non_exhaustive_and_non_local) && def.variants.is_empty()
|
||||
},
|
||||
_ => false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1071:5
|
||||
thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1083:5
|
||||
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
|
||||
|
||||
error: internal compiler error: unexpected panic
|
||||
|
@ -0,0 +1,33 @@
|
||||
#![crate_type = "rlib"]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
pub enum PartiallyInhabitedVariants {
|
||||
Tuple(u8),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
pub struct IndirectUninhabitedEnum(UninhabitedEnum);
|
||||
|
||||
pub struct IndirectUninhabitedStruct(UninhabitedStruct);
|
||||
|
||||
pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
|
||||
|
||||
pub struct IndirectUninhabitedVariants(UninhabitedVariants);
|
38
src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs
Normal file
38
src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// aux-build:uninhabited.rs
|
||||
#![feature(never_type)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
use uninhabited::{
|
||||
UninhabitedEnum,
|
||||
UninhabitedStruct,
|
||||
UninhabitedTupleStruct,
|
||||
UninhabitedVariants,
|
||||
};
|
||||
|
||||
// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never
|
||||
// type can.
|
||||
|
||||
struct A;
|
||||
|
||||
fn can_coerce_never_type_to_anything(x: !) -> A {
|
||||
x
|
||||
}
|
||||
|
||||
fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,47 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions.rs:23:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found enum `uninhabited::UninhabitedEnum`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `uninhabited::UninhabitedEnum`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions.rs:27:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found struct `uninhabited::UninhabitedTupleStruct`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `uninhabited::UninhabitedTupleStruct`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions.rs:31:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found struct `uninhabited::UninhabitedStruct`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `uninhabited::UninhabitedStruct`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions.rs:35:5
|
||||
|
|
||||
LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found enum `uninhabited::UninhabitedVariants`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `uninhabited::UninhabitedVariants`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -0,0 +1,46 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce
|
||||
// to any type, as the never type can.
|
||||
|
||||
fn can_coerce_never_type_to_anything(x: !) -> A {
|
||||
x
|
||||
}
|
||||
|
||||
fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
|
||||
x //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,47 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:31:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found enum `UninhabitedEnum`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `UninhabitedEnum`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:35:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found struct `UninhabitedTupleStruct`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `UninhabitedTupleStruct`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:39:5
|
||||
|
|
||||
LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found struct `UninhabitedStruct`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `UninhabitedStruct`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coercions_same_crate.rs:43:5
|
||||
|
|
||||
LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
|
||||
| - expected `A` because of return type
|
||||
LL | x
|
||||
| ^ expected struct `A`, found enum `UninhabitedVariants`
|
||||
|
|
||||
= note: expected type `A`
|
||||
found type `UninhabitedVariants`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -0,0 +1,36 @@
|
||||
// aux-build:uninhabited.rs
|
||||
#![feature(never_type)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
use uninhabited::{
|
||||
IndirectUninhabitedEnum,
|
||||
IndirectUninhabitedStruct,
|
||||
IndirectUninhabitedTupleStruct,
|
||||
IndirectUninhabitedVariants,
|
||||
};
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type through a level of
|
||||
// indirection from an extern crate will not compile.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
|
||||
x: IndirectUninhabitedVariants,
|
||||
) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,35 @@
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `uninhabited::IndirectUninhabitedEnum` is not handled
|
||||
--> $DIR/indirect_match.rs:19:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `uninhabited::IndirectUninhabitedStruct` is not handled
|
||||
--> $DIR/indirect_match.rs:23:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `uninhabited::IndirectUninhabitedTupleStruct` is not handled
|
||||
--> $DIR/indirect_match.rs:27:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `uninhabited::IndirectUninhabitedVariants` is not handled
|
||||
--> $DIR/indirect_match.rs:33:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
@ -0,0 +1,52 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
pub struct IndirectUninhabitedEnum(UninhabitedEnum);
|
||||
|
||||
pub struct IndirectUninhabitedStruct(UninhabitedStruct);
|
||||
|
||||
pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
|
||||
|
||||
pub struct IndirectUninhabitedVariants(UninhabitedVariants);
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type through a level of
|
||||
// indirection from the defining crate will not compile without `#![feature(exhaustive_patterns)]`.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
|
||||
x: IndirectUninhabitedVariants,
|
||||
) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,59 @@
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `IndirectUninhabitedEnum` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:35:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
|
||||
| ----------------------------------------------------
|
||||
| | |
|
||||
| | variant not covered
|
||||
| `IndirectUninhabitedEnum` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `IndirectUninhabitedStruct` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:39:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
|
||||
| --------------------------------------------------------
|
||||
| | |
|
||||
| | variant not covered
|
||||
| `IndirectUninhabitedStruct` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `IndirectUninhabitedTupleStruct` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:43:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
|
||||
| ------------------------------------------------------------------
|
||||
| | |
|
||||
| | variant not covered
|
||||
| `IndirectUninhabitedTupleStruct` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `IndirectUninhabitedVariants` is not handled
|
||||
--> $DIR/indirect_match_same_crate.rs:49:11
|
||||
|
|
||||
LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
|
||||
| ------------------------------------------------------------
|
||||
| | |
|
||||
| | variant not covered
|
||||
| `IndirectUninhabitedVariants` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
@ -0,0 +1,40 @@
|
||||
// aux-build:uninhabited.rs
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
use uninhabited::{
|
||||
IndirectUninhabitedEnum,
|
||||
IndirectUninhabitedStruct,
|
||||
IndirectUninhabitedTupleStruct,
|
||||
IndirectUninhabitedVariants,
|
||||
};
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type through a level of
|
||||
// indirection from an extern crate will not compile. In particular, this enables the
|
||||
// `exhaustive_patterns` feature as this can change the branch used in the compiler to determine
|
||||
// this.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
|
||||
x: IndirectUninhabitedVariants,
|
||||
) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,35 @@
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedEnum` is non-empty
|
||||
--> $DIR/indirect_match_with_exhaustive_patterns.rs:23:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedStruct` is non-empty
|
||||
--> $DIR/indirect_match_with_exhaustive_patterns.rs:27:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedTupleStruct` is non-empty
|
||||
--> $DIR/indirect_match_with_exhaustive_patterns.rs:31:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedVariants` is non-empty
|
||||
--> $DIR/indirect_match_with_exhaustive_patterns.rs:37:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
@ -0,0 +1,58 @@
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
pub struct IndirectUninhabitedEnum(UninhabitedEnum);
|
||||
|
||||
pub struct IndirectUninhabitedStruct(UninhabitedStruct);
|
||||
|
||||
pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
|
||||
|
||||
pub struct IndirectUninhabitedVariants(UninhabitedVariants);
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
|
||||
// will compile. In particular, this enables the `exhaustive_patterns` feature as this can
|
||||
// change the branch used in the compiler to determine this.
|
||||
// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
|
||||
x: IndirectUninhabitedVariants,
|
||||
) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn main() {}
|
34
src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs
Normal file
34
src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// aux-build:uninhabited.rs
|
||||
#![feature(never_type)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
use uninhabited::{
|
||||
UninhabitedEnum,
|
||||
UninhabitedStruct,
|
||||
UninhabitedTupleStruct,
|
||||
UninhabitedVariants,
|
||||
};
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate
|
||||
// will not compile.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn main() {}
|
35
src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
Normal file
35
src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
Normal file
@ -0,0 +1,35 @@
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty
|
||||
--> $DIR/match.rs:19:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `uninhabited::UninhabitedStruct` is not handled
|
||||
--> $DIR/match.rs:23:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `uninhabited::UninhabitedTupleStruct` is not handled
|
||||
--> $DIR/match.rs:27:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: multiple patterns of type `uninhabited::UninhabitedVariants` are not handled
|
||||
--> $DIR/match.rs:31:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
@ -0,0 +1,42 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
|
||||
// will compile.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,49 @@
|
||||
error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `UninhabitedStruct` is not handled
|
||||
--> $DIR/match_same_crate.rs:31:11
|
||||
|
|
||||
LL | pub struct UninhabitedStruct {
|
||||
| - ----------------- variant not covered
|
||||
| _|
|
||||
| |
|
||||
LL | | _priv: !,
|
||||
LL | | }
|
||||
| |_- `UninhabitedStruct` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `UninhabitedTupleStruct` is not handled
|
||||
--> $DIR/match_same_crate.rs:35:11
|
||||
|
|
||||
LL | pub struct UninhabitedTupleStruct(!);
|
||||
| -------------------------------------
|
||||
| | |
|
||||
| | variant not covered
|
||||
| `UninhabitedTupleStruct` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: multiple patterns of type `UninhabitedVariants` are not handled
|
||||
--> $DIR/match_same_crate.rs:39:11
|
||||
|
|
||||
LL | / pub enum UninhabitedVariants {
|
||||
LL | | #[non_exhaustive] Tuple(!),
|
||||
| | ----- variant not covered
|
||||
LL | | #[non_exhaustive] Struct { x: ! }
|
||||
| | ------ variant not covered
|
||||
LL | | }
|
||||
| |_- `UninhabitedVariants` defined here
|
||||
...
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
@ -0,0 +1,37 @@
|
||||
// aux-build:uninhabited.rs
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
use uninhabited::{
|
||||
UninhabitedEnum,
|
||||
UninhabitedStruct,
|
||||
UninhabitedTupleStruct,
|
||||
UninhabitedVariants,
|
||||
};
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate
|
||||
// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can
|
||||
// change the branch used in the compiler to determine this.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
|
||||
match x {} //~ ERROR non-exhaustive patterns
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,35 @@
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty
|
||||
--> $DIR/match_with_exhaustive_patterns.rs:22:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedStruct` is non-empty
|
||||
--> $DIR/match_with_exhaustive_patterns.rs:26:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedTupleStruct` is non-empty
|
||||
--> $DIR/match_with_exhaustive_patterns.rs:30:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedVariants` is non-empty
|
||||
--> $DIR/match_with_exhaustive_patterns.rs:34:11
|
||||
|
|
||||
LL | match x {}
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
@ -0,0 +1,48 @@
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
struct A;
|
||||
|
||||
// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
|
||||
// will compile. In particular, this enables the `exhaustive_patterns` feature as this can
|
||||
// change the branch used in the compiler to determine this.
|
||||
// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648.
|
||||
|
||||
fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
|
||||
match x {}
|
||||
}
|
||||
|
||||
fn main() {}
|
59
src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs
Normal file
59
src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs
Normal file
@ -0,0 +1,59 @@
|
||||
// aux-build:uninhabited.rs
|
||||
// compile-pass
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
||||
extern crate uninhabited;
|
||||
|
||||
use uninhabited::{
|
||||
PartiallyInhabitedVariants,
|
||||
UninhabitedEnum,
|
||||
UninhabitedStruct,
|
||||
UninhabitedTupleStruct,
|
||||
UninhabitedVariants,
|
||||
};
|
||||
|
||||
fn uninhabited_enum() -> Option<UninhabitedEnum> {
|
||||
None
|
||||
}
|
||||
|
||||
fn uninhabited_variant() -> Option<UninhabitedVariants> {
|
||||
None
|
||||
}
|
||||
|
||||
fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
|
||||
PartiallyInhabitedVariants::Tuple(3)
|
||||
}
|
||||
|
||||
fn uninhabited_struct() -> Option<UninhabitedStruct> {
|
||||
None
|
||||
}
|
||||
|
||||
fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
|
||||
None
|
||||
}
|
||||
|
||||
// This test checks that non-exhaustive types that would normally be considered uninhabited within
|
||||
// the defining crate are not considered uninhabited from extern crates.
|
||||
|
||||
fn main() {
|
||||
match uninhabited_enum() {
|
||||
Some(_x) => (), // This line would normally error.
|
||||
None => (),
|
||||
}
|
||||
|
||||
match uninhabited_variant() {
|
||||
Some(_x) => (), // This line would normally error.
|
||||
None => (),
|
||||
}
|
||||
|
||||
// This line would normally error.
|
||||
while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {
|
||||
}
|
||||
|
||||
while let Some(_x) = uninhabited_struct() { // This line would normally error.
|
||||
}
|
||||
|
||||
while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error.
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(non_exhaustive)]
|
||||
|
||||
#[non_exhaustive]
|
||||
pub enum UninhabitedEnum {
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedTupleStruct(!);
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct UninhabitedStruct {
|
||||
_priv: !,
|
||||
}
|
||||
|
||||
pub enum UninhabitedVariants {
|
||||
#[non_exhaustive] Tuple(!),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
pub enum PartiallyInhabitedVariants {
|
||||
Tuple(u8),
|
||||
#[non_exhaustive] Struct { x: ! }
|
||||
}
|
||||
|
||||
fn uninhabited_enum() -> Option<UninhabitedEnum> {
|
||||
None
|
||||
}
|
||||
|
||||
fn uninhabited_variant() -> Option<UninhabitedVariants> {
|
||||
None
|
||||
}
|
||||
|
||||
fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
|
||||
PartiallyInhabitedVariants::Tuple(3)
|
||||
}
|
||||
|
||||
fn uninhabited_struct() -> Option<UninhabitedStruct> {
|
||||
None
|
||||
}
|
||||
|
||||
fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
|
||||
None
|
||||
}
|
||||
|
||||
// This test checks that non-exhaustive types that would normally be considered uninhabited within
|
||||
// the defining crate are still considered uninhabited.
|
||||
|
||||
fn main() {
|
||||
match uninhabited_enum() {
|
||||
Some(_x) => (), //~ ERROR unreachable pattern
|
||||
None => (),
|
||||
}
|
||||
|
||||
match uninhabited_variant() {
|
||||
Some(_x) => (), //~ ERROR unreachable pattern
|
||||
None => (),
|
||||
}
|
||||
|
||||
while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
|
||||
//~^ ERROR unreachable pattern
|
||||
}
|
||||
|
||||
while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern
|
||||
}
|
||||
|
||||
while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:53:9
|
||||
|
|
||||
LL | Some(_x) => (),
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/patterns_same_crate.rs:1:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:58:9
|
||||
|
|
||||
LL | Some(_x) => (),
|
||||
| ^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:62:15
|
||||
|
|
||||
LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:66:15
|
||||
|
|
||||
LL | while let Some(_x) = uninhabited_struct() {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/patterns_same_crate.rs:69:15
|
||||
|
|
||||
LL | while let Some(_x) = uninhabited_tuple_struct() {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user