From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/borrowck/fsu-moves-and-copies.rs | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/test/ui/borrowck/fsu-moves-and-copies.rs (limited to 'src/test/ui/borrowck/fsu-moves-and-copies.rs') diff --git a/src/test/ui/borrowck/fsu-moves-and-copies.rs b/src/test/ui/borrowck/fsu-moves-and-copies.rs new file mode 100644 index 000000000..85e0a840a --- /dev/null +++ b/src/test/ui/borrowck/fsu-moves-and-copies.rs @@ -0,0 +1,95 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(stable_features)] +// Issue 4691: Ensure that functional-struct-updates operates +// correctly and moves rather than copy when appropriate. + +#![feature(core)] + +struct ncint { v: isize } +fn ncint(v: isize) -> ncint { ncint { v: v } } + +struct NoFoo { copied: isize, nocopy: ncint, } +impl NoFoo { + fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } } +} + +struct MoveFoo { copied: isize, moved: Box, } +impl MoveFoo { + fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: Box::new(y) } } +} + +struct DropNoFoo { inner: NoFoo } +impl DropNoFoo { + fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } } +} +impl Drop for DropNoFoo { fn drop(&mut self) { } } + +struct DropMoveFoo { inner: MoveFoo } +impl DropMoveFoo { + fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } } +} +impl Drop for DropMoveFoo { fn drop(&mut self) { } } + + +fn test0() { + // just copy implicitly copyable fields from `f`, no moves + // (and thus it is okay that these are Drop; compare against + // test ui/borrowck/borrowck-struct-update-with-dtor.rs). + + // Case 1: Nocopyable + let f = DropNoFoo::new(1, 2); + let b = DropNoFoo { inner: NoFoo { nocopy: ncint(3), ..f.inner }}; + let c = DropNoFoo { inner: NoFoo { nocopy: ncint(4), ..f.inner }}; + assert_eq!(f.inner.copied, 1); + assert_eq!(f.inner.nocopy.v, 2); + + assert_eq!(b.inner.copied, 1); + assert_eq!(b.inner.nocopy.v, 3); + + assert_eq!(c.inner.copied, 1); + assert_eq!(c.inner.nocopy.v, 4); + + // Case 2: Owned + let f = DropMoveFoo::new(5, 6); + let b = DropMoveFoo { inner: MoveFoo { moved: Box::new(7), ..f.inner }}; + let c = DropMoveFoo { inner: MoveFoo { moved: Box::new(8), ..f.inner }}; + assert_eq!(f.inner.copied, 5); + assert_eq!(*f.inner.moved, 6); + + assert_eq!(b.inner.copied, 5); + assert_eq!(*b.inner.moved, 7); + + assert_eq!(c.inner.copied, 5); + assert_eq!(*c.inner.moved, 8); +} + +fn test1() { + // copying move-by-default fields from `f`, so it moves: + let f = MoveFoo::new(11, 12); + + let b = MoveFoo {moved: Box::new(13), ..f}; + let c = MoveFoo {copied: 14, ..f}; + assert_eq!(b.copied, 11); + assert_eq!(*b.moved, 13); + assert_eq!(c.copied, 14); + assert_eq!(*c.moved, 12); +} + +fn test2() { + // move non-copyable field + let f = NoFoo::new(21, 22); + let b = NoFoo {nocopy: ncint(23), ..f}; + let c = NoFoo {copied: 24, ..f}; + assert_eq!(b.copied, 21); + assert_eq!(b.nocopy.v, 23); + assert_eq!(c.copied, 24); + assert_eq!(c.nocopy.v, 22); +} + +pub fn main() { + test0(); + test1(); + test2(); +} -- cgit v1.2.3