summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2018-12-13 20:53:07 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2018-12-13 20:53:07 +0000
commitcdd537339eb9fe009f75f285a99aa8257775e656 (patch)
tree48fb6e4892d598d7ebf61096b26ff8d6a2c27a99
parent8375ab4ff43474c73e3572c2b226560f8cc8e695 (diff)
downloadrust-borrowck-niche-discriminants.tar.gz
Make determining the discriminant a normal Shallow readborrowck-niche-discriminants
Enum layout optimizations mean that the discriminant of an enum may not be stored in a tag disjoint from the rest of the fields of the enum. Stop borrow checking as though they are.
-rw-r--r--src/librustc_mir/borrow_check/mod.rs9
-rw-r--r--src/librustc_mir/borrow_check/nll/invalidation.rs8
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs13
-rw-r--r--src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr33
-rw-r--r--src/test/ui/nll/match-on-borrowed.rs8
-rw-r--r--src/test/ui/nll/match-on-borrowed.stderr26
6 files changed, 73 insertions, 24 deletions
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index e3029c6a19d..5eca62938f7 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -545,7 +545,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
self.mutate_place(
ContextKind::SetDiscrim.new(location),
(place, span),
- Shallow(Some(ArtificialField::Discriminant)),
+ Shallow(None),
JustWrite,
flow_state,
);
@@ -782,7 +782,6 @@ use self::AccessDepth::{Deep, Shallow};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum ArtificialField {
- Discriminant,
ArrayLength,
ShallowBorrow,
}
@@ -1191,14 +1190,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => {
let af = match *rvalue {
- Rvalue::Len(..) => ArtificialField::ArrayLength,
- Rvalue::Discriminant(..) => ArtificialField::Discriminant,
+ Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
+ Rvalue::Discriminant(..) => None,
_ => unreachable!(),
};
self.access_place(
context,
(place, span),
- (Shallow(Some(af)), Read(ReadKind::Copy)),
+ (Shallow(af), Read(ReadKind::Copy)),
LocalMutationIsAllowed::No,
flow_state,
);
diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs
index 8af23a8813a..07bda8af626 100644
--- a/src/librustc_mir/borrow_check/nll/invalidation.rs
+++ b/src/librustc_mir/borrow_check/nll/invalidation.rs
@@ -99,7 +99,7 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
self.mutate_place(
ContextKind::SetDiscrim.new(location),
place,
- Shallow(Some(ArtificialField::Discriminant)),
+ Shallow(None),
JustWrite,
);
}
@@ -360,14 +360,14 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => {
let af = match *rvalue {
- Rvalue::Len(..) => ArtificialField::ArrayLength,
- Rvalue::Discriminant(..) => ArtificialField::Discriminant,
+ Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
+ Rvalue::Discriminant(..) => None,
_ => unreachable!(),
};
self.access_place(
context,
place,
- (Shallow(Some(af)), Read(ReadKind::Copy)),
+ (Shallow(af), Read(ReadKind::Copy)),
LocalMutationIsAllowed::No,
);
}
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index eeac915cff3..e24586cca09 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -165,15 +165,12 @@ fn place_components_conflict<'gcx, 'tcx>(
let base_ty = base.ty(mir, tcx).to_ty(tcx);
match (elem, &base_ty.sty, access) {
- (_, _, Shallow(Some(ArtificialField::Discriminant)))
- | (_, _, Shallow(Some(ArtificialField::ArrayLength)))
+ (_, _, Shallow(Some(ArtificialField::ArrayLength)))
| (_, _, Shallow(Some(ArtificialField::ShallowBorrow))) => {
- // The discriminant and array length are like
- // additional fields on the type; they do not
- // overlap any existing data there. Furthermore,
- // they cannot actually be a prefix of any
- // borrowed place (at least in MIR as it is
- // currently.)
+ // The array length is like additional fields on the
+ // type; it does not overlap any existing data there.
+ // Furthermore, if cannot actually be a prefix of any
+ // borrowed place (at least in MIR as it is currently.)
//
// e.g., a (mutable) borrow of `a[5]` while we read the
// array length of `a`.
diff --git a/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr b/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr
index 17722bf226d..6f72de0edee 100644
--- a/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr
@@ -1,3 +1,31 @@
+warning[E0503]: cannot use `y` because it was mutably borrowed
+ --> $DIR/borrowck-anon-fields-variant.rs:27:7
+ |
+LL | Foo::Y(ref mut a, _) => a,
+ | --------- borrow of `y.0` occurs here
+...
+LL | Foo::Y(_, ref mut b) => b,
+ | ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
+...
+LL | *a += 1;
+ | ------- borrow later used here
+ |
+ = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+ It represents potential unsoundness in your code.
+ This warning will become a hard error in the future.
+
+error[E0503]: cannot use `y` because it was mutably borrowed
+ --> $DIR/borrowck-anon-fields-variant.rs:44:7
+ |
+LL | Foo::Y(ref mut a, _) => a,
+ | --------- borrow of `y.0` occurs here
+...
+LL | Foo::Y(ref mut b, _) => b, //~ ERROR cannot borrow
+ | ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
+...
+LL | *a += 1;
+ | ------- borrow later used here
+
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-variant.rs:44:14
|
@@ -10,6 +38,7 @@ LL | Foo::Y(ref mut b, _) => b, //~ ERROR cannot borrow
LL | *a += 1;
| ------- first borrow later used here
-error: aborting due to previous error
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0499`.
+Some errors occurred: E0499, E0503.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/nll/match-on-borrowed.rs b/src/test/ui/nll/match-on-borrowed.rs
index 6a8ce03e8fd..edce2b185df 100644
--- a/src/test/ui/nll/match-on-borrowed.rs
+++ b/src/test/ui/nll/match-on-borrowed.rs
@@ -46,9 +46,9 @@ fn enum_example(mut e: E) {
E::V(ref mut x, _) => x,
E::W => panic!(),
};
- match e { // OK, no access of borrowed data
+ match e { // Don't know that E uses a tag for its discriminant
_ if false => (),
- E::V(_, r) => (),
+ E::V(_, r) => (), //~ ERROR
E::W => (),
}
x;
@@ -59,9 +59,9 @@ fn indirect_enum_example(mut f: &mut E) {
E::V(ref mut x, _) => x,
E::W => panic!(),
};
- match f { // OK, no access of borrowed data
+ match f { // Don't know that E uses a tag for its discriminant
_ if false => (),
- E::V(_, r) => (),
+ E::V(_, r) => (), //~ ERROR
E::W => (),
}
x;
diff --git a/src/test/ui/nll/match-on-borrowed.stderr b/src/test/ui/nll/match-on-borrowed.stderr
index cdff29d44b8..2d34dd7805d 100644
--- a/src/test/ui/nll/match-on-borrowed.stderr
+++ b/src/test/ui/nll/match-on-borrowed.stderr
@@ -1,3 +1,27 @@
+error[E0503]: cannot use `e` because it was mutably borrowed
+ --> $DIR/match-on-borrowed.rs:51:9
+ |
+LL | E::V(ref mut x, _) => x,
+ | --------- borrow of `e.0` occurs here
+...
+LL | E::V(_, r) => (), //~ ERROR
+ | ^^^^^^^^^^ use of borrowed `e.0`
+...
+LL | x;
+ | - borrow later used here
+
+error[E0503]: cannot use `*f` because it was mutably borrowed
+ --> $DIR/match-on-borrowed.rs:64:9
+ |
+LL | E::V(ref mut x, _) => x,
+ | --------- borrow of `f.0` occurs here
+...
+LL | E::V(_, r) => (), //~ ERROR
+ | ^^^^^^^^^^ use of borrowed `f.0`
+...
+LL | x;
+ | - borrow later used here
+
error[E0503]: cannot use `t` because it was mutably borrowed
--> $DIR/match-on-borrowed.rs:82:9
|
@@ -16,7 +40,7 @@ error[E0381]: use of possibly uninitialized variable: `n`
LL | match n {} //~ ERROR
| ^ use of possibly uninitialized `n`
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
Some errors occurred: E0381, E0503.
For more information about an error, try `rustc --explain E0381`.