Handle non_exhaustive in borrow checking
This commit is contained in:
parent
5a1d028d4c
commit
294f7e4790
5 changed files with 84 additions and 1 deletions
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#[non_exhaustive]
|
||||
pub enum NonExhaustiveMonovariant {
|
||||
Variant(u32),
|
||||
}
|
||||
|
||||
pub enum ExhaustiveMonovariant {
|
||||
Variant(u32),
|
||||
}
|
||||
42
src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
Normal file
42
src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue