diff --git a/doc/rust.md b/doc/rust.md index a115f41ae86..bb0438016b8 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1426,6 +1426,7 @@ names are effectively reserved. Some significant attributes include: by the compiler can be found via `rustc -W help`. * The `deriving` attribute, for automatically generating implementations of certain traits. +* The `static_assert` attribute, for asserting that a static bool is true at compiletime Other attributes may be added or removed during development of the language. diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 94ca02b2255..17d3e2c4dfe 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 00000000000..06f8c9f1a32 --- /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 00000000000..de1c6427e14 --- /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 00000000000..81b0c9ff28c --- /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() { +}