Skip to content

Commit 32dde23

Browse files
authored
Rollup merge of #102559 - compiler-errors:issue-102553, r=oli-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 #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 #102553
2 parents d89d214 + c7d1ec0 commit 32dde23

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

compiler/rustc_const_eval/src/interpret/place.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -640,11 +640,17 @@ where
640640
// avoid force_allocation.
641641
let src = match self.read_immediate_raw(src)? {
642642
Ok(src_val) => {
643-
assert!(!src.layout.is_unsized(), "cannot copy unsized immediates");
644-
assert!(
645-
!dest.layout.is_unsized(),
646-
"the src is sized, so the dest must also be sized"
647-
);
643+
// FIXME(const_prop): Const-prop can possibly evaluate an
644+
// unsized copy operation when it thinks that the type is
645+
// actually sized, due to a trivially false where-clause
646+
// predicate like `where Self: Sized` with `Self = dyn Trait`.
647+
// See #102553 for an example of such a predicate.
648+
if src.layout.is_unsized() {
649+
throw_inval!(SizeOfUnsizedType(src.layout.ty));
650+
}
651+
if dest.layout.is_unsized() {
652+
throw_inval!(SizeOfUnsizedType(dest.layout.ty));
653+
}
648654
assert_eq!(src.layout.size, dest.layout.size);
649655
// Yay, we got a value that we can write directly.
650656
return if layout_compat {
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// compile-flags: --crate-type=lib
2+
// check-pass
3+
4+
pub trait Widget<E> {
5+
fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w>
6+
where
7+
Self: Sized + 'w;
8+
}
9+
10+
pub trait WidgetDyn<E> {}
11+
12+
impl<T, E> WidgetDyn<E> for T where T: Widget<E> {}
13+
14+
impl<E> Widget<E> for dyn WidgetDyn<E> + '_ {
15+
fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w>
16+
where
17+
Self: Sized + 'w,
18+
{
19+
// Even though this is illegal to const evaluate, this should never
20+
// trigger an ICE because it can never be called from actual code
21+
// (due to the trivially false where-clause predicate).
22+
Box::new(self)
23+
}
24+
}

0 commit comments

Comments
 (0)