- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
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.
              Outdated
          
            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.