# Idea: make assert!() a keyword - REJECTED

**URL:** https://internals.rust-lang.org/t/idea-make-assert-a-keyword-rejected/13066
**Category:** language design
**Created:** [September 15, 2020, 2:21pm UTC](https://internals.rust-lang.org/t/idea-make-assert-a-keyword-rejected/13066 "2020-09-15T14:21:12Z")
**Posts on this page:** 1
**Showing post:** 8

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [September 15, 2020, 5:53pm UTC](https://internals.rust-lang.org/t/idea-make-assert-a-keyword-rejected/13066/8 "2020-09-15T17:53:22Z")

</div>

I think _keyword_ is probably overkill, but _attribute_ might be interesting.

There's two things I'm thinking about there:

1. If it's an attribute, lints could read it to provide generic lints about constant expressions passed to the function.

For example, clippy has a specific [`iterator_step_by_zero`](https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero) lint. But `step_by` [has an `assert!(step != 0)`](https://github.com/rust-lang/rust/blob/97eb606e4b2becd17d46a67d87169f52b210e67c/library/core/src/iter/adapters/mod.rs#L605)†, so if that were exposed to the lint infrastructure it could be one lint for "always asserts".

And who knows, maybe that would also make it easier for a more complicated static analysis tool to try to prove/disprove them as well, for more than just constants.

† Though not in exactly the place we'd want for what I'm talking about here, but that's a side point and it could be moved.

1. If it's an attribute, it could also do more complicated transformations to make it more likely that the asserts will be checked in the caller.

This could do something along the lines of outlining, for more complicated methods. Imaging a complicated, non-generic function:

```rust
pub fn foo(x: i32) -> i32 { 
    assert_eq!(x & 1, 0);
    ... lots of complicated work here ...
}

```

We want to compile the complicated stuff only once, but we'd also like to elide the asserts by evaluating them in the caller. So imagine that we transformed that code into something like this:

```rust
#[inline]
pub fn foo(x: usize) -> String { 
    assert!(x < isize::MAX as usize);
    unsafe { inner(x) }

    #[forbid(unsafe-op-in-unsafe-fn)]
    unsafe fn inner(x: i32) -> i32 {
        unsafe { assume(x < isize::MAX as usize) };
        ... lots of complicated work here ...
    }
}

```

That way the conditions can get inlined and hopefully folded away, while still allowing separate compilation of the complicated bit and letting LLVM to optimize based on the conditions.

(There some clear weaknesses in here, like `assume` often being not a good idea, but hopefully it gets the idea across.)

---

_[View the full topic](https://internals.rust-lang.org/t/idea-make-assert-a-keyword-rejected/13066)._
