From 43499da7539d4d0f6bfcea14e19cbe3d7dda4777 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 3 Oct 2022 17:35:03 -0700 Subject: [PATCH 1/3] Support casting boxes to dyn* --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 5 +++++ src/test/ui/dyn-star/box.rs | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/dyn-star/box.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 56852b0fcc821..c8ff26f74e3b5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; +use rustc_target::abi::Size; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "trace", skip(self, bx))] @@ -285,6 +286,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("Only valid to do a DynStar cast into a DynStar type") }; let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref); + let data = match operand.layout.pointee_info_at(bx.cx(), Size::ZERO) { + Some(_) => bx.ptrtoint(data, bx.cx().type_isize()), + None => data, + }; OperandValue::Pair(data, vtable) } mir::CastKind::Pointer( diff --git a/src/test/ui/dyn-star/box.rs b/src/test/ui/dyn-star/box.rs new file mode 100644 index 0000000000000..d1f1819d9f35f --- /dev/null +++ b/src/test/ui/dyn-star/box.rs @@ -0,0 +1,17 @@ +// run-pass +// compile-flags: -C opt-level=0 + +#![feature(dyn_star)] +#![allow(incomplete_features)] + +use std::fmt::Display; + +fn make_dyn_star() -> dyn* Display { + Box::new(42) as dyn* Display +} + +fn main() { + let x = make_dyn_star(); + + println!("{x}"); +} From 0c47fdfedbb44256b3c78f315cd6150190317e38 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 7 Oct 2022 13:05:45 -0700 Subject: [PATCH 2/3] Cast vtable type too --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index c8ff26f74e3b5..5837b4ff2b9de 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -286,6 +286,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("Only valid to do a DynStar cast into a DynStar type") }; let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref); + let vtable = bx.pointercast(vtable, bx.cx().type_ptr_to(bx.cx().type_isize())); let data = match operand.layout.pointee_info_at(bx.cx(), Size::ZERO) { Some(_) => bx.ptrtoint(data, bx.cx().type_isize()), None => data, From 8b2c3ebb86b0f9a1d218daa0bd94096170233b74 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 12 Oct 2022 14:26:22 -0700 Subject: [PATCH 3/3] Add a fixme --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 5837b4ff2b9de..e3491d3675198 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -287,6 +287,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref); let vtable = bx.pointercast(vtable, bx.cx().type_ptr_to(bx.cx().type_isize())); + // FIXME(dyn-star): this is probably not the best way to check if this is + // a pointer, and really we should ensure that the value is a suitable + // pointer earlier in the compilation process. let data = match operand.layout.pointee_info_at(bx.cx(), Size::ZERO) { Some(_) => bx.ptrtoint(data, bx.cx().type_isize()), None => data,