blob: c814c328d836dab575df08a730a01465849028f6 [file]
//@ run-pass
#![feature(trivial_clone)]
use std::cell::Cell;
use std::clone::TrivialClone;
#[derive(Clone)]
struct DropCounter<'a>(&'a Cell<i32>);
unsafe impl<'a> TrivialClone for DropCounter<'a> {}
impl Drop for DropCounter<'_> {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}
struct CloneCounter<'a> {
clones: &'a Cell<i32>,
drops: &'a Cell<i32>,
}
impl<'a> CloneCounter<'a> {
fn new(clones: &'a Cell<i32>, drops: &'a Cell<i32>) -> Self {
Self { clones, drops }
}
}
impl<'a> Clone for CloneCounter<'a> {
fn clone(&self) -> Self {
self.clones.set(self.clones.get() + 1);
Self::new(self.clones, self.drops)
}
}
impl<'a> Drop for CloneCounter<'a> {
fn drop(&mut self) {
self.drops.set(self.drops.get() + 1);
}
}
fn main() {
// TrivialClone
let c = Cell::new(0);
let mut vec = vec![DropCounter(&c); 3];
vec.clear();
assert_eq!(c.get(), 3);
vec = vec![DropCounter(&c); 6];
vec.clear();
assert_eq!(c.get(), 9);
vec = vec![DropCounter(&c); 0];
assert_eq!(c.get(), 10);
vec.clear();
assert_eq!(c.get(), 10);
// nontrivial clone
let clones = Cell::new(0);
let drops = Cell::new(0);
let mut vec = vec![CloneCounter::new(&clones, &drops); 3];
assert_eq!(clones.get(), 2);
assert_eq!(drops.get(), 0);
vec.clear();
assert_eq!(clones.get(), 2);
assert_eq!(drops.get(), 3);
vec = vec![CloneCounter::new(&clones, &drops); 6];
assert_eq!(clones.get(), 7);
assert_eq!(drops.get(), 3);
vec.clear();
assert_eq!(clones.get(), 7);
assert_eq!(drops.get(), 9);
vec = vec![CloneCounter::new(&clones, &drops); 0];
assert_eq!(clones.get(), 7);
assert_eq!(drops.get(), 10);
vec.clear();
assert_eq!(clones.get(), 7);
assert_eq!(drops.get(), 10);
}