summaryrefslogtreecommitdiffstats
path: root/tests/ui/dropck/issue-24805-dropck-itemless.rs
blob: 45761b61c3e95097b5108020b3188d8473998c1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// run-pass

// Check that item-less traits do not cause dropck to inject extra
// region constraints.

#![allow(non_camel_case_types)]

#![feature(dropck_eyepatch)]

trait UserDefined { }

impl UserDefined for i32 { }
impl<'a, T> UserDefined for &'a T { }

// e.g., `impl_drop!(Send, D_Send)` expands to:
//   ```rust
//   struct D_Send<T:Send>(T);
//   impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } }
//   ```
macro_rules! impl_drop {
    ($Bound:ident, $Id:ident) => {
        struct $Id<T: $Bound>(#[allow(unused_tuple_struct_fields)] T);
        unsafe impl <#[may_dangle] T: $Bound> Drop for $Id<T> {
            fn drop(&mut self) { }
        }
    }
}

impl_drop!{Send,         D_Send}
impl_drop!{Sized,        D_Sized}

// See note below regarding Issue 24895
// impl_drop!{Copy,         D_Copy}

impl_drop!{Sync,         D_Sync}
impl_drop!{UserDefined,  D_UserDefined}

macro_rules! body {
    ($id:ident) => { {
        // `_d` and `d1` are assigned the *same* lifetime by region inference ...
        let (_d, d1);

        d1 = $id(1);
        // ... we store a reference to `d1` within `_d` ...
        _d = $id(&d1);

        // ... a *conservative* dropck will thus complain, because it
        // thinks Drop of _d could access the already dropped `d1`.
    } }
}

fn f_send() { body!(D_Send) }
fn f_sized() { body!(D_Sized) }
fn f_sync() { body!(D_Sync) }

// Issue 24895: Copy: Clone implies `impl<T:Copy> Drop for ...` can
// access a user-defined clone() method, which causes this test case
// to fail.
//
// If 24895 is resolved by removing the `Copy: Clone` relationship,
// then this definition and the call below should be uncommented. If
// it is resolved by deciding to keep the `Copy: Clone` relationship,
// then this comment and the associated bits of code can all be
// removed.

// fn f_copy() { body!(D_Copy) }

fn f_userdefined() { body!(D_UserDefined) }

fn main() {
    f_send();
    f_sized();
    // See note above regarding Issue 24895.
    // f_copy();
    f_sync();
    f_userdefined();
}