From 06e66d78c3a104b30fd59714d4dbb1a5d9f351bb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 19 Nov 2024 21:23:10 +0000 Subject: [PATCH 1/2] Rip out built-in PointerLike impl --- compiler/rustc_middle/src/ty/context.rs | 14 --------- .../src/solve/assembly/mod.rs | 10 ------ .../src/solve/effect_goals.rs | 7 ----- .../src/solve/normalizes_to/mod.rs | 7 ----- .../src/solve/trait_goals.rs | 26 ---------------- .../src/traits/select/candidate_assembly.rs | 31 ------------------- compiler/rustc_type_ir/src/interner.rs | 9 +----- compiler/rustc_type_ir/src/lang_items.rs | 1 - 8 files changed, 1 insertion(+), 104 deletions(-) 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; 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, ) -> Result, 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, - ) -> Result, 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, - ) -> Result, NoSolution> { - unreachable!("PointerLike is not const") - } - fn consider_builtin_fn_ptr_trait_candidate( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal, 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, - ) -> Result, NoSolution> { - panic!("`PointerLike` does not have an associated type: {:?}", goal); - } - fn consider_builtin_fn_ptr_trait_candidate( _ecx: &mut EvalCtxt<'_, D>, goal: Goal, 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, - ) -> Result, 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, 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, - param_env: Self::ParamEnv, - ty: Self::Ty, - ) -> bool; - type UnsizingParams: Deref>; 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, From 228068bc6efb16f359b5318e66fa789c2f58ce60 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 20 Nov 2024 02:46:56 +0000 Subject: [PATCH 2/2] Make PointerLike opt-in as a trait --- .../src/coherence/builtin.rs | 85 ++++++++++++++++--- library/alloc/src/boxed.rs | 6 ++ library/alloc/src/lib.rs | 1 + library/core/src/marker.rs | 12 +++ tests/crashes/113280.rs | 16 ---- tests/crashes/127676.rs | 8 -- tests/ui/dyn-star/async-block-dyn-star.rs | 9 ++ tests/ui/dyn-star/async-block-dyn-star.stderr | 20 +++++ ...ize-at-cast-polymorphic-bad.current.stderr | 11 ++- ...k-size-at-cast-polymorphic-bad.next.stderr | 11 ++- tests/ui/dyn-star/drop.rs | 7 +- tests/ui/dyn-star/enum-cast.rs | 7 +- tests/ui/dyn-star/error.rs | 2 +- tests/ui/dyn-star/error.stderr | 4 +- tests/ui/dyn-star/float-as-dyn-star.rs | 16 ++++ tests/ui/dyn-star/float-as-dyn-star.stderr | 21 +++++ tests/ui/dyn-star/upcast.stderr | 10 ++- 17 files changed, 194 insertions(+), 52 deletions(-) delete mode 100644 tests/crashes/113280.rs delete mode 100644 tests/crashes/127676.rs create mode 100644 tests/ui/dyn-star/async-block-dyn-star.rs create mode 100644 tests/ui/dyn-star/async-block-dyn-star.stderr create mode 100644 tests/ui/dyn-star/float-as-dyn-star.rs create mode 100644 tests/ui/dyn-star/float-as-dyn-star.stderr 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/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 Error for Box { Error::provide(&**self, request); } } + +#[cfg(not(bootstrap))] +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for Box {} 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, +} + /// 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 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: &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: &T) { +LL + fn polymorphic(t: &T) { | -LL | fn polymorphic(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: &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: &T) { +LL + fn polymorphic(t: &T) { | -LL | fn polymorphic(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 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 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`.