mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
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
This commit is contained in:
commit
32dde232d8
@ -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 {
|
||||
|
24
src/test/ui/const_prop/issue-102553.rs
Normal file
24
src/test/ui/const_prop/issue-102553.rs
Normal file
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user