From e64339645b675f3a1dbc21ae785fe9a754f0cb71 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Tue, 21 May 2013 20:26:45 -0400 Subject: [PATCH] Implement static_assert attribute This verifies that a static item evaluates to true, at compile time. --- src/librustc/middle/trans/base.rs | 21 ++++++++++++++++++++- src/test/compile-fail/static-assert.rs | 5 +++++ src/test/compile-fail/static-assert2.rs | 4 ++++ src/test/run-pass/static-assert.rs | 14 ++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/static-assert.rs create mode 100644 src/test/compile-fail/static-assert2.rs create mode 100644 src/test/run-pass/static-assert.rs diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 94ca02b22554..17d3e2c4dfef 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2147,7 +2147,26 @@ pub fn trans_item(ccx: @CrateContext, item: &ast::item) { trans_enum_def(ccx, enum_definition, item.id, vi, &mut i); } } - ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id), + ast::item_const(_, expr) => { + consts::trans_const(ccx, expr, item.id); + // Do static_assert checking. It can't really be done much earlier because we need to get + // the value of the bool out of LLVM + for item.attrs.each |attr| { + match attr.node.value.node { + ast::meta_word(x) => { + if x.slice(0, x.len()) == "static_assert" { + let v = ccx.const_values.get_copy(&item.id); + unsafe { + if !(llvm::LLVMConstIntGetZExtValue(v) as bool) { + ccx.sess.span_fatal(expr.span, "static assertion failed"); + } + } + } + }, + _ => () + } + } + }, ast::item_foreign_mod(ref foreign_mod) => { foreign::trans_foreign_mod(ccx, path, foreign_mod); } diff --git a/src/test/compile-fail/static-assert.rs b/src/test/compile-fail/static-assert.rs new file mode 100644 index 000000000000..06f8c9f1a325 --- /dev/null +++ b/src/test/compile-fail/static-assert.rs @@ -0,0 +1,5 @@ +#[static_assert] +static a: bool = false; //~ ERROR static assertion failed + +fn main() { +} diff --git a/src/test/compile-fail/static-assert2.rs b/src/test/compile-fail/static-assert2.rs new file mode 100644 index 000000000000..de1c6427e14b --- /dev/null +++ b/src/test/compile-fail/static-assert2.rs @@ -0,0 +1,4 @@ +#[static_assert] +static e: bool = 1 == 2; //~ ERROR static assertion failed + +fn main() {} diff --git a/src/test/run-pass/static-assert.rs b/src/test/run-pass/static-assert.rs new file mode 100644 index 000000000000..81b0c9ff28c3 --- /dev/null +++ b/src/test/run-pass/static-assert.rs @@ -0,0 +1,14 @@ +#[static_assert] +static b: bool = true; + +#[static_assert] +static c: bool = 1 == 1; + +#[static_assert] +static d: bool = 1 != 2; + +#[static_assert] +static f: bool = (4/2) == 2; + +fn main() { +}