//! 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(rustc_contracts)] 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(val: T) -> T where T: PartialOrd + Sub + From { val - 1u8.into() } /// Create a structure that takes a constant parameter. #[allow(dead_code)] struct Capped(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); }