-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[TEST] Don't allow constant eval to access generator layouts #115359
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
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri |
The Miri subtree was changed cc @rust-lang/miri |
@@ -357,6 +357,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, | |||
|
|||
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error | |||
|
|||
// We don't allow access to generator layout at compile time. | |||
const ACCESS_GENERATOR_LAYOUT: bool = false; |
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.
Please remove the default value here, and move it to the compile_time_machine macro below. After all this is also shared with Miri, so we don't set defaults here based on "being compile-time".
|
||
// Ensure we don't need the layout of any generators if applicable. | ||
// This prevents typeck from depending on MIR optimizations. | ||
self.validate_generator_layout_access(ty)?; |
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.
Why is this the one place where the layout is checked? That seems odd, aren't there tons of ways the layout could become relevant?
|
||
/// This function checks if the given `ty`'s layout depends on generators. | ||
#[inline(always)] | ||
pub fn validate_generator_layout_access(&self, ty: Ty<'tcx>) -> InterpResult<'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.
"validity.rs" is for checking that a value is valid. Please don't put unrelated functions here.
@@ -404,6 +404,7 @@ pub enum ValidationErrorKind<'tcx> { | |||
InvalidBool { value: String }, | |||
InvalidChar { value: String }, | |||
InvalidFnPtr { value: String }, | |||
GeneratorLayoutAccess { ty: Ty<'tcx>, generators: &'tcx List<Ty<'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.
"ValidationErrorKind" is for when a value doesn't satisfy its validity invariant. This is unrelated, please don't put that here.
Sound more like an InvalidProgram
error to me. Or ideally the error variant is only added in const_eval::error, so we structurally know it will not occur in Miri.
.allocation_spans | ||
.borrow_mut() | ||
.insert(alloc_id, (span, None)); | ||
ecx.machine.allocation_spans.borrow_mut().insert(alloc_id, (span, None)); |
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.
Please don't format these files, they'll have to be reformatted when syncing changes back to Miri. (Miri has a different rustfmt.toml.)
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.
Why doesn't rustfmt use those settings? :/
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 think it's up to RA to tell it the config file to use (rustfmt isn't invoked on a file, it is fed data via stdin and returned via stdout). Not sure if there's an open RA bug for this.
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.
It seems like RA changes the current directory to match the file for rustfmt
. I guess that doesn't work out.
do you have an example snippet that compiles on stable but doesn't compile anymore? |
As @RalfJung pointed out, this isn't the only place layout is used. It would have apply more generally to all allocations, effectively banning async and generator blocks from const eval, at least while allocations are byte based. That's not a particularly great outcome. @oli-obk I'll relay your example back to you: const X: usize = {
let x = Thing(|x: u128| async move {x});
x.size()
};
struct Thing<T>(T);
impl<U, T: Fn(u128) -> U> Thing<T> {
const fn size(&self) -> usize {
std::mem::size_of::<U>()
}
} |
Oh whoops. I remember this. Yea, this seems very annoying to prevent. I forget where the original discussion was. Why did we consider avoiding getting generator layouts during const eval? Avoiding some cycle errors? |
Here's the discussion on Zulip. The problem is that having const eval depend on generator layouts places constraints on optimization. We can't have an out of process LTO optimization of generator layouts for example. Just partially optimizing generator layouts within the query system gets quite hairy. I suspect there's some interesting interactions with monomorphization too. |
Thanks! I reread the thread. Splitting Reveal::All into |
Inevitably at some point people will ask to execute generators at compiletime. What do we do then? I don't think doing LTO on pre-lowering generators is a realistic option. |
The moment the new Reveal mode would resolve the issue raised in the zulip, as all it would do is make optimizations before the generator lowering pass stop being able to rely on the size of generators (without causing errors, just by returning something akin to |
https://github.com/Gilnaa/memoffset already works in const-eval when there is no interior mutability. |
☔ The latest upstream changes (presumably #115797) made this pull request unmergeable. Please resolve the merge conflicts. |
@oli-obk The problem with that approach is that we end up having that reveal option on anything that could use generator sizes, including I don't think the method in this PR is a suitable solution however, so I'm going to close it. |
This emits an error if generator layouts are observed by the frontend via constant evaluation. This ensures that the frontend does not depend on optimizations done later in MIR. This is a breaking change as generator layouts can be observed via the async feature combined with constant evaluation.
r? @oli-obk