Hide uninhabitedness checks behind feature gate

This commit is contained in:
Andrew Cann 2017-01-25 14:48:20 +08:00
parent c0d0e68be4
commit 2b7a23ed30
5 changed files with 81 additions and 41 deletions

View File

@ -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(),

View File

@ -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]

View File

@ -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)
}

View 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
}

View File

@ -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,
};
}