Skip to content

Commit e323548

Browse files
bors[bot]taiki-e
andauthored
Merge #212
212: Add test for project_replace on panic r=taiki-e a=taiki-e Refs: * rust-lang/rust#47949 * #194 (comment) Co-authored-by: Taiki Endo <te316e89@gmail.com>
2 parents 4b48996 + baa9b0e commit e323548

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

tests/pin_project.rs

+55
Original file line numberDiff line numberDiff line change
@@ -688,3 +688,58 @@ fn no_infer_outlives() {
688688
_x: <Example<A> as Bar<B>>::Y,
689689
}
690690
}
691+
692+
// https://github.com/rust-lang/rust/issues/47949
693+
// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111
694+
#[test]
695+
fn project_replace_panic() {
696+
use std::panic;
697+
698+
#[pin_project(Replace)]
699+
struct S<T, U> {
700+
#[pin]
701+
pinned: T,
702+
unpinned: U,
703+
}
704+
705+
struct D<'a>(&'a mut bool, bool);
706+
impl Drop for D<'_> {
707+
fn drop(&mut self) {
708+
*self.0 = true;
709+
if self.1 {
710+
panic!()
711+
}
712+
}
713+
}
714+
715+
let (mut a, mut b, mut c, mut d) = (false, false, false, false);
716+
let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
717+
let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) };
718+
let _y = Pin::new(&mut x)
719+
.project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
720+
// Previous `x.pinned` was dropped and panicked when `project_replace` is called, so this is unreachable.
721+
unreachable!();
722+
}));
723+
assert!(res.is_err());
724+
assert!(a);
725+
assert!(b);
726+
assert!(c);
727+
assert!(d);
728+
729+
let (mut a, mut b, mut c, mut d) = (false, false, false, false);
730+
let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
731+
let mut x = S { pinned: D(&mut a, false), unpinned: D(&mut b, true) };
732+
{
733+
let _y = Pin::new(&mut x)
734+
.project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
735+
// `_y` (previous `x.unpinned`) live to the end of this scope, so this is not unreachable,
736+
// unreachable!();
737+
}
738+
unreachable!();
739+
}));
740+
assert!(res.is_err());
741+
assert!(a);
742+
assert!(b);
743+
assert!(c);
744+
assert!(d);
745+
}

0 commit comments

Comments
 (0)