Enforce that we don't generate code for comptime fns - #159777
Conversation
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Enforce that we don't generate code for comptime fns
|
Sounds like Miri's |
|
I'm not worried about miri being able to reach this. There are enough safeguards to fail compilation before that happens. This was just about codegen picking what to codegen via various independent means, and I overlooked one. |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (2fa05b3): comparison URL. Overall result: no relevant changes - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (primary -3.7%, secondary 2.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesThis perf run didn't have relevant results for this metric. Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 485.902s -> 487.995s (0.43%) |
| DefKind::Fn | DefKind::AssocFn | ||
| if tcx.constness(def_id) == hir::Constness::Const { always: true } => | ||
| { | ||
| return None; | ||
| } |
There was a problem hiding this comment.
From what I can gather, you modified this function so (among other things) tcx.is_reachable_non_generic in RootCollector::is_root returns false for comptime functions when collecting mono items (collect_roots < collect_crate_mono_items).
However, under MonoItemCollectionStrategy::Eager (-Clink-dead-code) is_root doesn't consider is_reachable_non_generic, meaning the following two snippets of code both ICE in debug mode if -Clink-dead-code is passed
#![feature(rustc_attrs)] // for `rustc_comptime`
#![crate_type = "lib"]
#[rustc_comptime]
pub fn f() { std::mem::offset_of!(((),), 0); }
// => std::intrinsics::offset_of::<((),)>(0, 0)#![feature(rustc_attrs)] // for `rustc_comptime`
#![crate_type = "lib"]
#[rustc_comptime]
pub fn f() { size_of::<()>(); }with
thread 'rustc' (60874) panicked at compiler/rustc_symbol_mangling/src/lib.rs:246:9:
assertion failed: tcx.constness(instance.def_id()) != hir::Constness::Const { always: true }
The code above doesn't ICE in release mode.
However, calling these comptime intrinsics directly if -Clink-dead-code is passed also ICEs in release mode but it requires feature core_intrinsics of course & they already ICE on nightly, so this might be considered WONTFIX?:
#![feature(rustc_attrs)] // for `rustc_comptime`
#![feature(core_intrinsics)] // well...
#![crate_type = "lib"]
#[rustc_comptime] pub fn f() { std::intrinsics::size_of::<()>(); }error: internal compiler error: compiler/rustc_codegen_ssa/src/mir/intrinsic.rs:140:21: Nullary intrinsic size_of must be called in a const block. If you are seeing this message from code outside the standard library, the unstable implementation details of the relevant intrinsic may have changed. Consider using stable APIs instead. If you are adding a new nullary intrinsic that is inherently a runtime intrinsic, update this check.
--> <anon>:1:32
|
1 | #[rustc_comptime] pub fn f() { std::intrinsics::size_of::<()>(); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#![feature(rustc_attrs)] // for `rustc_comptime`
#![feature(core_intrinsics)] // well...
#![crate_type = "lib"]
#[rustc_comptime] pub fn f() { std::intrinsics::offset_of::<((),)>(0, 0); }error: internal compiler error: compiler/rustc_codegen_ssa/src/mir/block.rs:1075:37: intrinsic offset_of must be overridden by codegen backend, but isn't
--> <anon>:1:32
|
1 | #[rustc_comptime] pub fn f() { std::intrinsics::offset_of::<((),)>(0, 0); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There was a problem hiding this comment.
If you consider this acceptable for the time being (after all, use of -Clink-dead-code seems discouraged & it seems to require #![feature(rustc_attrs)] unless there's a different way to repro it w/o nightly features?), feel free to r=me w/ or w/o a FIXME.
I'm not super accustomed to this part of the compiler, so the fact that the current approach ICEs under -Clink-dead-code naively leads me to believe that there might be better places to put the Const { always: true } check(s)...
There was a problem hiding this comment.
I initially had the check only in monomorphization, but that didn't work out fully (got linker errors 😨 ). So I decided to just add the ICE and avoid it, which immediately pointed me to the reachable_non_generics query. That eagerly collects the symbols (for stable sorting), so I can't prevent it just at the call sites.
Managed to confuse myself a few times in between, but I ended up removing all "redundant" (or not redundant, as you figured out) checks from mono collection. So we may need both after all. While I never understood the reason for link-dead-code's existence, I'll try to not break it more than it is considering the many issues about it.
|
Thanks, I love it! r=me w/ or w/o a FIXME if you don't consider #159777 (comment) to be a concern for the time being. |
8648a76 to
4609fbc
Compare
|
The extra check only runs in eager mode, so we don't pay the cost for it except in link-dead-code mode, which... is already expensive as it is. @bors r=fmease |
…uwer Rollup of 14 pull requests Successful merges: - #160009 (`rust-analyzer` subtree update) - #159833 (ci: Make the `x86_64-gnu-parallel-frontend` job non-optional) - #158873 (applying `/Brepro` in bootstrap on MSVC and adding a run-make test.) - #159777 (Enforce that we don't generate code for comptime fns) - #159997 (On many bindings with move error, limit the number of `Span`s) - #158205 (fix: defer const normalize in coherence mode) - #159312 (Windows implementation for stdio set/take/replace) - #159772 (Fix lowering of resolved const inference variables) - #159785 (Share _Unwind_Exception definition between native and wasm) - #159968 (Fix the const impl suggestion) - #159974 (Update thinvec to 0.2.19) - #160013 (tests/ui: Ignore one query cycle test in parallel frontend mode) - #160016 (compiletest: do not talk about JSON when the user never sees any) - #160018 (test suite: add ARM case to ABI-required target feature check for -Ctarget-cpu)
Rollup merge of #159777 - oli-obk:really-comptime-this-time, r=fmease Enforce that we don't generate code for comptime fns ... by ICEing if you try to compute a symbol for them. There are various other ways we can assert it, but they were all a bit icky or already unreachable. r? @fmease (since you asked about it in #159727 (comment))
... by ICEing if you try to compute a symbol for them. There are various other ways we can assert it, but they were all a bit icky or already unreachable.
r? @fmease (since you asked about it in #159727 (comment))