]> git.lizzy.rs Git - rust.git/blob - src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
Rollup merge of #100855 - IsaacCloos:master, r=joshtriplett
[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     pub trait SomeTrait {
52         fn foo();
53     }
54     impl const SomeTrait for () {
55         fn foo() {}
56     }
57     // non-const impl
58     impl SomeTrait for i32 {
59         fn foo() {}
60     }
61
62     pub struct ConstDropWithBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
63
64     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
65         fn drop(&mut self) {
66             T::foo();
67         }
68     }
69
70     pub struct ConstDropWithNonconstBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
71
72     impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
73         fn drop(&mut self) {
74             // Note: we DON'T use the `T: SomeTrait` bound
75         }
76     }
77 }
78
79 use t::*;
80
81 implements_const_drop! {
82     1u8,
83     2,
84     3.0,
85     Foo,
86     Bar::A,
87     foo,
88     ConstDrop,
89     HasConstDrop(ConstDrop),
90     TrivialFields(1, 2, 3, 4),
91     &1,
92     &1 as *const i32,
93     ConstDropWithBound::<()>,
94     ConstDropWithNonconstBound::<i32>,
95     Result::<i32, !>::Ok(1),
96 }
97
98 fn main() {
99     struct HasDropGlue(#[allow(unused_tuple_struct_fields)] Box<u8>);
100     struct HasDropImpl;
101     impl Drop for HasDropImpl {
102         fn drop(&mut self) {
103             println!("not trivial drop");
104         }
105     }
106
107     // These types should pass because ~const in a non-const context should have no effect.
108     a(HasDropGlue(Box::new(0)));
109     a(HasDropImpl);
110
111     assert_eq!(C, 2);
112 }