diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 753892d1e9970..96a8551b1f1f7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -94,12 +94,12 @@ impl NoArgsAttributeParser for DenyExplicitImplParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl; } -pub(crate) struct DoNotImplementViaObjectParser; -impl NoArgsAttributeParser for DoNotImplementViaObjectParser { - const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object]; +pub(crate) struct DynIncompatibleTraitParser; +impl NoArgsAttributeParser for DynIncompatibleTraitParser { + const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); - const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::DynIncompatibleTrait; } // Specialization diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 4789f27785cb9..8d8ec77ed7584 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -65,8 +65,8 @@ use crate::attributes::stability::{ use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser}; use crate::attributes::traits::{ AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser, - DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser, - PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + DynIncompatibleTraitParser, FundamentalParser, MarkerParser, ParenSugarParser, PointeeParser, + SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; @@ -220,7 +220,7 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4d50b9683fc57..0d0f0b7a1d9bf 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1289,13 +1289,13 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" ), rustc_attr!( - rustc_do_not_implement_via_object, + rustc_dyn_incompatible_trait, 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_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ + even if it otherwise satisfies the requirements to be dyn-compatible." ), rustc_attr!( rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 7ddd71c346006..446563e74197b 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -520,15 +520,15 @@ pub enum AttributeKind { /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). Deprecation { deprecation: Deprecation, span: Span }, - /// Represents `#[rustc_do_not_implement_via_object]`. - DoNotImplementViaObject(Span), - /// Represents [`#[doc = "..."]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, /// Represents `#[rustc_dummy]`. Dummy, + /// Represents `#[rustc_dyn_incompatible_trait]`. + DynIncompatibleTrait(Span), + /// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute). ExportName { /// The name to export this item with. diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 2ccfdc2ad983d..ac7d1a0114d73 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -39,9 +39,9 @@ impl AttributeKind { DebuggerVisualizer(..) => No, DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, - DoNotImplementViaObject(..) => No, DocComment { .. } => Yes, Dummy => No, + DynIncompatibleTrait(..) => Yes, // FIXME: is this needed? ExportName { .. } => Yes, ExportStable => No, FfiConst(..) => No, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index bc3231cff9b47..58483dc44fe91 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -211,9 +211,7 @@ fn check_object_overlap<'tcx>( // This is a WF error tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`. } else { let mut supertrait_def_ids = elaborate::supertrait_def_ids(tcx, component_def_id); - if supertrait_def_ids - .any(|d| d == trait_def_id && tcx.trait_def(d).implement_via_object) - { + if supertrait_def_ids.any(|d| d == trait_def_id) { 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 a929a9215b3c7..659f91220989f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -996,7 +996,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { }); let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); - let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_)); + let force_dyn_incompatible = + find_attr!(attrs, AttributeKind::DynIncompatibleTrait(span) => *span); ty::TraitDef { def_id: def_id.to_def_id(), @@ -1011,7 +1012,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { skip_boxed_slice_during_method_dispatch, specialization_kind, must_implement_one_of, - implement_via_object, + force_dyn_incompatible, deny_explicit_impl, } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 0c7bddf60d974..ba22bfed62396 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -757,6 +757,9 @@ pub enum DynCompatibilityViolation { /// `Self: Sized` declared on the trait. SizedSelf(SmallVec<[Span; 1]>), + /// Trait is marked `#[rustc_dyn_incompatible_trait]`. + ExplicitlyDynIncompatible(SmallVec<[Span; 1]>), + /// Supertrait reference references `Self` an in illegal location /// (e.g., `trait Foo : Bar`). SupertraitSelf(SmallVec<[Span; 1]>), @@ -781,6 +784,9 @@ impl DynCompatibilityViolation { pub fn error_msg(&self) -> Cow<'static, str> { match self { DynCompatibilityViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), + DynCompatibilityViolation::ExplicitlyDynIncompatible(_) => { + "it opted out of dyn-compatibility".into() + } DynCompatibilityViolation::SupertraitSelf(spans) => { if spans.iter().any(|sp| *sp != DUMMY_SP) { "it uses `Self` as a type parameter".into() @@ -854,6 +860,7 @@ impl DynCompatibilityViolation { pub fn solution(&self) -> DynCompatibilityViolationSolution { match self { DynCompatibilityViolation::SizedSelf(_) + | DynCompatibilityViolation::ExplicitlyDynIncompatible(_) | DynCompatibilityViolation::SupertraitSelf(_) | DynCompatibilityViolation::SupertraitNonLifetimeBinder(..) | DynCompatibilityViolation::SupertraitConst(_) => { @@ -887,6 +894,7 @@ impl DynCompatibilityViolation { match self { DynCompatibilityViolation::SupertraitSelf(spans) | DynCompatibilityViolation::SizedSelf(spans) + | DynCompatibilityViolation::ExplicitlyDynIncompatible(spans) | DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans) | DynCompatibilityViolation::SupertraitConst(spans) => spans.clone(), DynCompatibilityViolation::AssocConst(_, span) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ae83e98f37d27..c6921164f14da 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -709,10 +709,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_def(def_id).is_fundamental } - fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool { - self.trait_def(trait_def_id).implement_via_object - } - fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool { self.trait_def(trait_def_id).safety.is_unsafe() } diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 691cb43b724a4..55445956a0c41 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_macros::{Decodable, Encodable, HashStable}; +use rustc_span::Span; use rustc_span::symbol::sym; use tracing::debug; @@ -69,10 +70,9 @@ pub struct TraitDef { /// must be implemented. pub must_implement_one_of: Option>, - /// Whether to add a builtin `dyn Trait: Trait` implementation. - /// This is enabled for all traits except ones marked with - /// `#[rustc_do_not_implement_via_object]`. - pub implement_via_object: bool, + /// Whether the trait should be considered dyn-incompatible, even if it otherwise + /// satisfies the requirements to be dyn-compatible. + pub force_dyn_incompatible: Option, /// Whether a trait is fully built-in, and any implementation is disallowed. /// This only applies to built-in traits, and is marked via 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 221593d6eadb5..7d94473bb7761 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -788,9 +788,6 @@ where candidates: &mut Vec>, ) { let cx = self.cx(); - if !cx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(cx)) { - return; - } let self_ty = goal.predicate.self_ty(); let bounds = match self_ty.kind() { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 347e103af9378..54a0ece5dc4dd 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -233,7 +233,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::SkipDuringMethodDispatch { .. } | AttributeKind::Coinductive(..) | AttributeKind::DenyExplicitImpl(..) - | AttributeKind::DoNotImplementViaObject(..) + | AttributeKind::DynIncompatibleTrait(..) | AttributeKind::SpecializationTrait(..) | AttributeKind::UnsafeSpecializationMarker(..) | AttributeKind::ParenSugar(..) diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 0afb94c18d7b9..438a01c6b9435 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -1392,7 +1392,7 @@ pub struct TraitDecl { pub skip_boxed_slice_during_method_dispatch: bool, pub specialization_kind: TraitSpecializationKind, pub must_implement_one_of: Option>, - pub implement_via_object: bool, + pub force_dyn_incompatible: Option, pub deny_explicit_impl: bool, } diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 36fc5724d51a9..bf8177f611dcb 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -595,7 +595,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef { .must_implement_one_of .as_ref() .map(|idents| idents.iter().map(|ident| opaque(ident)).collect()), - implement_via_object: self.implement_via_object, + force_dyn_incompatible: self.force_dyn_incompatible.stable(tables, cx), deny_explicit_impl: self.deny_explicit_impl, } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0912bad459da7..f4bd8034fc008 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1921,7 +1921,6 @@ symbols! { rustc_diagnostic_macros, rustc_dirty, rustc_do_not_const_check, - rustc_do_not_implement_via_object, rustc_doc_primitive, rustc_driver, rustc_dummy, @@ -1930,6 +1929,7 @@ symbols! { rustc_dump_predicates, rustc_dump_user_args, rustc_dump_vtable, + rustc_dyn_incompatible_trait, rustc_effective_visibility, rustc_evaluate_where_clauses, rustc_expected_cgu_reuse, diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 6ab92531e4eff..d6c967a588089 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -89,11 +89,18 @@ fn dyn_compatibility_violations_for_trait( .collect(); // Check the trait itself. - if trait_has_sized_self(tcx, trait_def_id) { + let has_sized_self = trait_has_sized_self(tcx, trait_def_id); + if has_sized_self { // We don't want to include the requirement from `Sized` itself to be `Sized` in the list. let spans = get_sized_bounds(tcx, trait_def_id); violations.push(DynCompatibilityViolation::SizedSelf(spans)); } + // only report dyn-incompatible supertraits if there is no `Self: Sized`, + // to avoid duplicate notes about `Sized`. + let trait_def = tcx.trait_def(trait_def_id); + if !has_sized_self && let Some(span) = trait_def.force_dyn_incompatible { + violations.push(DynCompatibilityViolation::ExplicitlyDynIncompatible([span].into())); + } let spans = predicates_reference_self(tcx, trait_def_id, false); if !spans.is_empty() { violations.push(DynCompatibilityViolation::SupertraitSelf(spans)); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 0906284e70196..261d8340dc289 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -799,10 +799,6 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( let tcx = selcx.tcx(); - if !tcx.trait_def(obligation.predicate.trait_def_id(tcx)).implement_via_object { - return; - } - let self_ty = obligation.predicate.self_ty(); let object_ty = selcx.infcx.shallow_resolve(self_ty); let data = match object_ty.kind() { 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 cecb43e537a8e..a4c90bfb0da25 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -904,10 +904,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { "assemble_candidates_from_object_ty", ); - if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object { - return; - } - self.infcx.probe(|_snapshot| { let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| { diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 3884f29a4fc80..b85c5b3760eda 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -377,8 +377,6 @@ pub trait Interner: fn trait_is_fundamental(self, def_id: Self::TraitId) -> bool; - fn trait_may_be_implemented_via_object(self, trait_def_id: Self::TraitId) -> bool; - /// Returns `true` if this is an `unsafe trait`. fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5fd0611a18434..415d6723481ce 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -152,7 +152,7 @@ unsafe impl Send for &T {} #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable #[rustc_specialization_trait] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] // `Sized` being coinductive, despite having supertraits, is okay as there are no user-written impls, // and we know that the supertraits are always implemented if the subtrait is just by looking at // the builtin impls. @@ -171,7 +171,6 @@ pub trait Sized: MetaSized { #[fundamental] #[rustc_specialization_trait] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] // `MetaSized` being coinductive, despite having supertraits, is okay for the same reasons as // `Sized` above. #[rustc_coinductive] @@ -189,7 +188,6 @@ pub trait MetaSized: PointeeSized { #[fundamental] #[rustc_specialization_trait] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] #[rustc_coinductive] pub trait PointeeSized { // Empty @@ -235,7 +233,7 @@ pub trait PointeeSized { #[unstable(feature = "unsize", issue = "18598")] #[lang = "unsize"] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] pub trait Unsize: PointeeSized { // Empty. } @@ -515,7 +513,7 @@ impl Copy for &T {} #[unstable(feature = "bikeshed_guaranteed_no_drop", issue = "none")] #[lang = "bikeshed_guaranteed_no_drop"] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] #[doc(hidden)] pub trait BikeshedGuaranteedNoDrop {} @@ -886,7 +884,7 @@ impl StructuralPartialEq for PhantomData {} )] #[lang = "discriminant_kind"] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] pub trait DiscriminantKind { /// The type of the discriminant, which must satisfy the trait /// bounds required by `mem::Discriminant`. @@ -1056,7 +1054,7 @@ marker_impls! { #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] pub const trait Destruct: PointeeSized {} /// A marker for tuple types. @@ -1067,7 +1065,7 @@ pub const trait Destruct: PointeeSized {} #[lang = "tuple_trait"] #[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple")] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] pub trait Tuple {} /// A marker for types which can be used as types of `const` generic parameters. @@ -1125,7 +1123,7 @@ marker_impls! { )] #[lang = "fn_ptr_trait"] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] 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 f36cb8cddb837..e26c1b8fa1e19 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -86,7 +86,7 @@ use crate::marker::ConstParamTy_; #[unstable_feature_bound(transmutability)] #[lang = "transmute_trait"] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] #[rustc_coinductive] pub unsafe trait TransmuteFrom where diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index dc3ec3fd19945..83858b519cb95 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -54,7 +54,7 @@ use crate::ptr::NonNull; /// [`to_raw_parts`]: *const::to_raw_parts #[lang = "pointee_trait"] #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] pub trait Pointee: PointeeSized { /// 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 d6f4762d09966..928d16aa43297 100644 --- a/tests/ui/traits/deny-builtin-object-impl.current.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.current.stderr @@ -4,41 +4,67 @@ error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted 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 +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:23:28 + | +LL | impl YesImplNotObject2 for dyn YesImplNotObject2 {} + | ^^^^^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 + | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... + +error[E0038]: the trait `NotImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:37:36 | LL | test_not_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | ^^^^^^^^^^^^^^^^ `NotImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:12:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:11:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility 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` + | ---------------- this trait is not dyn compatible... -error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:40:32 +error[E0038]: the trait `YesImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:40:36 | LL | test_yes_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` + | ^^^^^^^^^^^^^^^^ `YesImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:15:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:14:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility LL | trait YesImplNotObject {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `test_yes_impl_not_object` - --> $DIR/deny-builtin-object-impl.rs:30:32 + | ---------------- this trait is not dyn compatible... + +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:43:37 + | +LL | test_yes_impl_not_object2::(); + | ^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 | -LL | fn test_yes_impl_not_object() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0322. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0038, E0322. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/deny-builtin-object-impl.next.stderr b/tests/ui/traits/deny-builtin-object-impl.next.stderr index d6f4762d09966..928d16aa43297 100644 --- a/tests/ui/traits/deny-builtin-object-impl.next.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.next.stderr @@ -4,41 +4,67 @@ error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted 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 +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:23:28 + | +LL | impl YesImplNotObject2 for dyn YesImplNotObject2 {} + | ^^^^^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 + | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... + +error[E0038]: the trait `NotImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:37:36 | LL | test_not_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | ^^^^^^^^^^^^^^^^ `NotImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:12:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:11:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility 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` + | ---------------- this trait is not dyn compatible... -error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:40:32 +error[E0038]: the trait `YesImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:40:36 | LL | test_yes_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` + | ^^^^^^^^^^^^^^^^ `YesImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:15:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:14:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility LL | trait YesImplNotObject {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `test_yes_impl_not_object` - --> $DIR/deny-builtin-object-impl.rs:30:32 + | ---------------- this trait is not dyn compatible... + +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:43:37 + | +LL | test_yes_impl_not_object2::(); + | ^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 | -LL | fn test_yes_impl_not_object() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0322. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0038, E0322. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/deny-builtin-object-impl.rs b/tests/ui/traits/deny-builtin-object-impl.rs index 9d02ab7bd469e..5924b3fa2857a 100644 --- a/tests/ui/traits/deny-builtin-object-impl.rs +++ b/tests/ui/traits/deny-builtin-object-impl.rs @@ -8,20 +8,20 @@ trait NotImplYesObject {} #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] trait NotImplNotObject {} -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] trait YesImplNotObject {} -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] 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 {} +//~^ ERROR the trait `YesImplNotObject2` is not dyn compatible fn test_not_impl_yes_object() {} @@ -35,10 +35,11 @@ fn main() { test_not_impl_yes_object::(); test_not_impl_not_object::(); - //~^ ERROR the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + //~^ ERROR the trait `NotImplNotObject` is not dyn compatible test_yes_impl_not_object::(); - //~^ ERROR the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + //~^ ERROR the trait `YesImplNotObject` is not dyn compatible test_yes_impl_not_object2::(); + //~^ ERROR the trait `YesImplNotObject2` is not dyn compatible } diff --git a/tests/ui/traits/dyn-metasized.rs b/tests/ui/traits/dyn-metasized.rs new file mode 100644 index 0000000000000..5aeeb93aab65b --- /dev/null +++ b/tests/ui/traits/dyn-metasized.rs @@ -0,0 +1,23 @@ +//@ run-pass +#![feature(sized_hierarchy)] +use std::marker::MetaSized; + +trait Foo: std::fmt::Debug + MetaSized {} + +impl Foo for T {} + +fn unsize_sized(x: Box) -> Box { + x +} + +fn unsize_subtrait(x: Box) -> Box { + x +} + +fn main() { + let _bx = unsize_sized(Box::new(vec![1, 2, 3])); + + let bx: Box = Box::new(vec![1, 2, 3]); + let _ = format!("{bx:?}"); + let _bx = unsize_subtrait(bx); +} diff --git a/tests/ui/traits/dyn-pointeesized.rs b/tests/ui/traits/dyn-pointeesized.rs new file mode 100644 index 0000000000000..906f34eab3e12 --- /dev/null +++ b/tests/ui/traits/dyn-pointeesized.rs @@ -0,0 +1,14 @@ +//@ run-pass +#![feature(sized_hierarchy)] +// PointeeSized is effectively removed before reaching the trait solver. +use std::marker::PointeeSized; + +fn main() { + let dyn_ref: &(dyn PointeeSized + Send) = &42; + let dyn_ref: &dyn Send = dyn_ref; + let _dyn_ref: &(dyn PointeeSized + Send) = dyn_ref; + assert_eq!( + std::any::TypeId::of::(), + std::any::TypeId::of::(), + ); +} diff --git a/tests/ui/traits/dyn-sized.rs b/tests/ui/traits/dyn-sized.rs new file mode 100644 index 0000000000000..366f330154c6b --- /dev/null +++ b/tests/ui/traits/dyn-sized.rs @@ -0,0 +1,26 @@ +trait Foo: std::fmt::Debug + Sized {} + +impl Foo for T {} + +fn unsize_sized(x: Box) -> Box { + //~^ ERROR the trait `Sized` is not dyn compatible + x +} + +fn unsize_subtrait(x: Box) -> Box { + //~^ ERROR the trait `Foo` is not dyn compatible + //~| ERROR the trait `Sized` is not dyn compatible + x +} + +fn main() { + let _bx = unsize_sized(Box::new(vec![1, 2, 3])); + //~^ ERROR the trait `Sized` is not dyn compatible + + let bx: Box = Box::new(vec![1, 2, 3]); + //~^ ERROR the trait `Foo` is not dyn compatible + let _ = format!("{bx:?}"); + let _bx = unsize_subtrait(bx); + //~^ ERROR the trait `Foo` is not dyn compatible + //~| ERROR the trait `Sized` is not dyn compatible +} diff --git a/tests/ui/traits/dyn-sized.stderr b/tests/ui/traits/dyn-sized.stderr new file mode 100644 index 0000000000000..96cc306b7feec --- /dev/null +++ b/tests/ui/traits/dyn-sized.stderr @@ -0,0 +1,88 @@ +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/dyn-sized.rs:5:47 + | +LL | fn unsize_sized(x: Box) -> Box { + | ^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/dyn-sized.rs:10:27 + | +LL | fn unsize_subtrait(x: Box) -> Box { + | ^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-sized.rs:1:30 + | +LL | trait Foo: std::fmt::Debug + Sized {} + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/dyn-sized.rs:10:44 + | +LL | fn unsize_subtrait(x: Box) -> Box { + | ^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/dyn-sized.rs:17:15 + | +LL | let _bx = unsize_sized(Box::new(vec![1, 2, 3])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/dyn-sized.rs:20:21 + | +LL | let bx: Box = Box::new(vec![1, 2, 3]); + | ^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-sized.rs:1:30 + | +LL | trait Foo: std::fmt::Debug + Sized {} + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/dyn-sized.rs:23:31 + | +LL | let _bx = unsize_subtrait(bx); + | ^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-sized.rs:1:30 + | +LL | trait Foo: std::fmt::Debug + Sized {} + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/dyn-sized.rs:23:15 + | +LL | let _bx = unsize_subtrait(bx); + | ^^^^^^^^^^^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.rs b/tests/ui/traits/ice-with-dyn-pointee-errors.rs index 46cef2c8bc094..bb89f103e3f95 100644 --- a/tests/ui/traits/ice-with-dyn-pointee-errors.rs +++ b/tests/ui/traits/ice-with-dyn-pointee-errors.rs @@ -6,10 +6,12 @@ use core::ptr::Pointee; fn unknown_sized_object_ptr_in(_: &(impl Pointee + ?Sized)) {} fn raw_pointer_in(x: &dyn Pointee) { + //~^ ERROR the trait `Pointee` is not dyn compatible unknown_sized_object_ptr_in(x) - //~^ ERROR type mismatch resolving ` as Pointee>::Metadata == ()` + //~^ ERROR the trait `Pointee` is not dyn compatible } fn main() { raw_pointer_in(&42) + //~^ ERROR the trait `Pointee` is not dyn compatible } diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr index 5299236026d7e..9ff0445cda09b 100644 --- a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr +++ b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr @@ -1,19 +1,39 @@ -error[E0271]: type mismatch resolving ` as Pointee>::Metadata == ()` - --> $DIR/ice-with-dyn-pointee-errors.rs:9:33 +error[E0038]: the trait `Pointee` is not dyn compatible + --> $DIR/ice-with-dyn-pointee-errors.rs:8:23 + | +LL | fn raw_pointer_in(x: &dyn Pointee) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `Pointee` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + | + = note: the trait is not dyn compatible because it opted out of dyn-compatibility + +error[E0038]: the trait `Pointee` is not dyn compatible + --> $DIR/ice-with-dyn-pointee-errors.rs:10:5 | LL | unknown_sized_object_ptr_in(x) - | --------------------------- ^ expected `()`, found `DynMetadata>` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Pointee` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + | + = note: the trait is not dyn compatible because it opted out of dyn-compatibility + +error[E0038]: the trait `Pointee` is not dyn compatible + --> $DIR/ice-with-dyn-pointee-errors.rs:15:20 + | +LL | raw_pointer_in(&42) + | ^^^ `Pointee` is not dyn compatible | - = note: expected unit type `()` - found struct `DynMetadata>` -note: required by a bound in `unknown_sized_object_ptr_in` - --> $DIR/ice-with-dyn-pointee-errors.rs:6:50 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL | -LL | fn unknown_sized_object_ptr_in(_: &(impl Pointee + ?Sized)) {} - | ^^^^^^^^^^^^^ required by this bound in `unknown_sized_object_ptr_in` + = note: the trait is not dyn compatible because it opted out of dyn-compatibility -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/ice-with-dyn-pointee.rs b/tests/ui/traits/ice-with-dyn-pointee.rs deleted file mode 100644 index 45361cc44600d..0000000000000 --- a/tests/ui/traits/ice-with-dyn-pointee.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![feature(ptr_metadata)] -// Address issue #112737 -- ICE with dyn Pointee -extern crate core; -use core::ptr::Pointee; - -fn raw_pointer_in(_: &dyn Pointee) {} - -fn main() { - raw_pointer_in(&42) -} diff --git a/tests/ui/unsized/issue-71659.current.stderr b/tests/ui/unsized/issue-71659.current.stderr index f7de668ba3a56..22e43e07dbda5 100644 --- a/tests/ui/unsized/issue-71659.current.stderr +++ b/tests/ui/unsized/issue-71659.current.stderr @@ -1,18 +1,22 @@ -error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied - --> $DIR/issue-71659.rs:34:15 +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/issue-71659.rs:33:17 | -LL | let x = x.cast::<[i32]>(); - | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` +LL | let x: &dyn Foo = &[]; + | ^^^ `Foo` is not dyn compatible | -note: required by a bound in `Cast::cast` - --> $DIR/issue-71659.rs:23:15 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/marker.rs:LL:COL | -LL | fn cast(&self) -> &T - | ---- required by a bound in this associated function -LL | where -LL | Self: CastTo, - | ^^^^^^^^^ required by this bound in `Cast::cast` + = note: ...because it opted out of dyn-compatibility + | + ::: $DIR/issue-71659.rs:29:11 + | +LL | pub trait Foo: CastTo<[i32]> {} + | --- this trait is not dyn compatible... + = help: only type `[i32; 0]` implements `Foo` within this crate; consider using it directly instead. + = note: `Foo` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/unsized/issue-71659.next.stderr b/tests/ui/unsized/issue-71659.next.stderr index f7de668ba3a56..22e43e07dbda5 100644 --- a/tests/ui/unsized/issue-71659.next.stderr +++ b/tests/ui/unsized/issue-71659.next.stderr @@ -1,18 +1,22 @@ -error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied - --> $DIR/issue-71659.rs:34:15 +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/issue-71659.rs:33:17 | -LL | let x = x.cast::<[i32]>(); - | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` +LL | let x: &dyn Foo = &[]; + | ^^^ `Foo` is not dyn compatible | -note: required by a bound in `Cast::cast` - --> $DIR/issue-71659.rs:23:15 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/marker.rs:LL:COL | -LL | fn cast(&self) -> &T - | ---- required by a bound in this associated function -LL | where -LL | Self: CastTo, - | ^^^^^^^^^ required by this bound in `Cast::cast` + = note: ...because it opted out of dyn-compatibility + | + ::: $DIR/issue-71659.rs:29:11 + | +LL | pub trait Foo: CastTo<[i32]> {} + | --- this trait is not dyn compatible... + = help: only type `[i32; 0]` implements `Foo` within this crate; consider using it directly instead. + = note: `Foo` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/unsized/issue-71659.rs b/tests/ui/unsized/issue-71659.rs index c463ed125bb6a..9e1387fa84434 100644 --- a/tests/ui/unsized/issue-71659.rs +++ b/tests/ui/unsized/issue-71659.rs @@ -31,6 +31,6 @@ impl Foo for [i32; 0] {} fn main() { let x: &dyn Foo = &[]; + //~^ ERROR: the trait `Foo` is not dyn compatible let x = x.cast::<[i32]>(); - //~^ ERROR: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied }