-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Limit the promotion of const fns to the libstd and the rustc_promotable
attribute
#53851
Conversation
@bors try |
⌛ Trying commit dc280eb2bc82f51f865c5bc3dc9cd8997cc3d69c with merge 952c7dbfa2628309f557b367929ffc17af20b332... |
☀️ Test successful - status-travis |
@craterbot run start=master#1114ab684fbad001c4e580326d8eb4d8c4e917d3 end=try#952c7dbfa2628309f557b367929ffc17af20b332 mode=check-only |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🎉 Experiment
|
One spurious regression, and one true regression:
|
... and that could be fixed by using |
@eddyb said on IRC that we should instead add a whitelist of promotable const fns, and add the currently stable ones to it in order to not have any possibility of breakage even outside crates.io |
Anything, as long as we do it before |
dc280eb
to
5f4c14d
Compare
use syntax::attr; | ||
use rustc_target::spec::abi; | ||
|
||
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { |
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.
I collected all the logic in this one file in order to make our lives easier and have less code duplication which might cause odd inconsistencies
@@ -253,9 +250,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeEvaluator { | |||
ecx.goto_block(ret)?; // fully evaluated and done | |||
return Ok(None); | |||
} | |||
return Err( |
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.
I had to remove this because the is_const_fn
above is now overly restrictive (it will forbid calling str::len
with the const_str_len
feature gate but without the const_slice_len
feature gate because that calls [u8]::len
internally). We already check all the guarantees in the const_qualif
pass, there's no need to check them again at evaluation time.
&mut self, | ||
def_id: DefId, | ||
) -> Promotability { | ||
if self.tcx.is_promotable_const_fn(def_id) { |
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.
This is now just a single call to is_promotable_const_fn
which seems a major improvement over the code duplication we were doing here before.
src/test/run-pass/issue-49955-2.rs
Outdated
#[inline(never)] | ||
fn tuple_field() -> &'static u32 { | ||
// This test is MIR-borrowck-only because the old borrowck | ||
// doesn't agree that borrows of "frozen" (i.e. without any | ||
// interior mutability) fields of non-frozen temporaries, | ||
// should be promoted, while MIR promotion does promote them. | ||
&(Cell::new(5), 42).1 | ||
&(FIVE, 42).1 |
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.
calls to Cell::new
are not promotable anymore, thus this breaks. The crater run didn't show any cases of people actually writing this kind of code (also needs MIR borrowck)
| calling non-const fn `<I as std::iter::IntoIterator><std::ops::RangeFrom<usize>>::into_iter` | ||
| inside call to `std::iter::range::<impl std::iter::Iterator for std::ops::RangeFrom<A>><usize>::next` | ||
| | ||
::: $SRC_DIR/libcore/ptr.rs:LL:COL |
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.
Diagnostics improvement or regression. Depending on your view. We used to stop at the first non-const fn, now we just stop if/when we fail to actually evaluate. An error is reported above about non const fn calls and other non-const things happening here.
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.
Although I like the specificity, this is not actually actionable, is it? I would not block on improving this message though.
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.
We could probably make it a delay_span_bug
, but i fear that we'll overlook some case and then run into that hypothetical ICE at some point.
These kind of errors only happen for repeat/array lengths and enum variant discriminant initializers (or constants used in such). Everything else reports only the other errors above.
Alternatively we can try to figure out a scheme that prevents const eval of constants with const qualification errors.
r? @eddyb |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
6939244
to
c793391
Compare
@bors r=eddyb |
📌 Commit c793391 has been approved by |
Limit the promotion of const fns to the libstd and the `rustc_promotable` attribute There are so many questions around promoting const fn calls... it seems saner to try to limit automatic promotion to const fns which were explicitly opted in for promotion. I added the attribute to all public stable const fns that were already promotable (e.g. not Cell::new) in order to not cause any breakage r? @eddyb cc @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
Broader discussion continues in rust-lang/const-eval#19 |
There are so many questions around promoting const fn calls... it seems saner to try to limit automatic promotion to const fns which were explicitly opted in for promotion.
I added the attribute to all public stable const fns that were already promotable (e.g. not Cell::new) in order to not cause any breakage
r? @eddyb
cc @nikomatsakis