about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs8
-rw-r--r--tests/ui/dyn-star/llvm-old-style-ptrs.rs23
2 files changed, 31 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 229e3d9dc5f..4e13d4dbcb7 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -273,6 +273,14 @@ pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
         "destination type must be a dyn*"
     );
+    // FIXME(dyn-star): We can remove this when all supported LLVMs use opaque ptrs only.
+    let unit_ptr = bx.cx().type_ptr_to(bx.cx().type_struct(&[], false));
+    let src = match bx.cx().type_kind(bx.cx().backend_type(src_ty_and_layout)) {
+        TypeKind::Pointer => bx.pointercast(src, unit_ptr),
+        TypeKind::Integer => bx.inttoptr(src, unit_ptr),
+        // FIXME(dyn-star): We probably have to do a bitcast first, then inttoptr.
+        kind => bug!("unexpected TypeKind for left-hand side of `dyn*` cast: {kind:?}"),
+    };
     (src, unsized_info(bx, src_ty_and_layout.ty, dst_ty, old_info))
 }
 
diff --git a/tests/ui/dyn-star/llvm-old-style-ptrs.rs b/tests/ui/dyn-star/llvm-old-style-ptrs.rs
new file mode 100644
index 00000000000..d35519632be
--- /dev/null
+++ b/tests/ui/dyn-star/llvm-old-style-ptrs.rs
@@ -0,0 +1,23 @@
+// run-pass
+// compile-flags: -Copt-level=0 -Cllvm-args=-opaque-pointers=0
+
+// (opaque-pointers flag is called force-opaque-pointers in LLVM 13...)
+// min-llvm-version: 14.0
+
+// This test can be removed once non-opaque pointers are gone from LLVM, maybe.
+
+#![feature(dyn_star, pointer_like_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+use std::marker::PointerLike;
+
+fn make_dyn_star<'a>(t: impl PointerLike + Debug + 'a) -> dyn* Debug + 'a {
+    t as _
+}
+
+fn main() {
+    println!("{:?}", make_dyn_star(Box::new(1i32)));
+    println!("{:?}", make_dyn_star(2usize));
+    println!("{:?}", make_dyn_star((3usize,)));
+}