-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Various const eval and pattern matching ICE fixes #67192
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
Changes from all commits
1e40681
b5b5258
bb1ecee
13694de
a0bd1a6
0e969b7
a7a011d
6b651b1
41d5818
8a88ff1
cb8d1c3
6937ca2
72ebce0
0e3fafa
9520551
1acbf4b
20c1b3f
1531c39
b476344
aaffe12
12a4c2c
f65a91e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -923,12 +923,14 @@ where | |
return self.copy_op(src, dest); | ||
} | ||
// We still require the sizes to match. | ||
assert!( | ||
src.layout.size == dest.layout.size, | ||
"Size mismatch when transmuting!\nsrc: {:#?}\ndest: {:#?}", | ||
src, | ||
dest | ||
); | ||
if src.layout.size != dest.layout.size { | ||
// FIXME: This should be an assert instead of an error, but if we transmute within an | ||
// array length computation, `typeck` may not have yet been run and errored out. In fact | ||
// most likey we *are* running `typeck` right now. Investigate whether we can bail out | ||
// on `typeck_tables().has_errors` at all const eval entry points. | ||
debug!("Size mismatch when transmuting!\nsrc: {:#?}\ndest: {:#?}", src, dest); | ||
throw_unsup!(TransmuteSizeDiff(src.layout.ty, dest.layout.ty)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is that we can't possibly continue evaluation here, there's no useful operation to do. So we need to error out. I'd rather fix this correctly in a follow up where I enforce that we don't even try to evaluate if we have typeck errors |
||
} | ||
// Unsized copies rely on interpreting `src.meta` with `dest.layout`, we want | ||
// to avoid that here. | ||
assert!( | ||
|
@@ -974,31 +976,20 @@ where | |
let (mplace, size) = match place.place { | ||
Place::Local { frame, local } => { | ||
match self.stack[frame].locals[local].access_mut()? { | ||
Ok(local_val) => { | ||
Ok(&mut local_val) => { | ||
// We need to make an allocation. | ||
// FIXME: Consider not doing anything for a ZST, and just returning | ||
// a fake pointer? Are we even called for ZST? | ||
|
||
// We cannot hold on to the reference `local_val` while allocating, | ||
// but we can hold on to the value in there. | ||
oli-obk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let old_val = | ||
if let LocalValue::Live(Operand::Immediate(value)) = *local_val { | ||
Some(value) | ||
} else { | ||
None | ||
}; | ||
|
||
// We need the layout of the local. We can NOT use the layout we got, | ||
// that might e.g., be an inner field of a struct with `Scalar` layout, | ||
// that has different alignment than the outer field. | ||
// We also need to support unsized types, and hence cannot use `allocate`. | ||
let local_layout = self.layout_of_local(&self.stack[frame], local, None)?; | ||
// We also need to support unsized types, and hence cannot use `allocate`. | ||
let (size, align) = self | ||
.size_and_align_of(meta, local_layout)? | ||
.expect("Cannot allocate for non-dyn-sized type"); | ||
let ptr = self.memory.allocate(size, align, MemoryKind::Stack); | ||
let mplace = MemPlace { ptr: ptr.into(), align, meta }; | ||
if let Some(value) = old_val { | ||
if let LocalValue::Live(Operand::Immediate(value)) = local_val { | ||
// Preserve old value. | ||
// We don't have to validate as we can assume the local | ||
// was already valid for its type. | ||
|
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 shouldn't add new "unclassified" error kinds. This one looks like UB to me?
But, how can it even be possible to get around the check rustc is already doing that the size must match...?
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 happens for array lengths, which are evaluated before typeck prevents const eval from running.... and now I'm thinking I can maybe just abort if typeck tables have errors. I'll try to remove this variant again, but I'd rather not make such a profound change to how we do early const eval in this PR
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 we should never run Miri on untypechecked code. That would mean we'd lose tons and tons of useful invariants -- Miri relies on code being well-typed in a lot of places. This would be an endless source of ICEs.
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.
yea, this is an issue since 1.0. I'll try to address it again, I think the query system may be up to it nowadays.