Hide uninhabitedness checks behind feature gate
This commit is contained in:
parent
c0d0e68be4
commit
2b7a23ed30
@ -191,11 +191,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
}
|
||||
}
|
||||
TyRef(_, ref tm) => {
|
||||
if tcx.sess.features.borrow().never_type {
|
||||
tm.ty.uninhabited_from(visited, tcx)
|
||||
} else {
|
||||
DefIdForest::empty()
|
||||
}
|
||||
tm.ty.uninhabited_from(visited, tcx)
|
||||
}
|
||||
|
||||
_ => DefIdForest::empty(),
|
||||
|
@ -379,19 +379,24 @@ impl<'tcx> Witness<'tcx> {
|
||||
fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
pcx: PatternContext<'tcx>) -> Vec<Constructor>
|
||||
{
|
||||
let check_inhabited = cx.tcx.sess.features.borrow().never_type;
|
||||
debug!("all_constructors({:?})", pcx.ty);
|
||||
match pcx.ty.sty {
|
||||
ty::TyBool =>
|
||||
[true, false].iter().map(|b| ConstantValue(ConstVal::Bool(*b))).collect(),
|
||||
ty::TySlice(ref sub_ty) => {
|
||||
if sub_ty.is_uninhabited_from(cx.module, cx.tcx) {
|
||||
if sub_ty.is_uninhabited_from(cx.module, cx.tcx)
|
||||
&& check_inhabited
|
||||
{
|
||||
vec![Slice(0)]
|
||||
} else {
|
||||
(0..pcx.max_slice_length+1).map(|length| Slice(length)).collect()
|
||||
}
|
||||
}
|
||||
ty::TyArray(ref sub_ty, length) => {
|
||||
if length == 0 || !sub_ty.is_uninhabited_from(cx.module, cx.tcx) {
|
||||
if length == 0 || !(sub_ty.is_uninhabited_from(cx.module, cx.tcx)
|
||||
&& check_inhabited)
|
||||
{
|
||||
vec![Slice(length)]
|
||||
} else {
|
||||
vec![]
|
||||
@ -403,7 +408,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
let forest = v.uninhabited_from(&mut visited,
|
||||
cx.tcx, substs,
|
||||
AdtKind::Enum);
|
||||
if forest.contains(cx.tcx, cx.module) {
|
||||
if forest.contains(cx.tcx, cx.module)
|
||||
&& check_inhabited
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(Variant(v.did))
|
||||
@ -411,7 +418,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||
}).collect()
|
||||
}
|
||||
_ => {
|
||||
if pcx.ty.is_uninhabited_from(cx.module, cx.tcx) {
|
||||
if pcx.ty.is_uninhabited_from(cx.module, cx.tcx)
|
||||
&& check_inhabited
|
||||
{
|
||||
vec![]
|
||||
} else {
|
||||
vec![Single]
|
||||
|
@ -99,20 +99,24 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
|
||||
let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| {
|
||||
i == variant_index || {
|
||||
let mut visited = FxHashSet::default();
|
||||
let node_set = v.uninhabited_from(&mut visited,
|
||||
self.hir.tcx(),
|
||||
substs,
|
||||
adt_def.adt_kind());
|
||||
!node_set.is_empty()
|
||||
if self.hir.tcx().sess.features.borrow().never_type {
|
||||
let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| {
|
||||
i == variant_index || {
|
||||
let mut visited = FxHashSet::default();
|
||||
let node_set = v.uninhabited_from(&mut visited,
|
||||
self.hir.tcx(),
|
||||
substs,
|
||||
adt_def.adt_kind());
|
||||
!node_set.is_empty()
|
||||
}
|
||||
});
|
||||
if irrefutable {
|
||||
let lvalue = match_pair.lvalue.downcast(adt_def, variant_index);
|
||||
candidate.match_pairs.extend(self.field_match_pairs(lvalue, subpatterns));
|
||||
Ok(())
|
||||
} else {
|
||||
Err(match_pair)
|
||||
}
|
||||
});
|
||||
if irrefutable {
|
||||
let lvalue = match_pair.lvalue.downcast(adt_def, variant_index);
|
||||
candidate.match_pairs.extend(self.field_match_pairs(lvalue, subpatterns));
|
||||
Ok(())
|
||||
} else {
|
||||
Err(match_pair)
|
||||
}
|
||||
|
50
src/test/compile-fail/uninhabited-matches-feature-gated.rs
Normal file
50
src/test/compile-fail/uninhabited-matches-feature-gated.rs
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(slice_patterns)]
|
||||
|
||||
enum Void {}
|
||||
|
||||
fn main() {
|
||||
let x: Result<u32, &'static Void> = Ok(23);
|
||||
let _ = match x { //~ ERROR non-exhaustive
|
||||
Ok(n) => n,
|
||||
};
|
||||
|
||||
let x: &Void = unsafe { std::mem::uninitialized() };
|
||||
let _ = match x {};
|
||||
//~^ ERROR non-exhaustive
|
||||
|
||||
let x: (Void,) = unsafe { std::mem::uninitialized() };
|
||||
let _ = match x {};
|
||||
//~^ ERROR non-exhaustive
|
||||
|
||||
let x: [Void; 1] = unsafe { std::mem::uninitialized() };
|
||||
let _ = match x {};
|
||||
//~^ ERROR non-exhaustive
|
||||
|
||||
let x: &[Void] = unsafe { std::mem::uninitialized() };
|
||||
let _ = match x { //~ ERROR non-exhaustive
|
||||
&[] => (),
|
||||
};
|
||||
|
||||
let x: Void = unsafe { std::mem::uninitialized() };
|
||||
let _ = match x {}; // okay
|
||||
|
||||
let x: Result<u32, Void> = Ok(23);
|
||||
let _ = match x { //~ ERROR non-exhaustive
|
||||
Ok(x) => x,
|
||||
};
|
||||
|
||||
let x: Result<u32, Void> = Ok(23);
|
||||
let Ok(x) = x;
|
||||
//~^ ERROR refutable
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
enum Void {}
|
||||
|
||||
fn main() {
|
||||
let x: Result<u32, &'static Void> = Ok(23);
|
||||
let _ = match x { //~ ERROR non-exhaustive
|
||||
Ok(n) => n,
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user