diff options
| author | Michael Goulet <michael@errs.io> | 2022-10-02 19:20:49 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-10-02 19:21:06 +0000 |
| commit | c7d1ec009c56546268a84525d1cb0797d68997c1 (patch) | |
| tree | 45c0bc1122164adeaec59b784ac328c0b15b2d68 | |
| parent | f914b82a754c6d85c0a909ab152f5b611defef73 (diff) | |
| download | rust-c7d1ec009c56546268a84525d1cb0797d68997c1.tar.gz rust-c7d1ec009c56546268a84525d1cb0797d68997c1.zip | |
Don't ICE when trying to copy unsized value in const prop
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/place.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/const_prop/issue-102553.rs | 24 |
2 files changed, 35 insertions, 5 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 7a01b85381a..eeeb7d6d3e5 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -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 { diff --git a/src/test/ui/const_prop/issue-102553.rs b/src/test/ui/const_prop/issue-102553.rs new file mode 100644 index 00000000000..523a9d7ac72 --- /dev/null +++ b/src/test/ui/const_prop/issue-102553.rs @@ -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) + } +} |
