Handle non_exhaustive in borrow checking

This commit is contained in:
Matthew Jasper 2019-11-24 22:39:05 +00:00
parent 5a1d028d4c
commit 294f7e4790
5 changed files with 84 additions and 1 deletions

View file

@ -164,7 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.hir.tcx().features().exhaustive_patterns &&
!v.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()).is_empty()
}
});
}) && (adt_def.did.is_local() || !adt_def.is_variant_list_non_exhaustive());
if irrefutable {
let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index);
candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns));

View file

@ -0,0 +1,8 @@
#[non_exhaustive]
pub enum NonExhaustiveMonovariant {
Variant(u32),
}
pub enum ExhaustiveMonovariant {
Variant(u32),
}

View file

@ -0,0 +1,42 @@
// Test that the borrow checker doesn't consider checking an exhaustive pattern
// as an access.
// check-pass
// aux-build:monovariants.rs
extern crate monovariants;
use monovariants::ExhaustiveMonovariant;
enum Local {
Variant(u32),
}
#[non_exhaustive]
enum LocalNonExhaustive {
Variant(u32),
}
fn main() {
let mut x = ExhaustiveMonovariant::Variant(1);
let y = &mut x;
match x {
ExhaustiveMonovariant::Variant(_) => {},
_ => {},
}
drop(y);
let mut x = Local::Variant(1);
let y = &mut x;
match x {
Local::Variant(_) => {},
_ => {},
}
drop(y);
let mut x = LocalNonExhaustive::Variant(1);
let y = &mut x;
match x {
LocalNonExhaustive::Variant(_) => {},
_ => {},
}
drop(y);
}

View file

@ -0,0 +1,18 @@
// Test that the borrow checker considers `#[non_exhaustive]` when checking
// whether a match contains a discriminant read.
// aux-build:monovariants.rs
extern crate monovariants;
use monovariants::NonExhaustiveMonovariant;
fn main() {
let mut x = NonExhaustiveMonovariant::Variant(1);
let y = &mut x;
match x {
NonExhaustiveMonovariant::Variant(_) => {},
//~^ ERROR cannot use `x` because it was mutably borrowed
_ => {},
}
drop(y);
}

View file

@ -0,0 +1,15 @@
error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-non-exhaustive.rs:13:9
|
LL | let y = &mut x;
| ------ borrow of `x` occurs here
LL | match x {
LL | NonExhaustiveMonovariant::Variant(_) => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of borrowed `x`
...
LL | drop(y);
| - borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0503`.