Replace #[rustc_do_not_implement_via_object] with #[rustc_dyn_incompatible_trait], which makes the marked trait dyn-incompatible.
Removes the attribute from `MetaSized` and `PointeeSized`, with a special case in the trait solvers for `MetaSized`. `dyn MetaSized` is a perfectly cromulent type, and seems to only have had #[rustc_do_not_implement_via_object] so the builtin object candidate does not overlap with the builtin MetaSized impl that all `dyn` types get. Resolves this with a special case by checking `is_sizedness_trait` where the trait solvers previously checked `implement_via_object`. `dyn PointeeSized` alone is rejected for other reasons (since `dyn PointeeSized` is considered to have no principal trait because `PointeeSized` is removed at an earlier stage of the compiler), but `(dyn PointeeSized + Send)` is valid and equivalent to `dyn Send`. Add suggestions from code review Update compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs and tests Co-authored-by: lcnr <rust@lcnr.de>
This commit is contained in:
parent
5c49c4f7c8
commit
c3205f98dd
35 changed files with 387 additions and 154 deletions
|
|
@ -94,12 +94,12 @@ impl<S: Stage> NoArgsAttributeParser<S> for DenyExplicitImplParser {
|
|||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl;
|
||||
}
|
||||
|
||||
pub(crate) struct DoNotImplementViaObjectParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for DoNotImplementViaObjectParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object];
|
||||
pub(crate) struct DynIncompatibleTraitParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for DynIncompatibleTraitParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = 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
|
||||
|
|
|
|||
|
|
@ -88,8 +88,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;
|
||||
|
|
@ -254,7 +254,7 @@ attribute_parsers!(
|
|||
Single<WithoutArgs<ConstStabilityIndirectParser>>,
|
||||
Single<WithoutArgs<CoroutineParser>>,
|
||||
Single<WithoutArgs<DenyExplicitImplParser>>,
|
||||
Single<WithoutArgs<DoNotImplementViaObjectParser>>,
|
||||
Single<WithoutArgs<DynIncompatibleTraitParser>>,
|
||||
Single<WithoutArgs<EiiForeignItemParser>>,
|
||||
Single<WithoutArgs<ExportStableParser>>,
|
||||
Single<WithoutArgs<FfiConstParser>>,
|
||||
|
|
|
|||
|
|
@ -1315,13 +1315,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),
|
||||
|
|
|
|||
|
|
@ -728,9 +728,6 @@ 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 `#[diagnostic::do_not_recommend]`.
|
||||
DoNotRecommend { attr_span: Span },
|
||||
|
||||
|
|
@ -746,6 +743,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[rustc_dummy]`.
|
||||
Dummy,
|
||||
|
||||
/// Represents `#[rustc_dyn_incompatible_trait]`.
|
||||
DynIncompatibleTrait(Span),
|
||||
|
||||
/// Implementation detail of `#[eii]`
|
||||
EiiDeclaration(EiiDecl),
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ impl AttributeKind {
|
|||
DebuggerVisualizer(..) => No,
|
||||
DenyExplicitImpl(..) => No,
|
||||
Deprecation { .. } => Yes,
|
||||
DoNotImplementViaObject(..) => No,
|
||||
DoNotRecommend { .. } => Yes,
|
||||
Doc(_) => Yes,
|
||||
DocComment { .. } => Yes,
|
||||
Dummy => No,
|
||||
DynIncompatibleTrait(..) => No,
|
||||
EiiDeclaration(_) => Yes,
|
||||
EiiForeignItem => No,
|
||||
EiiImpls(..) => No,
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -924,7 +924,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(),
|
||||
|
|
@ -939,7 +940,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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -764,6 +764,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<Self>`).
|
||||
SupertraitSelf(SmallVec<[Span; 1]>),
|
||||
|
|
@ -788,6 +791,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()
|
||||
|
|
@ -861,6 +867,7 @@ impl DynCompatibilityViolation {
|
|||
pub fn solution(&self) -> DynCompatibilityViolationSolution {
|
||||
match self {
|
||||
DynCompatibilityViolation::SizedSelf(_)
|
||||
| DynCompatibilityViolation::ExplicitlyDynIncompatible(_)
|
||||
| DynCompatibilityViolation::SupertraitSelf(_)
|
||||
| DynCompatibilityViolation::SupertraitNonLifetimeBinder(..)
|
||||
| DynCompatibilityViolation::SupertraitConst(_) => {
|
||||
|
|
@ -894,6 +901,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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::{self as hir, find_attr};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable};
|
||||
use rustc_span::Span;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::query::LocalCrate;
|
||||
|
|
@ -69,10 +70,9 @@ pub struct TraitDef {
|
|||
/// must be implemented.
|
||||
pub must_implement_one_of: Option<Box<[Ident]>>,
|
||||
|
||||
/// 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<Span>,
|
||||
|
||||
/// Whether a trait is fully built-in, and any implementation is disallowed.
|
||||
/// This only applies to built-in traits, and is marked via
|
||||
|
|
|
|||
|
|
@ -792,7 +792,9 @@ where
|
|||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let cx = self.cx();
|
||||
if !cx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(cx)) {
|
||||
if cx.is_sizedness_trait(goal.predicate.trait_def_id(cx)) {
|
||||
// `dyn MetaSized` is valid, but should get its `MetaSized` impl from
|
||||
// being `dyn` (SizedCandidate), not from the object candidate.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| AttributeKind::SkipDuringMethodDispatch { .. }
|
||||
| AttributeKind::Coinductive(..)
|
||||
| AttributeKind::DenyExplicitImpl(..)
|
||||
| AttributeKind::DoNotImplementViaObject(..)
|
||||
| AttributeKind::DynIncompatibleTrait(..)
|
||||
| AttributeKind::SpecializationTrait(..)
|
||||
| AttributeKind::UnsafeSpecializationMarker(..)
|
||||
| AttributeKind::ParenSugar(..)
|
||||
|
|
|
|||
|
|
@ -1395,7 +1395,7 @@ pub struct TraitDecl {
|
|||
pub skip_boxed_slice_during_method_dispatch: bool,
|
||||
pub specialization_kind: TraitSpecializationKind,
|
||||
pub must_implement_one_of: Option<Vec<Ident>>,
|
||||
pub implement_via_object: bool,
|
||||
pub force_dyn_incompatible: Option<Span>,
|
||||
pub deny_explicit_impl: bool,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -597,7 +597,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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1950,7 +1950,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,
|
||||
|
|
@ -1959,6 +1958,7 @@ symbols! {
|
|||
rustc_dump_predicates,
|
||||
rustc_dump_user_args,
|
||||
rustc_dump_vtable,
|
||||
rustc_dyn_incompatible_trait,
|
||||
rustc_effective_visibility,
|
||||
rustc_eii_foreign_item,
|
||||
rustc_evaluate_where_clauses,
|
||||
|
|
|
|||
|
|
@ -93,7 +93,10 @@ fn dyn_compatibility_violations_for_trait(
|
|||
// 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));
|
||||
} else if let Some(span) = tcx.trait_def(trait_def_id).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));
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -904,7 +904,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
"assemble_candidates_from_object_ty",
|
||||
);
|
||||
|
||||
if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object {
|
||||
if self.tcx().is_sizedness_trait(obligation.predicate.def_id()) {
|
||||
// `dyn MetaSized` is valid, but should get its `MetaSized` impl from
|
||||
// being `dyn` (SizedCandidate), not from the object candidate.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -378,8 +378,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ unsafe impl<T: Sync + PointeeSized> 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.
|
||||
|
|
@ -172,7 +172,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]
|
||||
|
|
@ -190,7 +189,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
|
||||
|
|
@ -236,7 +234,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<T: PointeeSized>: PointeeSized {
|
||||
// Empty.
|
||||
}
|
||||
|
|
@ -509,7 +507,7 @@ impl<T: PointeeSized> 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 {}
|
||||
|
||||
|
|
@ -884,7 +882,7 @@ impl<T: PointeeSized> StructuralPartialEq for PhantomData<T> {}
|
|||
)]
|
||||
#[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`.
|
||||
|
|
@ -1054,7 +1052,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.
|
||||
|
|
@ -1065,7 +1063,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.
|
||||
|
|
@ -1123,7 +1121,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"]
|
||||
|
|
|
|||
|
|
@ -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<Src, const ASSUME: Assume = { Assume::NOTHING }>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -55,7 +55,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"]
|
||||
|
|
|
|||
25
tests/ui/dyn-compatibility/metasized.rs
Normal file
25
tests/ui/dyn-compatibility/metasized.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//@ run-pass
|
||||
//! This test and `sized-*.rs` and `pointeesized.rs` test that dyn-compatibility correctly
|
||||
//! handles sizedness traits, which are special in several parts of the compiler.
|
||||
#![feature(sized_hierarchy)]
|
||||
use std::marker::MetaSized;
|
||||
|
||||
trait Foo: std::fmt::Debug + MetaSized {}
|
||||
|
||||
impl<T: std::fmt::Debug + MetaSized> Foo for T {}
|
||||
|
||||
fn unsize_sized<T: 'static>(x: Box<T>) -> Box<dyn MetaSized> {
|
||||
x
|
||||
}
|
||||
|
||||
fn unsize_subtrait(x: Box<dyn Foo>) -> Box<dyn MetaSized> {
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _bx = unsize_sized(Box::new(vec![1, 2, 3]));
|
||||
|
||||
let bx: Box<dyn Foo> = Box::new(vec![1, 2, 3]);
|
||||
let _ = format!("{bx:?}");
|
||||
let _bx = unsize_subtrait(bx);
|
||||
}
|
||||
17
tests/ui/dyn-compatibility/pointeesized.rs
Normal file
17
tests/ui/dyn-compatibility/pointeesized.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//@ run-pass
|
||||
//! This test and `sized-*.rs` and `metasized.rs` test that dyn-compatibility correctly
|
||||
//! handles sizedness traits, which are special in several parts of the compiler.
|
||||
#![feature(sized_hierarchy)]
|
||||
// PointeeSized is effectively removed before reaching the trait solver,
|
||||
// so it's as though it wasn't even mentioned in the trait list.
|
||||
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::<dyn Send>(),
|
||||
std::any::TypeId::of::<dyn PointeeSized + Send>(),
|
||||
);
|
||||
}
|
||||
29
tests/ui/dyn-compatibility/sized-3.rs
Normal file
29
tests/ui/dyn-compatibility/sized-3.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! This test and `metasized.rs` and `pointeesized.rs` test that dyn-compatibility correctly
|
||||
//! handles the different sizedness traits, which are special in several parts of the compiler.
|
||||
|
||||
trait Foo: std::fmt::Debug + Sized {}
|
||||
|
||||
impl<T: std::fmt::Debug + Sized> Foo for T {}
|
||||
|
||||
fn unsize_sized<T: 'static>(x: Box<T>) -> Box<dyn Sized> {
|
||||
//~^ ERROR the trait `Sized` is not dyn compatible
|
||||
x
|
||||
}
|
||||
|
||||
fn unsize_subtrait(x: Box<dyn Foo>) -> Box<dyn Sized> {
|
||||
//~^ 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<dyn Foo> = 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
|
||||
}
|
||||
88
tests/ui/dyn-compatibility/sized-3.stderr
Normal file
88
tests/ui/dyn-compatibility/sized-3.stderr
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
error[E0038]: the trait `Sized` is not dyn compatible
|
||||
--> $DIR/sized-3.rs:8:47
|
||||
|
|
||||
LL | fn unsize_sized<T: 'static>(x: Box<T>) -> Box<dyn Sized> {
|
||||
| ^^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
|
||||
error[E0038]: the trait `Foo` is not dyn compatible
|
||||
--> $DIR/sized-3.rs:13:27
|
||||
|
|
||||
LL | fn unsize_subtrait(x: Box<dyn Foo>) -> Box<dyn Sized> {
|
||||
| ^^^^^^^ `Foo` is not dyn compatible
|
||||
|
|
||||
note: for a trait to be dyn compatible it needs to allow building a vtable
|
||||
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $DIR/sized-3.rs:4: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/sized-3.rs:13:44
|
||||
|
|
||||
LL | fn unsize_subtrait(x: Box<dyn Foo>) -> Box<dyn Sized> {
|
||||
| ^^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
|
||||
error[E0038]: the trait `Sized` is not dyn compatible
|
||||
--> $DIR/sized-3.rs:20: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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
|
||||
error[E0038]: the trait `Foo` is not dyn compatible
|
||||
--> $DIR/sized-3.rs:23:21
|
||||
|
|
||||
LL | let bx: Box<dyn Foo> = 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $DIR/sized-3.rs:4: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/sized-3.rs:26: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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $DIR/sized-3.rs:4: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/sized-3.rs:26: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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
||||
|
|
@ -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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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::<dyn NotImplNotObject>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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<T: NotImplNotObject + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^ 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::<dyn YesImplNotObject>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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 | fn test_yes_impl_not_object<T: YesImplNotObject + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object`
|
||||
LL | test_yes_impl_not_object2::<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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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: 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`.
|
||||
|
|
|
|||
|
|
@ -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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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::<dyn NotImplNotObject>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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<T: NotImplNotObject + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^ 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::<dyn YesImplNotObject>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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 | fn test_yes_impl_not_object<T: YesImplNotObject + ?Sized>() {}
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object`
|
||||
LL | test_yes_impl_not_object2::<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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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: 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`.
|
||||
|
|
|
|||
|
|
@ -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<T: NotImplYesObject + ?Sized>() {}
|
||||
|
||||
|
|
@ -35,10 +35,11 @@ fn main() {
|
|||
test_not_impl_yes_object::<dyn NotImplYesObject>();
|
||||
|
||||
test_not_impl_not_object::<dyn NotImplNotObject>();
|
||||
//~^ ERROR the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied
|
||||
//~^ ERROR the trait `NotImplNotObject` is not dyn compatible
|
||||
|
||||
test_yes_impl_not_object::<dyn YesImplNotObject>();
|
||||
//~^ ERROR the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied
|
||||
//~^ ERROR the trait `YesImplNotObject` is not dyn compatible
|
||||
|
||||
test_yes_impl_not_object2::<dyn YesImplNotObject2>();
|
||||
//~^ ERROR the trait `YesImplNotObject2` is not dyn compatible
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ use core::ptr::Pointee;
|
|||
fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?Sized)) {}
|
||||
|
||||
fn raw_pointer_in(x: &dyn Pointee<Metadata = ()>) {
|
||||
//~^ ERROR the trait `Pointee` is not dyn compatible
|
||||
unknown_sized_object_ptr_in(x)
|
||||
//~^ ERROR type mismatch resolving `<dyn Pointee<Metadata = ()> 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,39 @@
|
|||
error[E0271]: type mismatch resolving `<dyn Pointee<Metadata = ()> 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<Metadata = ()>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `Pointee` is not dyn compatible
|
||||
|
|
||||
note: for a trait to be dyn compatible it needs to allow building a vtable
|
||||
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $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<dyn Pointee<Metadata = ()>>`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Pointee` is not dyn compatible
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found struct `DynMetadata<dyn Pointee<Metadata = ()>>`
|
||||
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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
|
||||
|
|
||||
LL | fn unknown_sized_object_ptr_in(_: &(impl Pointee<Metadata = ()> + ?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[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: for a trait to be dyn compatible it needs to allow building a vtable
|
||||
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
|
||||
|
|
||||
= note: the trait is not dyn compatible because it opted out of dyn-compatibility
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
||||
|
|
|
|||
|
|
@ -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<Metadata = ()>) {}
|
||||
|
||||
fn main() {
|
||||
raw_pointer_in(&42)
|
||||
}
|
||||
|
|
@ -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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
|
||||
LL | fn cast<T: ?Sized>(&self) -> &T
|
||||
| ---- required by a bound in this associated function
|
||||
LL | where
|
||||
LL | Self: CastTo<T>,
|
||||
| ^^^^^^^^^ 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`.
|
||||
|
|
|
|||
|
|
@ -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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
|
||||
LL | fn cast<T: ?Sized>(&self) -> &T
|
||||
| ---- required by a bound in this associated function
|
||||
LL | where
|
||||
LL | Self: CastTo<T>,
|
||||
| ^^^^^^^^^ 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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue