-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Add hook for overriding compiler builtin macros #145734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add hook for overriding compiler builtin macros #145734
Conversation
|
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. Some changes occurred to the CTFE machinery |
@@ -40,6 +40,7 @@ pub fn provide(providers: &mut Providers) { | |||
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; | |||
providers.eval_static_initializer = const_eval::eval_static_initializer_provider; | |||
providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider; | |||
providers.hooks.after_register_builtin_macros = |_, _| {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this have to do with const-eval...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, nothing lol. I was trying to figure out which crate's provide()
function a default implementation should go under, and am not very familiar with the compiler's layout. Is this the right way to do that, and if so which provide()
would be the right one to add it to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which provide() would be the right one to add it to?
I'm not sure either, I'm just a const-eval maintainer and was confused about what showed up on "my turf" here. ;)
Something that deals with macros, probably... or rustc_middle if nothing else fits, I guess.
Is this for the standard library verification? If so you can just define a panic macro inside compiler-builtins to override the builtin one, right? Aside from the standard library verification, I wouldn't expect Kani to do anything with compiler-builtins at all. There shouldn't be any MIR level calls to compiler-builtins except for memcpy, memset and memcmp which you did want to shim anyway. |
The macro is not defined i compiler-builtins so I am not sure why you are bringing that up? |
I mean that for the standard library verification I think they could just put macro_rules! panic { ... } at the top of |
Hey @bjorn3, this situation actually came up in the context of verifying user programs, not the standard library itself. AFAIK, when compiling a user crate, Kani uses However, if the user writes something like (Here's the link to the original Kani issue for more context.) |
You need to build the dependencies against the modified standard library as well, then they will use your macro. I wonder how anything can work if you are mixing different standard libraries...? This PR sets a precedent for ad-hoc patching of the standard library through rustc itself -- today you need this for builtin macros, but who knows what you want to replace tomorrow? I don't see anything specific to panic or builtin macros that would make them harder to replace than any other part of the standard library. (Them being builtin just means the standard library macro has no body, but in terms of name resolution it should behave like any normal macro.) |
Is model-checking/kani#4169 the PR implementing what you mentioned above? That is something completely different from "--extern to link against a slightly modified version of the standard library where we've overridden panic!() to call a kani::panic() intrinsic instead" though so I must be looking at the wrong thing. |
Okay I have found https://github.com/model-checking/kani/blob/96eb502ffce80c3408c79d18620c84e364be9310/library/std/src/lib.rs#L203. But that's not a modified standard library. That's a tiny crate called If you actually modified the standard library, you could change the macro in whatever way you please and it'd apply everywhere. |
If you are not verifying compiler-builtins, can you just ignore all functions in compiler-builtins when translating from MIR to whatever Kani produces? 99% of compiler-builtins will never be called from MIR and the remaining 1% (memcpy, memmove, memset, ...) you almost certainly want to shim anyway as it is often provided by libc rather than compiler-builtins |
@bjorn3 why do you keep talking about compiler-builtins? This is about builtin macros, which have nothing to do with compiler-builtins... |
I read that as compiler-builtins macros. As in macros invoked inside the compiler-builtins crate. Never mind I guess. |
Kani's std layer was originally introduced to allow us to override the assert macro. Our overriden assert macro serves two purposes:
The mechanism we use for overrides is pretty hacky though, and relies on passing We were hoping that rustc can provide a more reliable mechanism for performing such overrides so that we can rid of this hack. |
It is in general impossible to "overwrite" the macros in std without building your own std -- the std that is distributed is already fully macro-expanded. In that sense I think actually this PR is pointless? @AlexanderPortland have you actually tried this with Kani? Even with this PR, I am fairly sure that if you call
If you want the changes to affect even std itself, I don't think there is any realistic alternative to patching the std sources and then building a custom std. |
It would be useful for compiler plugins to be able to override the functionality of builtin macros, so this PR attempts to implement that. This is my first real attempt at contributing to Rust, so I’m looking to improve my skills and am very open to feedback or criticism!
This feature would specifically be very useful for us in Kani, as it would allow us to stub out the std library's
panic!()
macro when we’re doing codegen for verification and avoid having to verify the complicated string formatting from certain calls of that macro.r? @oli-obk