diff options
author | David Tolnay <dtolnay@chromium.org> | 2018-12-06 17:58:09 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-09 00:48:17 -0800 |
commit | 3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49 (patch) | |
tree | bd83bc797de92ebf1d9592c2e740f798160b2c73 /assertions/src/mechanism.rs | |
parent | f97991985d6921375eb5a533c49fd7df5a75d2cd (diff) | |
download | crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.tar crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.tar.gz crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.tar.bz2 crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.tar.lz crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.tar.xz crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.tar.zst crosvm-3c0aac44d7d7150bbfb2981b92a4ed98a64a1a49.zip |
assertions: Add compile-time assertion macro
A static assertion is particularly appropriate when unsafe code relies on two types to have the same size, or on some type to have a particular size. This is a pattern I observed in USB code, for example: https://chromium.googlesource.com/chromiumos/platform/crosvm/+/ff7068402e6cff527a8558adf597b1596f075166/devices/src/usb/xhci/xhci_abi_schema.rs#522 EXAMPLE: extern crate assertions; use assertions::const_assert; fn main() { const_assert!(std::mem::size_of::<String>() == 24); } EXAMPLE THAT FAILS TO COMPILE: extern crate assertions; use assertions::const_assert; fn main() { // fails to compile: const_assert!(std::mem::size_of::<String>() == 8); } FAILURE LOOKS LIKE: error[E0271]: type mismatch resolving `<[(); 0] as assertions::Expr>::Value == assertions::True` --> src/main.rs:5:5 | 5 | const_assert!(std::mem::size_of::<String>() == 8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `assertions::True`, found struct `assertions::False` TEST=`cargo test` the new crate Change-Id: I6abe36d5a6a4bd4acb1a02e3aa7c1ece5357f007 Reviewed-on: https://chromium-review.googlesource.com/1366819 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: David Tolnay <dtolnay@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'assertions/src/mechanism.rs')
-rw-r--r-- | assertions/src/mechanism.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/assertions/src/mechanism.rs b/assertions/src/mechanism.rs new file mode 100644 index 0000000..e14b91a --- /dev/null +++ b/assertions/src/mechanism.rs @@ -0,0 +1,34 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std::marker::PhantomData; + +pub struct True; +pub struct False; + +pub trait Expr { + type Value; +} + +impl Expr for [(); 0] { + type Value = False; +} + +impl Expr for [(); 1] { + type Value = True; +} + +// If the macro instantiates this with `T = [(); 1]` then it compiles successfully. +// +// On the other hand if `T = [(); 0]` the user receives an error like the following: +// +// error[E0271]: type mismatch resolving `<[(); 0] as assertions::Expr>::Value == assertions::True` +// --> src/main.rs:5:5 +// | +// 5 | const_assert!(std::mem::size_of::<String>() == 8); +// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `assertions::True`, found struct `assertions::False` +// +pub struct Assert<T: Expr<Value = True>> { + marker: PhantomData<T>, +} |