From 42c00cb6479d6e03742968e06c6d280a272acd53 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 20 Dec 2024 16:57:14 +0100 Subject: [PATCH 1/3] split up `#[rustc_deny_explicit_impl]` attribute This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`. This allows us to have special traits that can have user-defined impls but do not have the automatic trait impl for trait objects (`impl Trait for dyn Trait`). --- compiler/rustc_feature/src/builtin_attrs.rs | 11 +++- .../rustc_hir_analysis/src/coherence/mod.rs | 4 +- compiler/rustc_hir_analysis/src/collect.rs | 45 +---------------- compiler/rustc_middle/src/ty/trait_def.rs | 4 +- compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/future/async_drop.rs | 4 +- library/core/src/marker.rs | 24 ++++++--- library/core/src/mem/transmutability.rs | 4 +- library/core/src/ptr/metadata.rs | 4 +- .../deny-builtin-object-impl.current.stderr | 50 ++++++++++++++----- .../deny-builtin-object-impl.next.stderr | 50 ++++++++++++++----- tests/ui/traits/deny-builtin-object-impl.rs | 41 +++++++++++---- 13 files changed, 152 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4b9f62fa764c0..63e5ebb8688f6 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -912,11 +912,20 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, - template!(List: "implement_via_object = (true|false)"), + template!(Word), ErrorFollowing, EncodeCrossCrate::No, "#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls" ), + rustc_attr!( + rustc_do_not_implement_via_object, + AttributeType::Normal, + template!(Word), + ErrorFollowing, + EncodeCrossCrate::No, + "#[rustc_do_not_implement_via_object] opts out of the automatic trait impl for trait objects \ + (`impl Trait for dyn Trait`)" + ), rustc_attr!( rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 3aad4bafeb5ab..1be4aa2f63ac4 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -206,7 +206,9 @@ fn check_object_overlap<'tcx>( // so this is valid. } else { let mut supertrait_def_ids = tcx.supertrait_def_ids(component_def_id); - if supertrait_def_ids.any(|d| d == trait_def_id) { + if supertrait_def_ids + .any(|d| d == trait_def_id && tcx.trait_def(d).implement_via_object) + { let span = tcx.def_span(impl_def_id); return Err(struct_span_code_err!( tcx.dcx(), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 5e662bb96bc44..ada70117b626f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1261,49 +1261,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - let mut deny_explicit_impl = false; - let mut implement_via_object = true; - if let Some(attr) = tcx.get_attr(def_id, sym::rustc_deny_explicit_impl) { - deny_explicit_impl = true; - let mut seen_attr = false; - for meta in attr.meta_item_list().iter().flatten() { - if let Some(meta) = meta.meta_item() - && meta.name_or_empty() == sym::implement_via_object - && let Some(lit) = meta.name_value_literal() - { - if seen_attr { - tcx.dcx().span_err(meta.span, "duplicated `implement_via_object` meta item"); - } - seen_attr = true; - - match lit.symbol { - kw::True => { - implement_via_object = true; - } - kw::False => { - implement_via_object = false; - } - _ => { - tcx.dcx().span_err( - meta.span, - format!( - "unknown literal passed to `implement_via_object` attribute: {}", - lit.symbol - ), - ); - } - } - } else { - tcx.dcx().span_err( - meta.span(), - format!("unknown meta item passed to `rustc_deny_explicit_impl` {meta:?}"), - ); - } - } - if !seen_attr { - tcx.dcx().span_err(attr.span, "missing `implement_via_object` meta item"); - } - } + let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl); + let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object); ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 188107e5d5498..743ea33b20a27 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -70,12 +70,12 @@ pub struct TraitDef { /// Whether to add a builtin `dyn Trait: Trait` implementation. /// This is enabled for all traits except ones marked with - /// `#[rustc_deny_explicit_impl(implement_via_object = false)]`. + /// `#[rustc_do_not_implement_via_object]`. pub implement_via_object: bool, /// Whether a trait is fully built-in, and any implementation is disallowed. /// This only applies to built-in traits, and is marked via - /// `#[rustc_deny_explicit_impl(implement_via_object = ...)]`. + /// `#[rustc_deny_explicit_impl]`. pub deny_explicit_impl: bool, } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2310dd9dc72db..1f2d5671f7a84 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -186,6 +186,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_coinductive, ..] | [sym::rustc_must_implement_one_of, ..] | [sym::rustc_deny_explicit_impl, ..] + | [sym::rustc_do_not_implement_via_object, ..] | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a7ff0576f92d6..123e4b1f01f26 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1717,6 +1717,7 @@ symbols! { rustc_diagnostic_macros, rustc_dirty, rustc_do_not_const_check, + rustc_do_not_implement_via_object, rustc_doc_primitive, rustc_driver, rustc_dummy, diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs index 7de5fe67cd096..ea6d3b800e64d 100644 --- a/library/core/src/future/async_drop.rs +++ b/library/core/src/future/async_drop.rs @@ -133,7 +133,9 @@ pub trait AsyncDrop { } #[lang = "async_destruct"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] trait AsyncDestruct { type AsyncDestructor: Future; } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 1620b949590d0..31b27b7ef2641 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -141,7 +141,9 @@ unsafe impl Send for &T {} )] #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable #[rustc_specialization_trait] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] #[rustc_coinductive] pub trait Sized { // Empty. @@ -181,7 +183,9 @@ pub trait Sized { /// [^1]: Formerly known as *object safe*. #[unstable(feature = "unsize", issue = "18598")] #[lang = "unsize"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait Unsize { // Empty. } @@ -815,7 +819,9 @@ impl StructuralPartialEq for PhantomData {} reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead" )] #[lang = "discriminant_kind"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait DiscriminantKind { /// The type of the discriminant, which must satisfy the trait /// bounds required by `mem::Discriminant`. @@ -956,7 +962,9 @@ marker_impls! { #[unstable(feature = "const_destruct", issue = "133214")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] #[cfg_attr(not(bootstrap), const_trait)] pub trait Destruct {} @@ -967,7 +975,9 @@ pub trait Destruct {} #[unstable(feature = "tuple_trait", issue = "none")] #[lang = "tuple_trait"] #[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple")] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait Tuple {} /// A marker for pointer-like types. @@ -1068,7 +1078,9 @@ marker_impls! { reason = "internal trait for implementing various traits for all function pointers" )] #[lang = "fn_ptr_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait FnPtr: Copy + Clone { /// Returns the address of the function pointer. #[lang = "fn_ptr_addr"] diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index 7fa3c33439170..9cf587650d949 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -84,7 +84,9 @@ use crate::marker::{ConstParamTy_, UnsizedConstParamTy}; /// `usize` is stable, but not portable. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] #[rustc_coinductive] pub unsafe trait TransmuteFrom where diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index ae9810e558aa1..b1d5e1fa3a059 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -53,7 +53,9 @@ use crate::ptr::NonNull; /// /// [`to_raw_parts`]: *const::to_raw_parts #[lang = "pointee_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait Pointee { /// The type for metadata in pointers and references to `Self`. #[lang = "metadata_type"] diff --git a/tests/ui/traits/deny-builtin-object-impl.current.stderr b/tests/ui/traits/deny-builtin-object-impl.current.stderr index 8423a2519b23b..d6f4762d09966 100644 --- a/tests/ui/traits/deny-builtin-object-impl.current.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.current.stderr @@ -1,20 +1,44 @@ -error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:19:23 +error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted + --> $DIR/deny-builtin-object-impl.rs:20:1 | -LL | test_not_object::(); - | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` +LL | impl NotImplYesObject for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `NotImplYesObject` not allowed + +error[E0277]: the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:37:32 + | +LL | test_not_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:12:1 + | +LL | trait NotImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_not_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:28:32 + | +LL | fn test_not_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_not_impl_not_object` + +error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:40:32 + | +LL | test_yes_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` | help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:11:1 + --> $DIR/deny-builtin-object-impl.rs:15:1 | -LL | trait NotObject {} - | ^^^^^^^^^^^^^^^ -note: required by a bound in `test_not_object` - --> $DIR/deny-builtin-object-impl.rs:15:23 +LL | trait YesImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_yes_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:30:32 | -LL | fn test_not_object() {} - | ^^^^^^^^^ required by this bound in `test_not_object` +LL | fn test_yes_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0322. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/deny-builtin-object-impl.next.stderr b/tests/ui/traits/deny-builtin-object-impl.next.stderr index 8423a2519b23b..d6f4762d09966 100644 --- a/tests/ui/traits/deny-builtin-object-impl.next.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.next.stderr @@ -1,20 +1,44 @@ -error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:19:23 +error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted + --> $DIR/deny-builtin-object-impl.rs:20:1 | -LL | test_not_object::(); - | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` +LL | impl NotImplYesObject for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `NotImplYesObject` not allowed + +error[E0277]: the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:37:32 + | +LL | test_not_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:12:1 + | +LL | trait NotImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_not_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:28:32 + | +LL | fn test_not_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_not_impl_not_object` + +error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:40:32 + | +LL | test_yes_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` | help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:11:1 + --> $DIR/deny-builtin-object-impl.rs:15:1 | -LL | trait NotObject {} - | ^^^^^^^^^^^^^^^ -note: required by a bound in `test_not_object` - --> $DIR/deny-builtin-object-impl.rs:15:23 +LL | trait YesImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_yes_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:30:32 | -LL | fn test_not_object() {} - | ^^^^^^^^^ required by this bound in `test_not_object` +LL | fn test_yes_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0322. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/deny-builtin-object-impl.rs b/tests/ui/traits/deny-builtin-object-impl.rs index c16dcca8fbc27..9d02ab7bd469e 100644 --- a/tests/ui/traits/deny-builtin-object-impl.rs +++ b/tests/ui/traits/deny-builtin-object-impl.rs @@ -4,18 +4,41 @@ #![feature(rustc_attrs)] -#[rustc_deny_explicit_impl(implement_via_object = true)] -trait YesObject {} +#[rustc_deny_explicit_impl] +trait NotImplYesObject {} -#[rustc_deny_explicit_impl(implement_via_object = false)] -trait NotObject {} +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] +trait NotImplNotObject {} -fn test_yes_object() {} +#[rustc_do_not_implement_via_object] +trait YesImplNotObject {} -fn test_not_object() {} +#[rustc_do_not_implement_via_object] +trait YesImplNotObject2 {} + +impl NotImplYesObject for () {} +//~^ ERROR explicit impls for the `NotImplYesObject` trait are not permitted + +// If there is no automatic impl then we can add a manual impl: +impl YesImplNotObject2 for dyn YesImplNotObject2 {} + +fn test_not_impl_yes_object() {} + +fn test_not_impl_not_object() {} + +fn test_yes_impl_not_object() {} + +fn test_yes_impl_not_object2() {} fn main() { - test_yes_object::(); - test_not_object::(); - //~^ ERROR the trait bound `dyn NotObject: NotObject` is not satisfied + test_not_impl_yes_object::(); + + test_not_impl_not_object::(); + //~^ ERROR the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + + test_yes_impl_not_object::(); + //~^ ERROR the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + + test_yes_impl_not_object2::(); } From 971a4f2d3b0c44fae115b39e4fa9607a911ed59c Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 20 Dec 2024 17:35:29 +0100 Subject: [PATCH 2/3] unimplement `PointerLike` for trait objects --- library/core/src/marker.rs | 1 + tests/ui/dyn-star/dyn-pointer-like.rs | 23 +++++++++++++ tests/ui/dyn-star/dyn-pointer-like.stderr | 39 +++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 tests/ui/dyn-star/dyn-pointer-like.rs create mode 100644 tests/ui/dyn-star/dyn-pointer-like.stderr diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 31b27b7ef2641..bdfa162919f21 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -990,6 +990,7 @@ pub trait Tuple {} message = "`{Self}` needs to have the same ABI as a pointer", label = "`{Self}` needs to be a pointer-like type" )] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait PointerLike {} #[cfg(not(bootstrap))] diff --git a/tests/ui/dyn-star/dyn-pointer-like.rs b/tests/ui/dyn-star/dyn-pointer-like.rs new file mode 100644 index 0000000000000..f26fa90505cf7 --- /dev/null +++ b/tests/ui/dyn-star/dyn-pointer-like.rs @@ -0,0 +1,23 @@ +// Test that `dyn PointerLike` and `dyn* PointerLike` do not implement `PointerLike`. +// This used to ICE during codegen. + +#![crate_type = "lib"] + +#![feature(pointer_like_trait, dyn_star)] +#![feature(unsized_fn_params)] +#![expect(incomplete_features)] +#![expect(internal_features)] + +use std::marker::PointerLike; + +pub fn lol(x: dyn* PointerLike) { + foo(x); //~ ERROR `dyn* PointerLike` needs to have the same ABI as a pointer +} + +pub fn uwu(x: dyn PointerLike) { + foo(x); //~ ERROR `dyn PointerLike` needs to have the same ABI as a pointer +} + +fn foo(x: T) { + let _: dyn* PointerLike = x; +} diff --git a/tests/ui/dyn-star/dyn-pointer-like.stderr b/tests/ui/dyn-star/dyn-pointer-like.stderr new file mode 100644 index 0000000000000..4c558e92d3f91 --- /dev/null +++ b/tests/ui/dyn-star/dyn-pointer-like.stderr @@ -0,0 +1,39 @@ +error[E0277]: `dyn* PointerLike` needs to have the same ABI as a pointer + --> $DIR/dyn-pointer-like.rs:14:9 + | +LL | foo(x); + | --- ^ the trait `PointerLike` is not implemented for `dyn* PointerLike` + | | + | required by a bound introduced by this call + | + = note: the trait bound `dyn* PointerLike: PointerLike` is not satisfied +note: required by a bound in `foo` + --> $DIR/dyn-pointer-like.rs:21:11 + | +LL | fn foo(x: T) { + | ^^^^^^^^^^^ required by this bound in `foo` +help: consider borrowing here + | +LL | foo(&x); + | + +LL | foo(&mut x); + | ++++ + +error[E0277]: `dyn PointerLike` needs to have the same ABI as a pointer + --> $DIR/dyn-pointer-like.rs:18:9 + | +LL | foo(x); + | --- ^ `dyn PointerLike` needs to be a pointer-like type + | | + | required by a bound introduced by this call + | + = help: the trait `PointerLike` is not implemented for `dyn PointerLike` +note: required by a bound in `foo` + --> $DIR/dyn-pointer-like.rs:21:11 + | +LL | fn foo(x: T) { + | ^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 159dba89efa23c36eca92f1b63176314c357d2a4 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 20 Dec 2024 17:37:34 +0100 Subject: [PATCH 3/3] fix `PointerLike` docs --- library/core/src/marker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index bdfa162919f21..3d79706f8ecf9 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -982,8 +982,8 @@ pub trait Tuple {} /// A marker for pointer-like types. /// -/// All types that have the same size and alignment as a `usize` or -/// `*const ()` automatically implement this trait. +/// This trait can only be implemented for types that have the same size and alignment +/// as a `usize` or `*const ()`. #[unstable(feature = "pointer_like_trait", issue = "none")] #[lang = "pointer_like"] #[diagnostic::on_unimplemented(