about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs85
-rw-r--r--compiler/rustc_middle/src/ty/context.rs14
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs26
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs31
-rw-r--r--compiler/rustc_type_ir/src/interner.rs9
-rw-r--r--compiler/rustc_type_ir/src/lang_items.rs1
-rw-r--r--library/alloc/src/boxed.rs6
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/marker.rs12
-rw-r--r--tests/crashes/113280.rs16
-rw-r--r--tests/crashes/127676.rs8
-rw-r--r--tests/ui/dyn-star/async-block-dyn-star.rs9
-rw-r--r--tests/ui/dyn-star/async-block-dyn-star.stderr20
-rw-r--r--tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr11
-rw-r--r--tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr11
-rw-r--r--tests/ui/dyn-star/drop.rs7
-rw-r--r--tests/ui/dyn-star/enum-cast.rs7
-rw-r--r--tests/ui/dyn-star/error.rs2
-rw-r--r--tests/ui/dyn-star/error.stderr4
-rw-r--r--tests/ui/dyn-star/float-as-dyn-star.rs16
-rw-r--r--tests/ui/dyn-star/float-as-dyn-star.stderr21
-rw-r--r--tests/ui/dyn-star/upcast.stderr10
25 files changed, 195 insertions, 156 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index c2ad61820a7..3b49bc41ffe 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -37,22 +37,19 @@ pub(super) fn check_trait<'tcx>(
 ) -> Result<(), ErrorGuaranteed> {
     let lang_items = tcx.lang_items();
     let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header };
-    let mut res = checker.check(lang_items.drop_trait(), visit_implementation_of_drop);
-    res = res.and(checker.check(lang_items.copy_trait(), visit_implementation_of_copy));
-    res = res.and(checker.check(lang_items.const_param_ty_trait(), |checker| {
+    checker.check(lang_items.drop_trait(), visit_implementation_of_drop)?;
+    checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?;
+    checker.check(lang_items.const_param_ty_trait(), |checker| {
         visit_implementation_of_const_param_ty(checker, LangItem::ConstParamTy)
-    }));
-    res = res.and(checker.check(lang_items.unsized_const_param_ty_trait(), |checker| {
+    })?;
+    checker.check(lang_items.unsized_const_param_ty_trait(), |checker| {
         visit_implementation_of_const_param_ty(checker, LangItem::UnsizedConstParamTy)
-    }));
-
-    res = res.and(
-        checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized),
-    );
-    res.and(
-        checker
-            .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn),
-    )
+    })?;
+    checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?;
+    checker
+        .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?;
+    checker.check(lang_items.pointer_like(), visit_implementation_of_pointer_like)?;
+    Ok(())
 }
 
 struct Checker<'tcx> {
@@ -663,3 +660,63 @@ fn infringing_fields_error<'tcx>(
 
     err.emit()
 }
+
+fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
+    let tcx = checker.tcx;
+    let typing_env = ty::TypingEnv::non_body_analysis(tcx, checker.impl_def_id);
+    let impl_span = tcx.def_span(checker.impl_def_id);
+    let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty();
+
+    // If an ADT is repr(transparent)...
+    if let ty::Adt(def, args) = *self_ty.kind()
+        && def.repr().transparent()
+    {
+        // FIXME(compiler-errors): This should and could be deduplicated into a query.
+        // Find the nontrivial field.
+        let adt_typing_env = ty::TypingEnv::non_body_analysis(tcx, def.did());
+        let nontrivial_field = def.all_fields().find(|field_def| {
+            let field_ty = tcx.type_of(field_def.did).instantiate_identity();
+            !tcx.layout_of(adt_typing_env.as_query_input(field_ty))
+                .is_ok_and(|layout| layout.layout.is_1zst())
+        });
+
+        if let Some(nontrivial_field) = nontrivial_field {
+            // Check that the nontrivial field implements `PointerLike`.
+            let nontrivial_field = nontrivial_field.ty(tcx, args);
+            let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
+            let ocx = ObligationCtxt::new(&infcx);
+            ocx.register_bound(
+                ObligationCause::misc(impl_span, checker.impl_def_id),
+                param_env,
+                nontrivial_field,
+                tcx.lang_items().pointer_like().unwrap(),
+            );
+            // FIXME(dyn-star): We should regionck this implementation.
+            if ocx.select_all_or_error().is_empty() {
+                return Ok(());
+            }
+        }
+    }
+
+    let is_permitted_primitive = match *self_ty.kind() {
+        ty::Adt(def, _) => def.is_box(),
+        ty::Uint(..) | ty::Int(..) | ty::RawPtr(..) | ty::Ref(..) | ty::FnPtr(..) => true,
+        _ => false,
+    };
+
+    if is_permitted_primitive
+        && let Ok(layout) = tcx.layout_of(typing_env.as_query_input(self_ty))
+        && layout.layout.is_pointer_like(&tcx.data_layout)
+    {
+        return Ok(());
+    }
+
+    Err(tcx
+        .dcx()
+        .struct_span_err(
+            impl_span,
+            "implementation must be applied to type that has the same ABI as a pointer, \
+            or is `repr(transparent)` and whose field is `PointerLike`",
+        )
+        .emit())
+}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index ad42eacf823..b4d29f08a0f 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -602,19 +602,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.coroutine_is_async_gen(coroutine_def_id)
     }
 
-    // We don't use `TypingEnv` here as it's only defined in `rustc_middle` and
-    // `rustc_next_trait_solver` shouldn't have to know about it.
-    fn layout_is_pointer_like(
-        self,
-        typing_mode: ty::TypingMode<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        ty: Ty<'tcx>,
-    ) -> bool {
-        let typing_env = ty::TypingEnv { typing_mode, param_env };
-        self.layout_of(self.erase_regions(typing_env).as_query_input(self.erase_regions(ty)))
-            .is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
-    }
-
     type UnsizingParams = &'tcx rustc_index::bit_set::BitSet<u32>;
     fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
         self.unsizing_params_for_adt(adt_def_id)
@@ -688,7 +675,6 @@ bidirectional_lang_item_map! {
     Metadata,
     Option,
     PointeeTrait,
-    PointerLike,
     Poll,
     Sized,
     TransmuteTrait,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index ebf7372926f..78344571088 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -159,13 +159,6 @@ where
         goal: Goal<I, Self>,
     ) -> Result<Candidate<I>, NoSolution>;
 
-    /// A type is `PointerLike` if we can compute its layout, and that layout
-    /// matches the layout of `usize`.
-    fn consider_builtin_pointer_like_candidate(
-        ecx: &mut EvalCtxt<'_, D>,
-        goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution>;
-
     /// A type is a `FnPtr` if it is of `FnPtr` type.
     fn consider_builtin_fn_ptr_trait_candidate(
         ecx: &mut EvalCtxt<'_, D>,
@@ -449,9 +442,6 @@ where
                         ty::ClosureKind::FnOnce,
                     )
                 }
-                Some(TraitSolverLangItem::PointerLike) => {
-                    G::consider_builtin_pointer_like_candidate(self, goal)
-                }
                 Some(TraitSolverLangItem::FnPtrTrait) => {
                     G::consider_builtin_fn_ptr_trait_candidate(self, goal)
                 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 282ca2fedbc..1f5ca71dd6f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -210,13 +210,6 @@ where
         Err(NoSolution)
     }
 
-    fn consider_builtin_pointer_like_candidate(
-        _ecx: &mut EvalCtxt<'_, D>,
-        _goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution> {
-        unreachable!("PointerLike is not const")
-    }
-
     fn consider_builtin_fn_ptr_trait_candidate(
         _ecx: &mut EvalCtxt<'_, D>,
         _goal: Goal<I, Self>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 8a01659953d..6b407640426 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -363,13 +363,6 @@ where
         panic!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
     }
 
-    fn consider_builtin_pointer_like_candidate(
-        _ecx: &mut EvalCtxt<'_, D>,
-        goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution> {
-        panic!("`PointerLike` does not have an associated type: {:?}", goal);
-    }
-
     fn consider_builtin_fn_ptr_trait_candidate(
         _ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index e64d4eed9d8..ce16258d180 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -248,32 +248,6 @@ where
         )
     }
 
-    fn consider_builtin_pointer_like_candidate(
-        ecx: &mut EvalCtxt<'_, D>,
-        goal: Goal<I, Self>,
-    ) -> Result<Candidate<I>, NoSolution> {
-        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
-            return Err(NoSolution);
-        }
-
-        let cx = ecx.cx();
-        // But if there are inference variables, we have to wait until it's resolved.
-        if (goal.param_env, goal.predicate.self_ty()).has_non_region_infer() {
-            return ecx.forced_ambiguity(MaybeCause::Ambiguity);
-        }
-
-        if cx.layout_is_pointer_like(
-            ecx.typing_mode(goal.param_env),
-            goal.param_env,
-            goal.predicate.self_ty(),
-        ) {
-            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
-                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
-        } else {
-            Err(NoSolution)
-        }
-    }
-
     fn consider_builtin_fn_ptr_trait_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 1e0c487c4d4..345e1cc31f3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -111,8 +111,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 self.assemble_candidates_for_transmutability(obligation, &mut candidates);
             } else if tcx.is_lang_item(def_id, LangItem::Tuple) {
                 self.assemble_candidate_for_tuple(obligation, &mut candidates);
-            } else if tcx.is_lang_item(def_id, LangItem::PointerLike) {
-                self.assemble_candidate_for_pointer_like(obligation, &mut candidates);
             } else if tcx.is_lang_item(def_id, LangItem::FnPtrTrait) {
                 self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
             } else {
@@ -1216,35 +1214,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
     }
 
-    fn assemble_candidate_for_pointer_like(
-        &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
-        candidates: &mut SelectionCandidateSet<'tcx>,
-    ) {
-        // The regions of a type don't affect the size of the type
-        let tcx = self.tcx();
-        let self_ty = tcx.instantiate_bound_regions_with_erased(obligation.predicate.self_ty());
-
-        // But if there are inference variables, we have to wait until it's resolved.
-        if (obligation.param_env, self_ty).has_non_region_infer() {
-            candidates.ambiguous = true;
-            return;
-        }
-
-        // We should erase regions from both the param-env and type, since both
-        // may have infer regions. Specifically, after canonicalizing and instantiating,
-        // early bound regions turn into region vars in both the new and old solver.
-        let key = self.infcx.pseudo_canonicalize_query(
-            tcx.erase_regions(obligation.param_env),
-            tcx.erase_regions(self_ty),
-        );
-        if let Ok(layout) = tcx.layout_of(key)
-            && layout.layout.is_pointer_like(&tcx.data_layout)
-        {
-            candidates.vec.push(BuiltinCandidate { has_nested: false });
-        }
-    }
-
     fn assemble_candidates_for_fn_ptr_trait(
         &mut self,
         obligation: &PolyTraitObligation<'tcx>,
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 6e6cf91d855..4e1715dbd0f 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -13,7 +13,7 @@ use crate::lang_items::TraitSolverLangItem;
 use crate::relate::Relate;
 use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult};
 use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
-use crate::{self as ty, TypingMode, search_graph};
+use crate::{self as ty, search_graph};
 
 pub trait Interner:
     Sized
@@ -278,13 +278,6 @@ pub trait Interner:
     fn coroutine_is_gen(self, coroutine_def_id: Self::DefId) -> bool;
     fn coroutine_is_async_gen(self, coroutine_def_id: Self::DefId) -> bool;
 
-    fn layout_is_pointer_like(
-        self,
-        typing_mode: TypingMode<Self>,
-        param_env: Self::ParamEnv,
-        ty: Self::Ty,
-    ) -> bool;
-
     type UnsizingParams: Deref<Target = BitSet<u32>>;
     fn unsizing_params_for_adt(self, adt_def_id: Self::DefId) -> Self::UnsizingParams;
 
diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs
index d6ca22a90a4..df43346065d 100644
--- a/compiler/rustc_type_ir/src/lang_items.rs
+++ b/compiler/rustc_type_ir/src/lang_items.rs
@@ -31,7 +31,6 @@ pub enum TraitSolverLangItem {
     Metadata,
     Option,
     PointeeTrait,
-    PointerLike,
     Poll,
     Sized,
     TransmuteTrait,
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index ac3e4626ee5..ee60ec0fbac 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -191,6 +191,8 @@ use core::error::{self, Error};
 use core::fmt;
 use core::future::Future;
 use core::hash::{Hash, Hasher};
+#[cfg(not(bootstrap))]
+use core::marker::PointerLike;
 use core::marker::{Tuple, Unsize};
 use core::mem::{self, SizedTypeProperties};
 use core::ops::{
@@ -2131,3 +2133,7 @@ impl<E: Error> Error for Box<E> {
         Error::provide(&**self, request);
     }
 }
+
+#[cfg(not(bootstrap))]
+#[unstable(feature = "pointer_like_trait", issue = "none")]
+impl<T> PointerLike for Box<T> {}
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 7839fe04b8d..041ff37897f 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -136,6 +136,7 @@
 #![feature(panic_internals)]
 #![feature(pattern)]
 #![feature(pin_coerce_unsized_trait)]
+#![feature(pointer_like_trait)]
 #![feature(ptr_internals)]
 #![feature(ptr_metadata)]
 #![feature(ptr_sub_ptr)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1c5c58d64a2..c8ea52a1fb0 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -981,6 +981,18 @@ pub trait Tuple {}
 )]
 pub trait PointerLike {}
 
+#[cfg(not(bootstrap))]
+marker_impls! {
+    #[unstable(feature = "pointer_like_trait", issue = "none")]
+    PointerLike for
+        usize,
+        {T} &T,
+        {T} &mut T,
+        {T} *const T,
+        {T} *mut T,
+        {T: PointerLike} crate::pin::Pin<T>,
+}
+
 /// A marker for types which can be used as types of `const` generic parameters.
 ///
 /// These types must have a proper equivalence relation (`Eq`) and it must be automatically
diff --git a/tests/crashes/113280.rs b/tests/crashes/113280.rs
deleted file mode 100644
index 86677f416fe..00000000000
--- a/tests/crashes/113280.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: #113280
-//@ only-x86_64
-
-#![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 {
-    f32::from_bits(0x1) as f64
-}
-
-fn main() {
-    println!("{:?}", make_dyn_star(Box::new(1i32)));
-}
diff --git a/tests/crashes/127676.rs b/tests/crashes/127676.rs
deleted file mode 100644
index 81149c2ef84..00000000000
--- a/tests/crashes/127676.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #127676
-//@ edition:2018
-
-#![feature(dyn_star,const_async_blocks)]
-
-static S: dyn* Send + Sync = async { 42 };
-
-pub fn main() {}
diff --git a/tests/ui/dyn-star/async-block-dyn-star.rs b/tests/ui/dyn-star/async-block-dyn-star.rs
new file mode 100644
index 00000000000..9bffd6c6725
--- /dev/null
+++ b/tests/ui/dyn-star/async-block-dyn-star.rs
@@ -0,0 +1,9 @@
+//@ edition:2018
+
+#![feature(dyn_star, const_async_blocks)]
+//~^ WARN the feature `dyn_star` is incomplete
+
+static S: dyn* Send + Sync = async { 42 };
+//~^ needs to have the same ABI as a pointer
+
+pub fn main() {}
diff --git a/tests/ui/dyn-star/async-block-dyn-star.stderr b/tests/ui/dyn-star/async-block-dyn-star.stderr
new file mode 100644
index 00000000000..f62c85c0ad2
--- /dev/null
+++ b/tests/ui/dyn-star/async-block-dyn-star.stderr
@@ -0,0 +1,20 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/async-block-dyn-star.rs:3:12
+   |
+LL | #![feature(dyn_star, const_async_blocks)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `{async block@$DIR/async-block-dyn-star.rs:6:30: 6:35}` needs to have the same ABI as a pointer
+  --> $DIR/async-block-dyn-star.rs:6:30
+   |
+LL | static S: dyn* Send + Sync = async { 42 };
+   |                              ^^^^^^^^^^^^ `{async block@$DIR/async-block-dyn-star.rs:6:30: 6:35}` needs to be a pointer-like type
+   |
+   = help: the trait `PointerLike` is not implemented for `{async block@$DIR/async-block-dyn-star.rs:6:30: 6:35}`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr
index 7b5ea7bb707..a0aff69f396 100644
--- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr
+++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr
@@ -1,14 +1,17 @@
 error[E0277]: `&T` needs to have the same ABI as a pointer
   --> $DIR/check-size-at-cast-polymorphic-bad.rs:15:15
    |
+LL | fn polymorphic<T: Debug + ?Sized>(t: &T) {
+   |                - this type parameter needs to be `Sized`
 LL |     dyn_debug(t);
    |               ^ `&T` needs to be a pointer-like type
    |
-   = help: the trait `PointerLike` is not implemented for `&T`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   = note: required for `&T` to implement `PointerLike`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL - fn polymorphic<T: Debug + ?Sized>(t: &T) {
+LL + fn polymorphic<T: Debug>(t: &T) {
    |
-LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerLike {
-   |                                          +++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr
index 7b5ea7bb707..a0aff69f396 100644
--- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr
+++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr
@@ -1,14 +1,17 @@
 error[E0277]: `&T` needs to have the same ABI as a pointer
   --> $DIR/check-size-at-cast-polymorphic-bad.rs:15:15
    |
+LL | fn polymorphic<T: Debug + ?Sized>(t: &T) {
+   |                - this type parameter needs to be `Sized`
 LL |     dyn_debug(t);
    |               ^ `&T` needs to be a pointer-like type
    |
-   = help: the trait `PointerLike` is not implemented for `&T`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   = note: required for `&T` to implement `PointerLike`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL - fn polymorphic<T: Debug + ?Sized>(t: &T) {
+LL + fn polymorphic<T: Debug>(t: &T) {
    |
-LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerLike {
-   |                                          +++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/dyn-star/drop.rs b/tests/ui/dyn-star/drop.rs
index ca86f1b5b01..bc746331527 100644
--- a/tests/ui/dyn-star/drop.rs
+++ b/tests/ui/dyn-star/drop.rs
@@ -1,13 +1,18 @@
 //@ run-pass
 //@ check-run-results
-#![feature(dyn_star)]
+#![feature(dyn_star, pointer_like_trait)]
 #![allow(incomplete_features)]
 
 use std::fmt::Debug;
+use std::marker::PointerLike;
 
 #[derive(Debug)]
+#[repr(transparent)]
 struct Foo(#[allow(dead_code)] usize);
 
+// FIXME(dyn_star): Make this into a derive.
+impl PointerLike for Foo {}
+
 impl Drop for Foo {
     fn drop(&mut self) {
         println!("destructor called");
diff --git a/tests/ui/dyn-star/enum-cast.rs b/tests/ui/dyn-star/enum-cast.rs
index 6e895e9527a..3cc7390eb12 100644
--- a/tests/ui/dyn-star/enum-cast.rs
+++ b/tests/ui/dyn-star/enum-cast.rs
@@ -3,13 +3,18 @@
 // This used to ICE, because the compiler confused a pointer-like to dyn* coercion
 // with a c-like enum to integer cast.
 
-#![feature(dyn_star)]
+#![feature(dyn_star, pointer_like_trait)]
 #![expect(incomplete_features)]
 
+use std::marker::PointerLike;
+
+#[repr(transparent)]
 enum E {
     Num(usize),
 }
 
+impl PointerLike for E {}
+
 trait Trait {}
 impl Trait for E {}
 
diff --git a/tests/ui/dyn-star/error.rs b/tests/ui/dyn-star/error.rs
index d8261387efa..7288596f3fa 100644
--- a/tests/ui/dyn-star/error.rs
+++ b/tests/ui/dyn-star/error.rs
@@ -7,7 +7,7 @@ trait Foo {}
 
 fn make_dyn_star() {
     let i = 42;
-    let dyn_i: dyn* Foo = i; //~ ERROR trait bound `{integer}: Foo` is not satisfied
+    let dyn_i: dyn* Foo = i; //~ ERROR trait bound `usize: Foo` is not satisfied
 }
 
 fn main() {}
diff --git a/tests/ui/dyn-star/error.stderr b/tests/ui/dyn-star/error.stderr
index a9f4a054519..55981c03bac 100644
--- a/tests/ui/dyn-star/error.stderr
+++ b/tests/ui/dyn-star/error.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `{integer}: Foo` is not satisfied
+error[E0277]: the trait bound `usize: Foo` is not satisfied
   --> $DIR/error.rs:10:27
    |
 LL |     let dyn_i: dyn* Foo = i;
-   |                           ^ the trait `Foo` is not implemented for `{integer}`
+   |                           ^ the trait `Foo` is not implemented for `usize`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/error.rs:6:1
diff --git a/tests/ui/dyn-star/float-as-dyn-star.rs b/tests/ui/dyn-star/float-as-dyn-star.rs
new file mode 100644
index 00000000000..1b629c64c25
--- /dev/null
+++ b/tests/ui/dyn-star/float-as-dyn-star.rs
@@ -0,0 +1,16 @@
+//@ only-x86_64
+
+#![feature(dyn_star, pointer_like_trait)]
+//~^ WARN the feature `dyn_star` is incomplete
+
+use std::fmt::Debug;
+use std::marker::PointerLike;
+
+fn make_dyn_star() -> dyn* Debug + 'static {
+    f32::from_bits(0x1) as f64
+    //~^ ERROR `f64` needs to have the same ABI as a pointer
+}
+
+fn main() {
+    println!("{:?}", make_dyn_star());
+}
diff --git a/tests/ui/dyn-star/float-as-dyn-star.stderr b/tests/ui/dyn-star/float-as-dyn-star.stderr
new file mode 100644
index 00000000000..9caba512e5f
--- /dev/null
+++ b/tests/ui/dyn-star/float-as-dyn-star.stderr
@@ -0,0 +1,21 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/float-as-dyn-star.rs:3:12
+   |
+LL | #![feature(dyn_star, pointer_like_trait)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `f64` needs to have the same ABI as a pointer
+  --> $DIR/float-as-dyn-star.rs:10:5
+   |
+LL |     f32::from_bits(0x1) as f64
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `f64` needs to be a pointer-like type
+   |
+   = help: the trait `PointerLike` is not implemented for `f64`
+   = help: the trait `PointerLike` is implemented for `usize`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/dyn-star/upcast.stderr b/tests/ui/dyn-star/upcast.stderr
index adef9525bf1..801e1c233c1 100644
--- a/tests/ui/dyn-star/upcast.stderr
+++ b/tests/ui/dyn-star/upcast.stderr
@@ -7,6 +7,14 @@ LL | #![feature(dyn_star, trait_upcasting)]
    = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
+error[E0277]: `W` needs to have the same ABI as a pointer
+  --> $DIR/upcast.rs:28:23
+   |
+LL |     let w: dyn* Foo = W(0);
+   |                       ^^^^ `W` needs to be a pointer-like type
+   |
+   = help: the trait `PointerLike` is not implemented for `W`
+
 error[E0277]: `dyn* Foo` needs to have the same ABI as a pointer
   --> $DIR/upcast.rs:30:23
    |
@@ -15,6 +23,6 @@ LL |     let w: dyn* Bar = w;
    |
    = help: the trait `PointerLike` is not implemented for `dyn* Foo`
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0277`.