Skip to content

Commit 7eda5b5

Browse files
committed
Added tests illustrating when and when not to use the UGEH attribute w.r.t. a lifetime param.
1 parent e2e261f commit 7eda5b5

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Demonstrate that having a lifetime param causes dropck to reject code
12+
// that might indirectly access previously dropped value.
13+
//
14+
// Compare with run-pass/issue28498-ugeh-with-lifetime-param.rs
15+
16+
#[derive(Debug)]
17+
struct ScribbleOnDrop(String);
18+
19+
impl Drop for ScribbleOnDrop {
20+
fn drop(&mut self) {
21+
self.0 = format!("DROPPED");
22+
}
23+
}
24+
25+
struct Foo<'a>(u32, &'a ScribbleOnDrop);
26+
27+
impl<'a> Drop for Foo<'a> {
28+
fn drop(&mut self) {
29+
// Use of `unsafe_destructor_blind_to_params` is unsound,
30+
// because destructor accesses borrowed data in `self.1`
31+
// and we must force that to strictly outlive `self`.
32+
println!("Dropping Foo({}, {:?})", self.0, self.1);
33+
}
34+
}
35+
36+
fn main() {
37+
let (last_dropped, foo0);
38+
let (foo1, first_dropped);
39+
40+
last_dropped = ScribbleOnDrop(format!("last"));
41+
first_dropped = ScribbleOnDrop(format!("first"));
42+
foo0 = Foo(0, &last_dropped);
43+
//~^ ERROR `last_dropped` does not live long enough
44+
foo1 = Foo(1, &first_dropped);
45+
//~^ ERROR `first_dropped` does not live long enough
46+
47+
println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Demonstrate the use of the unguarded escape hatch with a lifetime param
12+
// to assert that destructor will not access any dead data.
13+
//
14+
// Compare with compile-fail/issue28498-reject-lifetime-param.rs
15+
16+
#![feature(dropck_parametricity)]
17+
18+
#[derive(Debug)]
19+
struct ScribbleOnDrop(String);
20+
21+
impl Drop for ScribbleOnDrop {
22+
fn drop(&mut self) {
23+
self.0 = format!("DROPPED");
24+
}
25+
}
26+
27+
struct Foo<'a>(u32, &'a ScribbleOnDrop);
28+
29+
impl<'a> Drop for Foo<'a> {
30+
#[unsafe_destructor_blind_to_params]
31+
fn drop(&mut self) {
32+
// Use of `unsafe_destructor_blind_to_params` is sound,
33+
// because destructor never accesses `self.1`.
34+
println!("Dropping Foo({}, _)", self.0);
35+
}
36+
}
37+
38+
fn main() {
39+
let (last_dropped, foo0);
40+
let (foo1, first_dropped);
41+
42+
last_dropped = ScribbleOnDrop(format!("last"));
43+
first_dropped = ScribbleOnDrop(format!("first"));
44+
foo0 = Foo(0, &last_dropped);
45+
foo1 = Foo(1, &first_dropped);
46+
47+
println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
48+
}

0 commit comments

Comments
 (0)