mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 21:16:44 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			114 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // run-pass
 | |
| // revisions: stock precise
 | |
| #![feature(const_trait_impl)]
 | |
| #![feature(const_mut_refs)]
 | |
| #![feature(never_type)]
 | |
| #![cfg_attr(precise, feature(const_precise_live_drops))]
 | |
| 
 | |
| use std::marker::Destruct;
 | |
| 
 | |
| struct S<'a>(&'a mut u8);
 | |
| 
 | |
| impl<'a> const Drop for S<'a> {
 | |
|     fn drop(&mut self) {
 | |
|         *self.0 += 1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| const fn a<T: ~const Destruct>(_: T) {}
 | |
| 
 | |
| const fn b() -> u8 {
 | |
|     let mut c = 0;
 | |
|     let _ = S(&mut c);
 | |
|     a(S(&mut c));
 | |
|     c
 | |
| }
 | |
| 
 | |
| const C: u8 = b();
 | |
| 
 | |
| macro_rules! implements_const_drop {
 | |
|     ($($exp:expr),*$(,)?) => {
 | |
|         $(
 | |
|             const _: () = a($exp);
 | |
|         )*
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[allow(dead_code)]
 | |
| mod t {
 | |
|     pub struct Foo;
 | |
|     pub enum Bar { A }
 | |
|     pub fn foo() {}
 | |
|     pub struct ConstDrop;
 | |
| 
 | |
|     impl const Drop for ConstDrop {
 | |
|         fn drop(&mut self) {}
 | |
|     }
 | |
| 
 | |
|     pub struct HasConstDrop(pub ConstDrop);
 | |
|     pub struct TrivialFields(pub u8, pub i8, pub usize, pub isize);
 | |
| 
 | |
|     #[const_trait]
 | |
|     pub trait SomeTrait {
 | |
|         fn foo();
 | |
|     }
 | |
|     impl const SomeTrait for () {
 | |
|         fn foo() {}
 | |
|     }
 | |
|     // non-const impl
 | |
|     impl SomeTrait for i32 {
 | |
|         fn foo() {}
 | |
|     }
 | |
| 
 | |
|     pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
 | |
| 
 | |
|     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
 | |
|         fn drop(&mut self) {
 | |
|             T::foo();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub struct ConstDropWithNonconstBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
 | |
| 
 | |
|     impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
 | |
|         fn drop(&mut self) {
 | |
|             // Note: we DON'T use the `T: SomeTrait` bound
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| use t::*;
 | |
| 
 | |
| implements_const_drop! {
 | |
|     1u8,
 | |
|     2,
 | |
|     3.0,
 | |
|     Foo,
 | |
|     Bar::A,
 | |
|     foo,
 | |
|     ConstDrop,
 | |
|     HasConstDrop(ConstDrop),
 | |
|     TrivialFields(1, 2, 3, 4),
 | |
|     &1,
 | |
|     &1 as *const i32,
 | |
|     ConstDropWithBound::<()>,
 | |
|     ConstDropWithNonconstBound::<i32>,
 | |
|     Result::<i32, !>::Ok(1),
 | |
| }
 | |
| 
 | |
| fn main() {
 | |
|     struct HasDropGlue(#[allow(unused_tuple_struct_fields)] Box<u8>);
 | |
|     struct HasDropImpl;
 | |
|     impl Drop for HasDropImpl {
 | |
|         fn drop(&mut self) {
 | |
|             println!("not trivial drop");
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // These types should pass because ~const in a non-const context should have no effect.
 | |
|     a(HasDropGlue(Box::new(0)));
 | |
|     a(HasDropImpl);
 | |
| 
 | |
|     assert_eq!(C, 2);
 | |
| }
 | 
