diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-07-27 01:33:01 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-07-27 18:56:16 +0300 |
| commit | 9be35f82c1abf2ecbab489bca9eca138ea648312 (patch) | |
| tree | 69888506e34af447d9748c0d542de3ba1dd76210 /src/test/ui/borrowck | |
| parent | ca9faa52f5ada0054b1fa27d97aedf448afb059b (diff) | |
| download | rust-9be35f82c1abf2ecbab489bca9eca138ea648312.tar.gz rust-9be35f82c1abf2ecbab489bca9eca138ea648312.zip | |
tests: Move run-pass tests without naming conflicts to ui
Diffstat (limited to 'src/test/ui/borrowck')
29 files changed, 709 insertions, 0 deletions
diff --git a/src/test/ui/borrowck/borrowck-assign-to-subfield.rs b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs new file mode 100644 index 00000000000..050d702b625 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs @@ -0,0 +1,23 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + struct A { + a: isize, + w: B, + } + struct B { + a: isize + } + let mut p = A { + a: 1, + w: B {a: 1}, + }; + + // even though `x` is not declared as a mutable field, + // `p` as a whole is mutable, so it can be modified. + p.a = 2; + + // this is true for an interior field too + p.w.a = 2; +} diff --git a/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs b/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs new file mode 100644 index 00000000000..72bf43da95e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// Test taken from #45641 (https://github.com/rust-lang/rust/issues/45641) + +static mut Y: u32 = 0; + +unsafe fn should_ok() { + Y = 1; +} + +fn main() {} diff --git a/src/test/ui/borrowck/borrowck-binding-mutbl.rs b/src/test/ui/borrowck/borrowck-binding-mutbl.rs new file mode 100644 index 00000000000..c2d2e02ec15 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-binding-mutbl.rs @@ -0,0 +1,16 @@ +// run-pass + +struct F { f: Vec<isize> } + +fn impure(_v: &[isize]) { +} + +pub fn main() { + let mut x = F {f: vec![3]}; + + match x { + F {f: ref mut v} => { + impure(v); + } + } +} diff --git a/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs b/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs new file mode 100644 index 00000000000..15c6e8bf210 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(box_syntax)] + +fn borrow<F>(x: &isize, f: F) where F: FnOnce(&isize) { + f(x) +} + +fn test1(x: &Box<isize>) { + borrow(&*(*x).clone(), |p| { + let x_a = &**x as *const isize; + assert!((x_a as usize) != (p as *const isize as usize)); + assert_eq!(unsafe{*x_a}, *p); + }) +} + +pub fn main() { + test1(&box 22); +} diff --git a/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs new file mode 100644 index 00000000000..2839a9195a0 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_variables)] +// Test that freezing an `&mut` pointer while referent is +// frozen is legal. +// +// Example from src/librustc_borrowck/borrowck/README.md + +// pretty-expanded FIXME #23616 + +fn foo<'a>(mut t0: &'a mut isize, + mut t1: &'a mut isize) { + let p: &isize = &*t0; // Freezes `*t0` + let mut t2 = &t0; + let q: &isize = &**t2; // Freezes `*t0`, but that's ok... + let r: &isize = &*t0; // ...after all, could do same thing directly. +} + +pub fn main() { +} diff --git a/src/test/ui/borrowck/borrowck-closures-two-imm.rs b/src/test/ui/borrowck/borrowck-closures-two-imm.rs new file mode 100644 index 00000000000..ab135194a09 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-closures-two-imm.rs @@ -0,0 +1,41 @@ +// run-pass +// Tests that two closures can simultaneously have immutable +// access to the variable, whether that immutable access be used +// for direct reads or for taking immutable ref. Also check +// that the main function can read the variable too while +// the closures are in scope. Issue #6801. + + +fn a() -> i32 { + let mut x = 3; + x += 1; + let c1 = || x * 4; + let c2 = || x * 5; + c1() * c2() * x +} + +fn get(x: &i32) -> i32 { + *x * 4 +} + +fn b() -> i32 { + let mut x = 3; + x += 1; + let c1 = || get(&x); + let c2 = || get(&x); + c1() * c2() * x +} + +fn c() -> i32 { + let mut x = 3; + x += 1; + let c1 = || x * 5; + let c2 = || get(&x); + c1() * c2() * x +} + +pub fn main() { + assert_eq!(a(), 1280); + assert_eq!(b(), 1024); + assert_eq!(c(), 1280); +} diff --git a/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs b/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs new file mode 100644 index 00000000000..126323d8d24 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x = [22]; + let y = &x[0]; + assert_eq!(*y, 22); +} diff --git a/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs b/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs new file mode 100644 index 00000000000..199931d6d1e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs @@ -0,0 +1,28 @@ +// run-pass +// Test that a `&mut` inside of an `&` is freezable. + + +struct MutSlice<'a, T:'a> { + data: &'a mut [T] +} + +fn get<'a, T>(ms: &'a MutSlice<'a, T>, index: usize) -> &'a T { + &ms.data[index] +} + +pub fn main() { + let mut data = [1, 2, 3]; + { + let slice = MutSlice { data: &mut data }; + slice.data[0] += 4; + let index0 = get(&slice, 0); + let index1 = get(&slice, 1); + let index2 = get(&slice, 2); + assert_eq!(*index0, 5); + assert_eq!(*index1, 2); + assert_eq!(*index2, 3); + } + assert_eq!(data[0], 5); + assert_eq!(data[1], 2); + assert_eq!(data[2], 3); +} diff --git a/src/test/ui/borrowck/borrowck-lend-args.rs b/src/test/ui/borrowck/borrowck-lend-args.rs new file mode 100644 index 00000000000..d0ef2dcdd28 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-lend-args.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +fn borrow(_v: &isize) {} + +fn borrow_from_arg_imm_ref(v: Box<isize>) { + borrow(&*v); +} + +fn borrow_from_arg_mut_ref(v: &mut Box<isize>) { + borrow(&**v); +} + +fn borrow_from_arg_copy(v: Box<isize>) { + borrow(&*v); +} + +pub fn main() { +} diff --git a/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs b/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs new file mode 100644 index 00000000000..628e49f574c --- /dev/null +++ b/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unconditional_recursion)] + +// Check that we do not ICE when compiling this +// macro, which reuses the expression `$id` + + +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct Foo { + a: isize +} + +pub enum Bar { + Bar1, Bar2(isize, Box<Bar>), +} + +impl Foo { + fn elaborate_stm(&mut self, s: Box<Bar>) -> Box<Bar> { + macro_rules! declare { + ($id:expr, $rest:expr) => ({ + self.check_id($id); + box Bar::Bar2($id, $rest) + }) + } + match s { + box Bar::Bar2(id, rest) => declare!(id, self.elaborate_stm(rest)), + _ => panic!() + } + } + + fn check_id(&mut self, s: isize) { panic!() } +} + +pub fn main() { } diff --git a/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs b/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs new file mode 100644 index 00000000000..98e4b881893 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let bar: Box<_> = box 3; + let h = || -> isize { *bar }; + assert_eq!(h(), 3); +} diff --git a/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs new file mode 100644 index 00000000000..96d2663500e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test case from #39963. + +#[derive(Clone)] +struct Foo(Option<Box<Foo>>, Option<Box<Foo>>); + +fn test(f: &mut Foo) { + match *f { + Foo(Some(ref mut left), Some(ref mut right)) => match **left { + Foo(Some(ref mut left), Some(ref mut right)) => panic!(), + _ => panic!(), + }, + _ => panic!(), + } +} + +fn main() { +} diff --git a/src/test/ui/borrowck/borrowck-mut-uniq.rs b/src/test/ui/borrowck/borrowck-mut-uniq.rs new file mode 100644 index 00000000000..80b3484e0fb --- /dev/null +++ b/src/test/ui/borrowck/borrowck-mut-uniq.rs @@ -0,0 +1,33 @@ +// run-pass +#![feature(box_syntax)] + +use std::mem::swap; + +#[derive(Debug)] +struct Ints {sum: Box<isize>, values: Vec<isize> } + +fn add_int(x: &mut Ints, v: isize) { + *x.sum += v; + let mut values = Vec::new(); + swap(&mut values, &mut x.values); + values.push(v); + swap(&mut values, &mut x.values); +} + +fn iter_ints<F>(x: &Ints, mut f: F) -> bool where F: FnMut(&isize) -> bool { + let l = x.values.len(); + (0..l).all(|i| f(&x.values[i])) +} + +pub fn main() { + let mut ints: Box<_> = box Ints {sum: box 0, values: Vec::new()}; + add_int(&mut *ints, 22); + add_int(&mut *ints, 44); + + iter_ints(&*ints, |i| { + println!("isize = {:?}", *i); + true + }); + + println!("ints={:?}", ints); +} diff --git a/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs b/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs new file mode 100644 index 00000000000..d2b0c01545e --- /dev/null +++ b/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs @@ -0,0 +1,16 @@ +// run-pass + + +fn want_slice(v: &[isize]) -> isize { + let mut sum = 0; + for i in v { sum += *i; } + sum +} + +fn has_mut_vec(v: Vec<isize> ) -> isize { + want_slice(&v) +} + +pub fn main() { + assert_eq!(has_mut_vec(vec![1, 2, 3]), 6); +} diff --git a/src/test/ui/borrowck/borrowck-pat-enum.rs b/src/test/ui/borrowck/borrowck-pat-enum.rs new file mode 100644 index 00000000000..7f9c5544d0b --- /dev/null +++ b/src/test/ui/borrowck/borrowck-pat-enum.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(dead_code)] +// ignore-pretty issue #37199 + +fn match_ref(v: Option<isize>) -> isize { + match v { + Some(ref i) => { + *i + } + None => {0} + } +} + +fn match_ref_unused(v: Option<isize>) { + match v { + Some(_) => {} + None => {} + } +} + +fn impure(_i: isize) { +} + +fn match_imm_reg(v: &Option<isize>) { + match *v { + Some(ref i) => {impure(*i)} // OK because immutable + None => {} + } +} + +fn match_mut_reg(v: &mut Option<isize>) { + match *v { + Some(ref i) => {impure(*i)} // OK, frozen + None => {} + } +} + +pub fn main() { +} diff --git a/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs b/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs new file mode 100644 index 00000000000..1362fd8ce4c --- /dev/null +++ b/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs @@ -0,0 +1,14 @@ +// run-pass + +pub fn main() { + let mut x = None; + match x { + None => { + // It is ok to reassign x here, because there is in + // fact no outstanding loan of x! + x = Some(0); + } + Some(_) => { } + } + assert_eq!(x, Some(0)); +} diff --git a/src/test/ui/borrowck/borrowck-rvalues-mutable.rs b/src/test/ui/borrowck/borrowck-rvalues-mutable.rs new file mode 100644 index 00000000000..c4695c942e1 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-rvalues-mutable.rs @@ -0,0 +1,34 @@ +// run-pass + +struct Counter { + value: usize +} + +impl Counter { + fn new(v: usize) -> Counter { + Counter {value: v} + } + + fn inc<'a>(&'a mut self) -> &'a mut Counter { + self.value += 1; + self + } + + fn get(&self) -> usize { + self.value + } + + fn get_and_inc(&mut self) -> usize { + let v = self.value; + self.value += 1; + v + } +} + +pub fn main() { + let v = Counter::new(22).get_and_inc(); + assert_eq!(v, 22); + + let v = Counter::new(22).inc().inc().get(); + assert_eq!(v, 24); +} diff --git a/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs b/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs new file mode 100644 index 00000000000..e89332ae31a --- /dev/null +++ b/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs @@ -0,0 +1,42 @@ +// run-pass +// Tests that the scope of the pointer returned from `get()` is +// limited to the deref operation itself, and does not infect the +// block as a whole. + + +struct Box { + x: usize +} + +impl Box { + fn get(&self) -> &usize { + &self.x + } + fn set(&mut self, x: usize) { + self.x = x; + } +} + +fn fun1() { + // in the past, borrow checker behaved differently when + // init and decl of `v` were distinct + let v; + let mut a_box = Box {x: 0}; + a_box.set(22); + v = *a_box.get(); + a_box.set(v+1); + assert_eq!(23, *a_box.get()); +} + +fn fun2() { + let mut a_box = Box {x: 0}; + a_box.set(22); + let v = *a_box.get(); + a_box.set(v+1); + assert_eq!(23, *a_box.get()); +} + +pub fn main() { + fun1(); + fun2(); +} diff --git a/src/test/ui/borrowck/borrowck-static-item-in-fn.rs b/src/test/ui/borrowck/borrowck-static-item-in-fn.rs new file mode 100644 index 00000000000..5f4379325a5 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-static-item-in-fn.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(dead_code)] +// Regression test for issue #7740 + +// pretty-expanded FIXME #23616 + +pub fn main() { + static A: &'static char = &'A'; +} diff --git a/src/test/ui/borrowck/borrowck-trait-lifetime.rs b/src/test/ui/borrowck/borrowck-trait-lifetime.rs new file mode 100644 index 00000000000..8a6dfe76d60 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-trait-lifetime.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_imports)] +// This test verifies that casting from the same lifetime on a value +// to the same lifetime on a trait succeeds. See issue #10766. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +use std::marker; + +fn main() { + trait T { fn foo(&self) {} } + + fn f<'a, V: T>(v: &'a V) -> &'a dyn T { + v as &'a dyn T + } +} diff --git a/src/test/ui/borrowck/borrowck-uniq-via-ref.rs b/src/test/ui/borrowck/borrowck-uniq-via-ref.rs new file mode 100644 index 00000000000..bdf7cc57a53 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-uniq-via-ref.rs @@ -0,0 +1,49 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +struct Rec { + f: Box<isize>, +} + +struct Outer { + f: Inner +} + +struct Inner { + g: Innermost +} + +struct Innermost { + h: Box<isize>, +} + +fn borrow(_v: &isize) {} + +fn box_mut(v: &mut Box<isize>) { + borrow(&**v); // OK: &mut -> &imm +} + +fn box_mut_rec(v: &mut Rec) { + borrow(&*v.f); // OK: &mut -> &imm +} + +fn box_mut_recs(v: &mut Outer) { + borrow(&*v.f.g.h); // OK: &mut -> &imm +} + +fn box_imm(v: &Box<isize>) { + borrow(&**v); // OK +} + +fn box_imm_rec(v: &Rec) { + borrow(&*v.f); // OK +} + +fn box_imm_recs(v: &Outer) { + borrow(&*v.f.g.h); // OK +} + +pub fn main() { +} diff --git a/src/test/ui/borrowck/borrowck-univariant-enum.rs b/src/test/ui/borrowck/borrowck-univariant-enum.rs new file mode 100644 index 00000000000..c78e9475233 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-univariant-enum.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::cell::Cell; + +#[derive(Copy, Clone)] +enum newtype { + newvar(isize) +} + +pub fn main() { + + // Test that borrowck treats enums with a single variant + // specially. + + let x = &Cell::new(5); + let y = &Cell::new(newtype::newvar(3)); + let z = match y.get() { + newtype::newvar(b) => { + x.set(x.get() + 1); + x.get() * b + } + }; + assert_eq!(z, 18); +} diff --git a/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs new file mode 100644 index 00000000000..adc7dfd541f --- /dev/null +++ b/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs @@ -0,0 +1,20 @@ +// run-pass + +// Test file taken from issue 45129 (https://github.com/rust-lang/rust/issues/45129) + +struct Foo { x: [usize; 2] } + +static mut SFOO: Foo = Foo { x: [23, 32] }; + +impl Foo { + fn x(&mut self) -> &mut usize { &mut self.x[0] } +} + +fn main() { + unsafe { + let sfoo: *mut Foo = &mut SFOO; + let x = (*sfoo).x(); + (*sfoo).x[1] += 1; + *x += 1; + } +} diff --git a/src/test/ui/borrowck/borrowck-unused-mut-locals.rs b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs new file mode 100644 index 00000000000..fd0e346e2b4 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs @@ -0,0 +1,46 @@ +// run-pass +#![deny(unused_mut)] + +#[derive(Debug)] +struct A {} + +fn init_a() -> A { + A {} +} + +#[derive(Debug)] +struct B<'a> { + ed: &'a mut A, +} + +fn init_b<'a>(ed: &'a mut A) -> B<'a> { + B { ed } +} + +#[derive(Debug)] +struct C<'a> { + pd: &'a mut B<'a>, +} + +fn init_c<'a>(pd: &'a mut B<'a>) -> C<'a> { + C { pd } +} + +#[derive(Debug)] +struct D<'a> { + sd: &'a mut C<'a>, +} + +fn init_d<'a>(sd: &'a mut C<'a>) -> D<'a> { + D { sd } +} + +fn main() { + let mut a = init_a(); + let mut b = init_b(&mut a); + let mut c = init_c(&mut b); + + let d = init_d(&mut c); + + println!("{:?}", d) +} diff --git a/src/test/ui/borrowck/issue-62007-assign-box.rs b/src/test/ui/borrowck/issue-62007-assign-box.rs new file mode 100644 index 00000000000..f6fbea821b5 --- /dev/null +++ b/src/test/ui/borrowck/issue-62007-assign-box.rs @@ -0,0 +1,27 @@ +// run-pass + +// Issue #62007: assigning over a deref projection of a box (in this +// case, `*list = n;`) should be able to kill all borrows of `*list`, +// so that `*list` can be borrowed on the next iteration through the +// loop. + +#![allow(dead_code)] + +struct List<T> { + value: T, + next: Option<Box<List<T>>>, +} + +fn to_refs<T>(mut list: Box<&mut List<T>>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + *list = n; + } else { + return result; + } + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-62007-assign-field.rs b/src/test/ui/borrowck/issue-62007-assign-field.rs new file mode 100644 index 00000000000..5b21c083816 --- /dev/null +++ b/src/test/ui/borrowck/issue-62007-assign-field.rs @@ -0,0 +1,26 @@ +// run-pass + +// Issue #62007: assigning over a field projection (`list.0 = n;` in +// this case) should be able to kill all borrows of `list.0`, so that +// `list.0` can be borrowed on the next iteration through the loop. + +#![allow(dead_code)] + +struct List<T> { + value: T, + next: Option<Box<List<T>>>, +} + +fn to_refs<T>(mut list: (&mut List<T>,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut (list.0).value); + if let Some(n) = (list.0).next.as_mut() { + list.0 = n; + } else { + return result; + } + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/two-phase-baseline.rs b/src/test/ui/borrowck/two-phase-baseline.rs new file mode 100644 index 00000000000..994dc823dfc --- /dev/null +++ b/src/test/ui/borrowck/two-phase-baseline.rs @@ -0,0 +1,9 @@ +// run-pass + +// This is the "goto example" for why we want two phase borrows. + +fn main() { + let mut v = vec![0, 1, 2]; + v.push(v.len()); + assert_eq!(v, [0, 1, 2, 3]); +} diff --git a/src/test/ui/borrowck/two-phase-bin-ops.rs b/src/test/ui/borrowck/two-phase-bin-ops.rs new file mode 100644 index 00000000000..1242ae307d3 --- /dev/null +++ b/src/test/ui/borrowck/two-phase-bin-ops.rs @@ -0,0 +1,35 @@ +// run-pass +use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; +use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign}; + +struct A(i32); + +macro_rules! trivial_binop { + ($Trait:ident, $m:ident) => { + impl $Trait<i32> for A { fn $m(&mut self, rhs: i32) { self.0 = rhs; } } + } +} + +trivial_binop!(AddAssign, add_assign); +trivial_binop!(SubAssign, sub_assign); +trivial_binop!(MulAssign, mul_assign); +trivial_binop!(DivAssign, div_assign); +trivial_binop!(RemAssign, rem_assign); +trivial_binop!(BitAndAssign, bitand_assign); +trivial_binop!(BitOrAssign, bitor_assign); +trivial_binop!(BitXorAssign, bitxor_assign); +trivial_binop!(ShlAssign, shl_assign); +trivial_binop!(ShrAssign, shr_assign); + +fn main() { + let mut a = A(10); + a += a.0; + a -= a.0; + a *= a.0; + a /= a.0; + a &= a.0; + a |= a.0; + a ^= a.0; + a <<= a.0; + a >>= a.0; +} diff --git a/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs b/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs new file mode 100644 index 00000000000..0b20e1945e6 --- /dev/null +++ b/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs @@ -0,0 +1,15 @@ +// run-pass + +fn main() { + let mut a = 0; + let mut b = 0; + let p = if maybe() { + &mut a + } else { + &mut b + }; + use_(p); +} + +fn maybe() -> bool { false } +fn use_<T>(_: T) { } |
