]> git.lizzy.rs Git - rust.git/blob - src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
Require Drop impls to have the same constness on its bounds as the bounds on the...
[rust.git] / src / test / ui / rfc-2632-const-trait-impl / const-drop.rs
1 // run-pass
2 // revisions: stock precise
3 #![feature(const_trait_impl)]
4 #![feature(const_mut_refs)]
5 #![feature(never_type)]
6 #![cfg_attr(precise, feature(const_precise_live_drops))]
7
8 use std::marker::Destruct;
9
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
18 const fn a<T: ~const Destruct>(_: T) {}
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);
50
51     #[const_trait]
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
63     pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
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     }
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,
94     ConstDropWithBound::<()>,
95     ConstDropWithNonconstBound::<i32>,
96     Result::<i32, !>::Ok(1),
97 }
98
99 fn main() {
100     struct HasDropGlue(#[allow(unused_tuple_struct_fields)] Box<u8>);
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 }