Skip to content

Commit e2e261f

Browse files
committed
Added tests illustrating when and when not to use the UGEH attribute w.r.t. a trait bound.
1 parent 92da3f9 commit e2e261f

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 trait bound causes dropck to reject code
12+
// that might indirectly access previously dropped value.
13+
//
14+
// Compare with run-pass/issue28498-ugeh-with-trait-bound.rs
15+
16+
use std::fmt;
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<T:fmt::Debug>(u32, T);
28+
29+
impl<T:fmt::Debug> Drop for Foo<T> {
30+
fn drop(&mut self) {
31+
// Use of `unsafe_destructor_blind_to_params` is unsound,
32+
// because we access `T` fmt method when we pass `self.1`
33+
// below, and thus potentially read from borrowed data.
34+
println!("Dropping Foo({}, {:?})", self.0, self.1);
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+
//~^ ERROR `last_dropped` does not live long enough
46+
foo1 = Foo(1, &first_dropped);
47+
//~^ ERROR `first_dropped` does not live long enough
48+
49+
println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 trait bound
12+
// to assert that destructor will not access any dead data.
13+
//
14+
// Compare with compile-fail/issue28498-reject-trait-bound.rs
15+
16+
#![feature(dropck_parametricity)]
17+
18+
use std::fmt;
19+
20+
#[derive(Debug)]
21+
struct ScribbleOnDrop(String);
22+
23+
impl Drop for ScribbleOnDrop {
24+
fn drop(&mut self) {
25+
self.0 = format!("DROPPED");
26+
}
27+
}
28+
29+
struct Foo<T:fmt::Debug>(u32, T);
30+
31+
impl<T:fmt::Debug> Drop for Foo<T> {
32+
#[unsafe_destructor_blind_to_params]
33+
fn drop(&mut self) {
34+
// Use of `unsafe_destructor_blind_to_params` is sound,
35+
// because destructor never accesses the `Debug::fmt` method
36+
// of `T`, despite having it available.
37+
println!("Dropping Foo({}, _)", self.0);
38+
}
39+
}
40+
41+
fn main() {
42+
let (last_dropped, foo0);
43+
let (foo1, first_dropped);
44+
45+
last_dropped = ScribbleOnDrop(format!("last"));
46+
first_dropped = ScribbleOnDrop(format!("first"));
47+
foo0 = Foo(0, &last_dropped);
48+
foo1 = Foo(1, &first_dropped);
49+
50+
println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
51+
}

0 commit comments

Comments
 (0)