]>
Commit | Line | Data |
---|---|---|
c295e0f8 XL |
1 | // run-pass |
2 | // revisions: stock precise | |
3 | #![feature(const_trait_impl)] | |
c295e0f8 | 4 | #![feature(const_mut_refs)] |
5099ac24 | 5 | #![feature(never_type)] |
c295e0f8 XL |
6 | #![cfg_attr(precise, feature(const_precise_live_drops))] |
7 | ||
5e7ed085 FG |
8 | use std::marker::Destruct; |
9 | ||
c295e0f8 XL |
10 | struct S<'a>(&'a mut u8); |
11 | ||
12 | impl<'a> const Drop for S<'a> { | |
13 | fn drop(&mut self) { | |
14 | *self.0 += 1; | |
15 | } | |
16 | } | |
17 | ||
5e7ed085 | 18 | const fn a<T: ~const Destruct>(_: T) {} |
c295e0f8 XL |
19 | |
20 | const fn b() -> u8 { | |
21 | let mut c = 0; | |
22 | let _ = S(&mut c); | |
23 | a(S(&mut c)); | |
24 | c | |
25 | } | |
26 | ||
27 | const C: u8 = b(); | |
28 | ||
29 | macro_rules! implements_const_drop { | |
30 | ($($exp:expr),*$(,)?) => { | |
31 | $( | |
32 | const _: () = a($exp); | |
33 | )* | |
34 | } | |
35 | } | |
36 | ||
37 | #[allow(dead_code)] | |
38 | mod t { | |
39 | pub struct Foo; | |
40 | pub enum Bar { A } | |
41 | pub fn foo() {} | |
42 | pub struct ConstDrop; | |
43 | ||
44 | impl const Drop for ConstDrop { | |
45 | fn drop(&mut self) {} | |
46 | } | |
47 | ||
48 | pub struct HasConstDrop(pub ConstDrop); | |
49 | pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize); | |
5099ac24 | 50 | |
2b03887a | 51 | #[const_trait] |
5099ac24 FG |
52 | pub trait SomeTrait { |
53 | fn foo(); | |
54 | } | |
55 | impl const SomeTrait for () { | |
56 | fn foo() {} | |
57 | } | |
58 | // non-const impl | |
59 | impl SomeTrait for i32 { | |
60 | fn foo() {} | |
61 | } | |
62 | ||
2b03887a | 63 | pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>); |
5099ac24 FG |
64 | |
65 | impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> { | |
66 | fn drop(&mut self) { | |
67 | T::foo(); | |
68 | } | |
69 | } | |
70 | ||
71 | pub struct ConstDropWithNonconstBound<T: SomeTrait>(pub core::marker::PhantomData<T>); | |
72 | ||
73 | impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> { | |
74 | fn drop(&mut self) { | |
75 | // Note: we DON'T use the `T: SomeTrait` bound | |
76 | } | |
77 | } | |
c295e0f8 XL |
78 | } |
79 | ||
80 | use t::*; | |
81 | ||
82 | implements_const_drop! { | |
83 | 1u8, | |
84 | 2, | |
85 | 3.0, | |
86 | Foo, | |
87 | Bar::A, | |
88 | foo, | |
89 | ConstDrop, | |
90 | HasConstDrop(ConstDrop), | |
91 | TrivialFields(1, 2, 3, 4), | |
92 | &1, | |
93 | &1 as *const i32, | |
5099ac24 FG |
94 | ConstDropWithBound::<()>, |
95 | ConstDropWithNonconstBound::<i32>, | |
96 | Result::<i32, !>::Ok(1), | |
c295e0f8 XL |
97 | } |
98 | ||
99 | fn main() { | |
064997fb | 100 | struct HasDropGlue(#[allow(unused_tuple_struct_fields)] Box<u8>); |
c295e0f8 XL |
101 | struct HasDropImpl; |
102 | impl Drop for HasDropImpl { | |
103 | fn drop(&mut self) { | |
104 | println!("not trivial drop"); | |
105 | } | |
106 | } | |
107 | ||
108 | // These types should pass because ~const in a non-const context should have no effect. | |
109 | a(HasDropGlue(Box::new(0))); | |
110 | a(HasDropImpl); | |
111 | ||
112 | assert_eq!(C, 2); | |
113 | } |