#[should_not_pass_borrow_checker] is analogy to
#[should_panic] for test functions, but it checks the correctness of lifetime bounds.
The implementation of the borrow checker is already thoroughly tested. Why would you need this?
One reason that I’ve used the crates version of compile-test for is checking that lifetime bounds are behaving as you expect and prohibiting misuse of your code (where the internals are unsafe).
The most complicated use I’ve done is with an interner that gave out
&str to members on an append-only
HashSet<String>. I needed to make sure that the lifetimes given were bound correctly when I conjured them from thin air.
(To gloss over details, I had a
StringInterner(&'a mut HashSet<String> and
fn StringInterner(&self, &str) -> &'a str. This required unsafe to implement and I was checking that the lifetime did guarantee what I wanted it to (and the first few iterations didn’t).)
I have no doubt about the soundness of the borrow checker. Quite the opposite, I rely on it to check the soundness of my library which is implemented in unsafe code and use lifetime bounds in public interface to prevent the library user from misuse. However thanks for your link, I will read those code later.
That does help. But it is not specified with borrow check errors, and applicable only for doc test.
I don’t know of a reason why compile-fail should only exist for doctests, and it’s easy to imagine APIs where you’d want to verify that invalid client code fails in type checking or const eval or whatever instead of the borrow checker. There’s probably a backwards compatibility risk with making compile-fail detect overly specific kinds of compilation failure, but I think we can postpone that question.
I guess we need some compiler people to answer whether there is a serious obstacle to supporting compile-fail on regular non-doc tests. I imagine we’d have to require all tests at least parse successfully or else you wouldn’t even know what the tests are, but that seems fine. Macros could get weird though; we’d definitely want to write tests verifying that some invocations of my macro fail to compile.
Well, the compilation model makes it easy for doctests and hard for
#[test]s. It feels weird to spend effort making rustc capable of still running code after having an error.
And there’s a ton of corner cases here. If you fail to compile because overlapping impls, what impls are available in typechecking? If you mark a function as
#[compile_fail], what happens to something that was trying to call it? What if that things trying to call it was also marked