mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 21:16:44 +00:00 
			
		
		
		
	 ddbf54b67d
			
		
	
	
		ddbf54b67d
		
	
	
	
	
		
			
			This has now been approved as a language feature and no longer needs a `rustc_` prefix. Also change the `contracts` feature to be marked as incomplete and `contracts_internals` as internal.
		
			
				
	
	
		
			72 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! Test that contracts can be applied to generic functions.
 | |
| 
 | |
| //@ revisions: unchk_pass chk_pass chk_fail_pre chk_fail_post chk_const_fail
 | |
| //
 | |
| //@ [unchk_pass] run-pass
 | |
| //@ [chk_pass] run-pass
 | |
| //
 | |
| //@ [chk_fail_pre] run-fail
 | |
| //@ [chk_fail_post] run-fail
 | |
| //@ [chk_const_fail] run-fail
 | |
| //
 | |
| //@ [unchk_pass] compile-flags: -Zcontract-checks=no
 | |
| //
 | |
| //@ [chk_pass] compile-flags: -Zcontract-checks=yes
 | |
| //@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
 | |
| //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
 | |
| //@ [chk_const_fail] compile-flags: -Zcontract-checks=yes
 | |
| 
 | |
| #![feature(contracts)]
 | |
| //~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
 | |
| 
 | |
| use std::ops::Sub;
 | |
| 
 | |
| /// Dummy fn contract that precondition fails for val < 0, and post-condition fail for val == 1
 | |
| #[core::contracts::requires(val > 0u8.into())]
 | |
| #[core::contracts::ensures(|ret| *ret > 0u8.into())]
 | |
| fn decrement<T>(val: T) -> T
 | |
| where T: PartialOrd + Sub<Output=T> + From<u8>
 | |
| {
 | |
|     val - 1u8.into()
 | |
| }
 | |
| 
 | |
| /// Create a structure that takes a constant parameter.
 | |
| #[allow(dead_code)]
 | |
| struct Capped<const MAX: usize>(usize);
 | |
| 
 | |
| /// Now declare a function to create stars which shouldn't exceed 5 stars.
 | |
| // Add redundant braces to ensure the built-in macro can handle this syntax.
 | |
| #[allow(unused_braces)]
 | |
| #[core::contracts::requires(num <= 5)]
 | |
| unsafe fn stars_unchecked(num: usize) -> Capped<{ 5 }> {
 | |
|     Capped(num)
 | |
| }
 | |
| 
 | |
| 
 | |
| fn main() {
 | |
|     check_decrement();
 | |
|     check_stars();
 | |
| }
 | |
| 
 | |
| fn check_stars() {
 | |
|     // This should always pass.
 | |
|     let _ = unsafe { stars_unchecked(3) };
 | |
| 
 | |
|     // This violates the contract.
 | |
|     #[cfg(any(unchk_pass, chk_const_fail))]
 | |
|     let _ = unsafe { stars_unchecked(10) };
 | |
| }
 | |
| 
 | |
| fn check_decrement() {
 | |
|     // This should always pass
 | |
|     assert_eq!(decrement(10u8), 9u8);
 | |
| 
 | |
|     // This should fail requires but pass with no contract check.
 | |
|     #[cfg(any(unchk_pass, chk_fail_pre))]
 | |
|     assert_eq!(decrement(-2i128), -3i128);
 | |
| 
 | |
|     // This should fail ensures but pass with no contract check.
 | |
|     #[cfg(any(unchk_pass, chk_fail_post))]
 | |
|     assert_eq!(decrement(1i32), 0i32);
 | |
| }
 |