Skip to content

Commit

Permalink
Rollup merge of #108790 - cjgillot:mono-cast, r=oli-obk
Browse files Browse the repository at this point in the history
Do not ICE when interpreting a cast between non-monomorphic types

Fixes #101596
  • Loading branch information
matthiaskrgr authored Mar 6, 2023
2 parents 4bd6f7f + 858eab6 commit 3ae047b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
35 changes: 22 additions & 13 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

Pointer(PointerCast::ReifyFnPointer) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;

// The src operand does not matter, just its type
match *src.layout.ty.kind() {
ty::FnDef(def_id, substs) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;

let instance = ty::Instance::resolve_for_fn_ptr(
*self.tcx,
self.param_env,
Expand Down Expand Up @@ -100,12 +100,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

Pointer(PointerCast::ClosureFnPointer(_)) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;

// The src operand does not matter, just its type
match *src.layout.ty.kind() {
ty::Closure(def_id, substs) => {
// All reifications must be monomorphic, bail out otherwise.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;

let instance = ty::Instance::resolve_closure(
*self.tcx,
def_id,
Expand Down Expand Up @@ -359,8 +359,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx);
self.write_immediate(val, dest)
}

_ => {
// Do not ICE if we are not monomorphic enough.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
ensure_monomorphic_enough(*self.tcx, cast_ty)?;

span_bug!(
self.cur_span(),
"invalid pointer unsizing {:?} -> {:?}",
Expand Down Expand Up @@ -404,12 +407,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
Ok(())
}
_ => span_bug!(
self.cur_span(),
"unsize_into: invalid conversion: {:?} -> {:?}",
src.layout,
dest.layout
),
_ => {
// Do not ICE if we are not monomorphic enough.
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
ensure_monomorphic_enough(*self.tcx, cast_ty.ty)?;

span_bug!(
self.cur_span(),
"unsize_into: invalid conversion: {:?} -> {:?}",
src.layout,
dest.layout
)
}
}
}
}
15 changes: 15 additions & 0 deletions tests/ui/mir/unsize-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Check that the interpreter does not ICE when trying to unsize `B` to `[u8]`.
// This is a `build` test to ensure that const-prop-lint runs.
// build-pass

#![feature(unsize)]

fn foo<B>(buffer: &mut [B; 2])
where B: std::marker::Unsize<[u8]>,
{
let buffer: &[u8] = &buffer[0];
}

fn main() {
foo(&mut [[0], [5]]);
}

0 comments on commit 3ae047b

Please sign in to comment.