Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
428 additions
and
0 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
src/test/compile-fail/auxiliary/dropck_eyepatch_extern_crate.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#![feature(generic_param_attrs)] | ||
#![feature(dropck_eyepatch)] | ||
|
||
// The point of this test is to illustrate that the `#[may_dangle]` | ||
// attribute specifically allows, in the context of a type | ||
// implementing `Drop`, a generic parameter to be instantiated with a | ||
// lifetime that does not strictly outlive the owning type itself, | ||
// and that this attributes effects are preserved when importing | ||
// the type from another crate. | ||
// | ||
// See also dropck-eyepatch.rs for more information about the general | ||
// structure of the test. | ||
|
||
use std::fmt; | ||
|
||
pub struct Dt<A: fmt::Debug>(pub &'static str, pub A); | ||
pub struct Dr<'a, B:'a+fmt::Debug>(pub &'static str, pub &'a B); | ||
pub struct Pt<A,B: fmt::Debug>(pub &'static str, pub A, pub B); | ||
pub struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(pub &'static str, pub &'a B, pub &'b B); | ||
pub struct St<A: fmt::Debug>(pub &'static str, pub A); | ||
pub struct Sr<'a, B:'a+fmt::Debug>(pub &'static str, pub &'a B); | ||
|
||
impl<A: fmt::Debug> Drop for Dt<A> { | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } | ||
} | ||
impl<'a, B: fmt::Debug> Drop for Dr<'a, B> { | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } | ||
} | ||
unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt<A, B> { | ||
// (unsafe to access self.1 due to #[may_dangle] on A) | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } | ||
} | ||
unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { | ||
// (unsafe to access self.1 due to #[may_dangle] on 'a) | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// aux-build:dropck_eyepatch_extern_crate.rs | ||
|
||
extern crate dropck_eyepatch_extern_crate as other; | ||
|
||
use other::{Dt,Dr,Pt,Pr,St,Sr}; | ||
|
||
fn main() { | ||
use std::cell::Cell; | ||
let c_long; | ||
let (c, mut dt, mut dr, mut pt, mut pr, st, sr) | ||
: (Cell<_>, Dt<_>, Dr<_>, Pt<_, _>, Pr<_>, St<_>, Sr<_>); | ||
c_long = Cell::new(1); | ||
c = Cell::new(1); | ||
|
||
// No error: sufficiently long-lived state can be referenced in dtors | ||
dt = Dt("dt", &c_long); | ||
dr = Dr("dr", &c_long); | ||
// Error: destructor order imprecisely modelled | ||
dt = Dt("dt", &c); //~ ERROR `c` does not live long enough | ||
dr = Dr("dr", &c); //~ ERROR `c` does not live long enough | ||
|
||
// No error: Drop impl asserts .1 (A and &'a _) are not accessed | ||
pt = Pt("pt", &c, &c_long); | ||
pr = Pr("pr", &c, &c_long); | ||
|
||
// Error: Drop impl's assertion does not apply to `B` nor `&'b _` | ||
pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough | ||
pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough | ||
|
||
// No error: St and Sr have no destructor. | ||
st = St("st", &c); | ||
sr = Sr("sr", &c); | ||
|
||
println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#![feature(generic_param_attrs)] | ||
#![feature(dropck_eyepatch)] | ||
|
||
// The point of this test is to illustrate that the `#[may_dangle]` | ||
// attribute specifically allows, in the context of a type | ||
// implementing `Drop`, a generic parameter to be instantiated with a | ||
// lifetime that does not strictly outlive the owning type itself. | ||
// | ||
// Here we test that only the expected errors are issued. | ||
// | ||
// The illustration is made concrete by comparison with two variations | ||
// on the type with `#[may_dangle]`: | ||
// | ||
// 1. an analogous type that does not implement `Drop` (and thus | ||
// should exhibit maximal flexibility with respect to dropck), and | ||
// | ||
// 2. an analogous type that does not use `#[may_dangle]` (and thus | ||
// should exhibit the standard limitations imposed by dropck. | ||
// | ||
// The types in this file follow a pattern, {D,P,S}{t,r}, where: | ||
// | ||
// - D means "I implement Drop" | ||
// | ||
// - P means "I implement Drop but guarantee my (first) parameter is | ||
// pure, i.e. not accessed from the destructor"; no other parameters | ||
// are pure. | ||
// | ||
// - S means "I do not implement Drop" | ||
// | ||
// - t suffix is used when the first generic is a type | ||
// | ||
// - r suffix is used when the first generic is a lifetime. | ||
|
||
use std::fmt; | ||
|
||
struct Dt<A: fmt::Debug>(&'static str, A); | ||
struct Dr<'a, B:'a+fmt::Debug>(&'static str, &'a B); | ||
struct Pt<A,B: fmt::Debug>(&'static str, A, B); | ||
struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(&'static str, &'a B, &'b B); | ||
struct St<A: fmt::Debug>(&'static str, A); | ||
struct Sr<'a, B:'a+fmt::Debug>(&'static str, &'a B); | ||
|
||
impl<A: fmt::Debug> Drop for Dt<A> { | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } | ||
} | ||
impl<'a, B: fmt::Debug> Drop for Dr<'a, B> { | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } | ||
} | ||
unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt<A, B> { | ||
// (unsafe to access self.1 due to #[may_dangle] on A) | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } | ||
} | ||
unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { | ||
// (unsafe to access self.1 due to #[may_dangle] on 'a) | ||
fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } | ||
} | ||
|
||
fn main() { | ||
use std::cell::Cell; | ||
let c_long; | ||
let (c, mut dt, mut dr, mut pt, mut pr, st, sr) | ||
: (Cell<_>, Dt<_>, Dr<_>, Pt<_, _>, Pr<_>, St<_>, Sr<_>); | ||
c_long = Cell::new(1); | ||
c = Cell::new(1); | ||
|
||
// No error: sufficiently long-lived state can be referenced in dtors | ||
dt = Dt("dt", &c_long); | ||
dr = Dr("dr", &c_long); | ||
// Error: destructor order imprecisely modelled | ||
dt = Dt("dt", &c); //~ ERROR `c` does not live long enough | ||
dr = Dr("dr", &c); //~ ERROR `c` does not live long enough | ||
|
||
// No error: Drop impl asserts .1 (A and &'a _) are not accessed | ||
pt = Pt("pt", &c, &c_long); | ||
pr = Pr("pr", &c, &c_long); | ||
|
||
// Error: Drop impl's assertion does not apply to `B` nor `&'b _` | ||
pt = Pt("pt", &c_long, &c); //~ ERROR `c` does not live long enough | ||
pr = Pr("pr", &c_long, &c); //~ ERROR `c` does not live long enough | ||
|
||
// No error: St and Sr have no destructor. | ||
st = St("st", &c); | ||
sr = Sr("sr", &c); | ||
|
||
println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Check that `may_dangle` is rejected if `dropck_eyepatch` feature gate is absent. | ||
|
||
#![feature(generic_param_attrs)] | ||
|
||
struct Pt<A>(A); | ||
impl<#[may_dangle] A> Drop for Pt<A> { | ||
//~^ ERROR may_dangle has unstable semantics and may be removed in the future | ||
//~| HELP add #![feature(dropck_eyepatch)] to the crate attributes to enable | ||
fn drop(&mut self) { } | ||
} |
61 changes: 61 additions & 0 deletions
61
src/test/run-pass/auxiliary/dropck_eyepatch_extern_crate.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#![feature(generic_param_attrs)] | ||
#![feature(dropck_eyepatch)] | ||
|
||
// The point of this test is to illustrate that the `#[may_dangle]` | ||
// attribute specifically allows, in the context of a type | ||
// implementing `Drop`, a generic parameter to be instantiated with a | ||
// lifetime that does not strictly outlive the owning type itself, | ||
// and that this attributes effects are preserved when importing | ||
// the type from another crate. | ||
// | ||
// See also dropck-eyepatch.rs for more information about the general | ||
// structure of the test. | ||
|
||
use std::cell::RefCell; | ||
|
||
pub trait Foo { fn foo(&self, _: &str); } | ||
|
||
pub struct Dt<A: Foo>(pub &'static str, pub A); | ||
pub struct Dr<'a, B:'a+Foo>(pub &'static str, pub &'a B); | ||
pub struct Pt<A,B: Foo>(pub &'static str, pub A, pub B); | ||
pub struct Pr<'a, 'b, B:'a+'b+Foo>(pub &'static str, pub &'a B, pub &'b B); | ||
pub struct St<A: Foo>(pub &'static str, pub A); | ||
pub struct Sr<'a, B:'a+Foo>(pub &'static str, pub &'a B); | ||
|
||
impl<A: Foo> Drop for Dt<A> { | ||
fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } | ||
} | ||
impl<'a, B: Foo> Drop for Dr<'a, B> { | ||
fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } | ||
} | ||
unsafe impl<#[may_dangle] A, B: Foo> Drop for Pt<A, B> { | ||
// (unsafe to access self.1 due to #[may_dangle] on A) | ||
fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } | ||
} | ||
unsafe impl<#[may_dangle] 'a, 'b, B: Foo> Drop for Pr<'a, 'b, B> { | ||
// (unsafe to access self.1 due to #[may_dangle] on 'a) | ||
fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } | ||
} | ||
|
||
impl Foo for RefCell<String> { | ||
fn foo(&self, s: &str) { | ||
let s2 = format!("{}|{}", *self.borrow(), s); | ||
*self.borrow_mut() = s2; | ||
} | ||
} | ||
|
||
impl<'a, T:Foo> Foo for &'a T { | ||
fn foo(&self, s: &str) { | ||
(*self).foo(s); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// aux-build:dropck_eyepatch_extern_crate.rs | ||
|
||
extern crate dropck_eyepatch_extern_crate as other; | ||
|
||
use other::{Dt,Dr,Pt,Pr,St,Sr}; | ||
|
||
fn main() { | ||
use std::cell::RefCell; | ||
|
||
struct CheckOnDrop(RefCell<String>, &'static str); | ||
impl Drop for CheckOnDrop { | ||
fn drop(&mut self) { assert_eq!(*self.0.borrow(), self.1); } | ||
} | ||
|
||
let c_long; | ||
let (c, dt, dr, pt, pr, st, sr) | ||
: (CheckOnDrop, Dt<_>, Dr<_>, Pt<_, _>, Pr<_>, St<_>, Sr<_>); | ||
c_long = CheckOnDrop(RefCell::new("c_long".to_string()), | ||
"c_long|pr|pt|dr|dt"); | ||
c = CheckOnDrop(RefCell::new("c".to_string()), | ||
"c"); | ||
|
||
// No error: sufficiently long-lived state can be referenced in dtors | ||
dt = Dt("dt", &c_long.0); | ||
dr = Dr("dr", &c_long.0); | ||
|
||
// No error: Drop impl asserts .1 (A and &'a _) are not accessed | ||
pt = Pt("pt", &c.0, &c_long.0); | ||
pr = Pr("pr", &c.0, &c_long.0); | ||
|
||
// No error: St and Sr have no destructor. | ||
st = St("st", &c.0); | ||
sr = Sr("sr", &c.0); | ||
|
||
println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); | ||
assert_eq!(*c_long.0.borrow(), "c_long"); | ||
assert_eq!(*c.0.borrow(), "c"); | ||
} |
Oops, something went wrong.