Skip to content

Commit

Permalink
Rollup merge of rust-lang#102559 - compiler-errors:issue-102553, r=ol…
Browse files Browse the repository at this point in the history
…i-obk

Don't ICE when trying to copy unsized value in const prop

When we have a trivially false where-clause predicate like `Self: Sized` where `Self = dyn Trait`, we sometimes don't throw an error during typeck for an illegal operation such as copying an unsized type.

This, unfortunately, cannot be made into an error (at least not without some migration -- see rust-lang#95611 for example), but we should at least not ICE, since this function will never actually be reachable from main, for example.

r? `@RalfJung` since I think you added these assertions? but feel free to reassign.

Fixes rust-lang#102553
  • Loading branch information
Dylan-DPC authored Oct 4, 2022
2 parents d89d214 + c7d1ec0 commit 32dde23
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
16 changes: 11 additions & 5 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,11 +640,17 @@ where
// avoid force_allocation.
let src = match self.read_immediate_raw(src)? {
Ok(src_val) => {
assert!(!src.layout.is_unsized(), "cannot copy unsized immediates");
assert!(
!dest.layout.is_unsized(),
"the src is sized, so the dest must also be sized"
);
// FIXME(const_prop): Const-prop can possibly evaluate an
// unsized copy operation when it thinks that the type is
// actually sized, due to a trivially false where-clause
// predicate like `where Self: Sized` with `Self = dyn Trait`.
// See #102553 for an example of such a predicate.
if src.layout.is_unsized() {
throw_inval!(SizeOfUnsizedType(src.layout.ty));
}
if dest.layout.is_unsized() {
throw_inval!(SizeOfUnsizedType(dest.layout.ty));
}
assert_eq!(src.layout.size, dest.layout.size);
// Yay, we got a value that we can write directly.
return if layout_compat {
Expand Down
24 changes: 24 additions & 0 deletions src/test/ui/const_prop/issue-102553.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// compile-flags: --crate-type=lib
// check-pass

pub trait Widget<E> {
fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w>
where
Self: Sized + 'w;
}

pub trait WidgetDyn<E> {}

impl<T, E> WidgetDyn<E> for T where T: Widget<E> {}

impl<E> Widget<E> for dyn WidgetDyn<E> + '_ {
fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w>
where
Self: Sized + 'w,
{
// Even though this is illegal to const evaluate, this should never
// trigger an ICE because it can never be called from actual code
// (due to the trivially false where-clause predicate).
Box::new(self)
}
}

0 comments on commit 32dde23

Please sign in to comment.