Add support for trait object types in type_info reflection
This commit is contained in:
parent
e96bb7e44f
commit
a1893d3187
29 changed files with 399 additions and 42 deletions
178
compiler/rustc_const_eval/src/const_eval/dyn_trait.rs
Normal file
178
compiler/rustc_const_eval/src/const_eval/dyn_trait.rs
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
use rustc_middle::mir::interpret::{CtfeProvenance, InterpResult, Scalar, interp_ok};
|
||||
use rustc_middle::ty::{Region, Ty};
|
||||
use rustc_middle::{span_bug, ty};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::const_eval::CompileTimeMachine;
|
||||
use crate::interpret::{Immediate, InterpCx, MPlaceTy, MemoryKind, Writeable};
|
||||
impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
|
||||
pub(crate) fn write_dyn_trait_type_info(
|
||||
&mut self,
|
||||
dyn_place: impl Writeable<'tcx, CtfeProvenance>,
|
||||
data: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
region: Region<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let tcx = self.tcx.tcx;
|
||||
|
||||
// Find the principal trait ref (for super trait collection), collect auto traits,
|
||||
// and collect all projection predicates (used when computing TypeId for each supertrait).
|
||||
let mut principal: Option<ty::Binder<'tcx, ty::ExistentialTraitRef<'tcx>>> = None;
|
||||
let mut auto_traits_def_ids: Vec<ty::Binder<'tcx, DefId>> = Vec::new();
|
||||
let mut projections: Vec<ty::Binder<'tcx, ty::ExistentialProjection<'tcx>>> = Vec::new();
|
||||
|
||||
for b in data.iter() {
|
||||
match b.skip_binder() {
|
||||
ty::ExistentialPredicate::Trait(tr) => principal = Some(b.rebind(tr)),
|
||||
ty::ExistentialPredicate::AutoTrait(did) => auto_traits_def_ids.push(b.rebind(did)),
|
||||
ty::ExistentialPredicate::Projection(p) => projections.push(b.rebind(p)),
|
||||
}
|
||||
}
|
||||
|
||||
// This is to make principal dyn type include Trait and projection predicates, excluding auto traits.
|
||||
let principal_ty: Option<Ty<'tcx>> = principal.map(|_tr| {
|
||||
let preds = tcx
|
||||
.mk_poly_existential_predicates_from_iter(data.iter().filter(|b| {
|
||||
!matches!(b.skip_binder(), ty::ExistentialPredicate::AutoTrait(_))
|
||||
}));
|
||||
Ty::new_dynamic(tcx, preds, region)
|
||||
});
|
||||
|
||||
// DynTrait { predicates: &'static [Trait] }
|
||||
for (field_idx, field) in
|
||||
dyn_place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
|
||||
{
|
||||
let field_place = self.project_field(&dyn_place, field_idx)?;
|
||||
match field.name {
|
||||
sym::predicates => {
|
||||
self.write_dyn_trait_predicates_slice(
|
||||
&field_place,
|
||||
principal_ty,
|
||||
&auto_traits_def_ids,
|
||||
region,
|
||||
)?;
|
||||
}
|
||||
other => {
|
||||
span_bug!(self.tcx.def_span(field.did), "unimplemented DynTrait field {other}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interp_ok(())
|
||||
}
|
||||
|
||||
fn mk_dyn_principal_auto_trait_ty(
|
||||
&self,
|
||||
auto_trait_def_id: ty::Binder<'tcx, DefId>,
|
||||
region: Region<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx.tcx;
|
||||
|
||||
// Preserve the binder vars from the original auto-trait predicate.
|
||||
let pred_inner = ty::ExistentialPredicate::AutoTrait(auto_trait_def_id.skip_binder());
|
||||
let pred = ty::Binder::bind_with_vars(pred_inner, auto_trait_def_id.bound_vars());
|
||||
|
||||
let preds = tcx.mk_poly_existential_predicates_from_iter([pred].into_iter());
|
||||
Ty::new_dynamic(tcx, preds, region)
|
||||
}
|
||||
|
||||
fn write_dyn_trait_predicates_slice(
|
||||
&mut self,
|
||||
slice_place: &impl Writeable<'tcx, CtfeProvenance>,
|
||||
principal_ty: Option<Ty<'tcx>>,
|
||||
auto_trait_def_ids: &[ty::Binder<'tcx, DefId>],
|
||||
region: Region<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let tcx = self.tcx.tcx;
|
||||
|
||||
// total entries in DynTrait predicates
|
||||
let total_len = principal_ty.map(|_| 1).unwrap_or(0) + auto_trait_def_ids.len();
|
||||
|
||||
// element type = DynTraitPredicate
|
||||
let slice_ty = slice_place.layout().ty.builtin_deref(false).unwrap(); // [DynTraitPredicate]
|
||||
let elem_ty = slice_ty.sequence_element_type(tcx); // DynTraitPredicate
|
||||
|
||||
let arr_layout = self.layout_of(Ty::new_array(tcx, elem_ty, total_len as u64))?;
|
||||
let arr_place = self.allocate(arr_layout, MemoryKind::Stack)?;
|
||||
let mut elems = self.project_array_fields(&arr_place)?;
|
||||
|
||||
// principal entry (if any) - NOT an auto trait
|
||||
if let Some(principal_ty) = principal_ty {
|
||||
let Some((_i, elem_place)) = elems.next(self)? else {
|
||||
span_bug!(self.tcx.span, "DynTrait.predicates length computed wrong (principal)");
|
||||
};
|
||||
self.write_dyn_trait_predicate(elem_place, principal_ty, false)?;
|
||||
}
|
||||
|
||||
// auto trait entries - these ARE auto traits
|
||||
for auto in auto_trait_def_ids {
|
||||
let Some((_i, elem_place)) = elems.next(self)? else {
|
||||
span_bug!(self.tcx.span, "DynTrait.predicates length computed wrong (auto)");
|
||||
};
|
||||
let auto_ty = self.mk_dyn_principal_auto_trait_ty(*auto, region);
|
||||
self.write_dyn_trait_predicate(elem_place, auto_ty, true)?;
|
||||
}
|
||||
|
||||
let arr_place = arr_place.map_provenance(CtfeProvenance::as_immutable);
|
||||
let imm = Immediate::new_slice(arr_place.ptr(), total_len as u64, self);
|
||||
self.write_immediate(imm, slice_place)
|
||||
}
|
||||
|
||||
fn write_dyn_trait_predicate(
|
||||
&mut self,
|
||||
predicate_place: MPlaceTy<'tcx>,
|
||||
trait_ty: Ty<'tcx>,
|
||||
is_auto: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
// DynTraitPredicate { trait_ty: Trait }
|
||||
for (field_idx, field) in predicate_place
|
||||
.layout
|
||||
.ty
|
||||
.ty_adt_def()
|
||||
.unwrap()
|
||||
.non_enum_variant()
|
||||
.fields
|
||||
.iter_enumerated()
|
||||
{
|
||||
let field_place = self.project_field(&predicate_place, field_idx)?;
|
||||
match field.name {
|
||||
sym::trait_ty => {
|
||||
// Now write the Trait struct
|
||||
self.write_trait(field_place, trait_ty, is_auto)?;
|
||||
}
|
||||
other => {
|
||||
span_bug!(
|
||||
self.tcx.def_span(field.did),
|
||||
"unimplemented DynTraitPredicate field {other}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
interp_ok(())
|
||||
}
|
||||
fn write_trait(
|
||||
&mut self,
|
||||
trait_place: MPlaceTy<'tcx>,
|
||||
trait_ty: Ty<'tcx>,
|
||||
is_auto: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
// Trait { ty: TypeId, is_auto: bool }
|
||||
for (field_idx, field) in
|
||||
trait_place.layout.ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
|
||||
{
|
||||
let field_place = self.project_field(&trait_place, field_idx)?;
|
||||
match field.name {
|
||||
sym::ty => {
|
||||
self.write_type_id(trait_ty, &field_place)?;
|
||||
}
|
||||
sym::is_auto => {
|
||||
self.write_scalar(Scalar::from_bool(is_auto), &field_place)?;
|
||||
}
|
||||
other => {
|
||||
span_bug!(self.tcx.def_span(field.did), "unimplemented Trait field {other}")
|
||||
}
|
||||
}
|
||||
}
|
||||
interp_ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ use tracing::instrument;
|
|||
use crate::interpret::InterpCx;
|
||||
|
||||
mod dummy_machine;
|
||||
mod dyn_trait;
|
||||
mod error;
|
||||
mod eval_queries;
|
||||
mod fn_queries;
|
||||
|
|
|
|||
|
|
@ -129,13 +129,18 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
|
|||
|
||||
variant
|
||||
}
|
||||
ty::Dynamic(predicates, region) => {
|
||||
let (variant, variant_place) = downcast(sym::DynTrait)?;
|
||||
let dyn_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
|
||||
self.write_dyn_trait_type_info(dyn_place, *predicates, *region)?;
|
||||
variant
|
||||
}
|
||||
ty::Adt(_, _)
|
||||
| ty::Foreign(_)
|
||||
| ty::Pat(_, _)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::UnsafeBinder(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ symbols! {
|
|||
AtomicU64,
|
||||
AtomicU128,
|
||||
AtomicUsize,
|
||||
AutoTrait,
|
||||
BTreeEntry,
|
||||
BTreeMap,
|
||||
BTreeSet,
|
||||
|
|
@ -231,6 +232,7 @@ symbols! {
|
|||
Display,
|
||||
DoubleEndedIterator,
|
||||
Duration,
|
||||
DynTrait,
|
||||
Encodable,
|
||||
Encoder,
|
||||
Enumerate,
|
||||
|
|
@ -1297,6 +1299,7 @@ symbols! {
|
|||
io_stdout,
|
||||
irrefutable_let_patterns,
|
||||
is,
|
||||
is_auto,
|
||||
is_val_statically_known,
|
||||
isa_attribute,
|
||||
isize,
|
||||
|
|
@ -1750,6 +1753,7 @@ symbols! {
|
|||
precise_capturing_in_traits,
|
||||
precise_pointer_size_matching,
|
||||
precision,
|
||||
predicates,
|
||||
pref_align_of,
|
||||
prefetch_read_data,
|
||||
prefetch_read_instruction,
|
||||
|
|
@ -2297,6 +2301,7 @@ symbols! {
|
|||
trace_macros,
|
||||
track_caller,
|
||||
trait_alias,
|
||||
trait_ty,
|
||||
trait_upcasting,
|
||||
transmute,
|
||||
transmute_generic_consts,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ pub enum TypeKind {
|
|||
Array(Array),
|
||||
/// Slices.
|
||||
Slice(Slice),
|
||||
/// Dynamic Traits.
|
||||
DynTrait(DynTrait),
|
||||
/// Primitive boolean type.
|
||||
Bool(Bool),
|
||||
/// Primitive character type.
|
||||
|
|
@ -105,6 +107,36 @@ pub struct Slice {
|
|||
pub element_ty: TypeId,
|
||||
}
|
||||
|
||||
/// Compile-time type information about dynamic traits.
|
||||
/// FIXME(#146922): Add super traits and generics
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
#[unstable(feature = "type_info", issue = "146922")]
|
||||
pub struct DynTrait {
|
||||
/// The predicates of a dynamic trait.
|
||||
pub predicates: &'static [DynTraitPredicate],
|
||||
}
|
||||
|
||||
/// Compile-time type information about a dynamic trait predicate.
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
#[unstable(feature = "type_info", issue = "146922")]
|
||||
pub struct DynTraitPredicate {
|
||||
/// The type of the trait as a dynamic trait type.
|
||||
pub trait_ty: Trait,
|
||||
}
|
||||
|
||||
/// Compile-time type information about a trait.
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
#[unstable(feature = "type_info", issue = "146922")]
|
||||
pub struct Trait {
|
||||
/// The TypeId of the trait as a dynamic type
|
||||
pub ty: TypeId,
|
||||
/// Whether the trait is an auto trait
|
||||
pub is_auto: bool,
|
||||
}
|
||||
|
||||
/// Compile-time type information about `bool`.
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
|
|
|
|||
|
|
@ -163,3 +163,132 @@ fn test_pointers() {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dynamic_traits() {
|
||||
use std::collections::HashSet;
|
||||
use std::mem::type_info::DynTraitPredicate;
|
||||
trait A<T> {}
|
||||
|
||||
trait B<const CONST_NUM: i32> {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
trait FooTrait<'a, 'b, const CONST_NUM: i32> {}
|
||||
|
||||
trait ProjectorTrait<'a, 'b> {}
|
||||
|
||||
fn preds_of<T: ?Sized + 'static>() -> &'static [DynTraitPredicate] {
|
||||
match const { Type::of::<T>() }.kind {
|
||||
TypeKind::DynTrait(d) => d.predicates,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pred<'a>(preds: &'a [DynTraitPredicate], want: TypeId) -> &'a DynTraitPredicate {
|
||||
preds
|
||||
.iter()
|
||||
.find(|p| p.trait_ty.ty == want)
|
||||
.unwrap_or_else(|| panic!("missing predicate for {want:?}"))
|
||||
}
|
||||
|
||||
fn assert_typeid_set_eq(actual: &[TypeId], expected: &[TypeId]) {
|
||||
let actual_set: HashSet<TypeId> = actual.iter().copied().collect();
|
||||
let expected_set: HashSet<TypeId> = expected.iter().copied().collect();
|
||||
assert_eq!(actual.len(), actual_set.len(), "duplicates present: {actual:?}");
|
||||
assert_eq!(
|
||||
actual_set, expected_set,
|
||||
"unexpected ids.\nactual: {actual:?}\nexpected: {expected:?}"
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_predicates_exact(preds: &[DynTraitPredicate], expected_pred_ids: &[TypeId]) {
|
||||
let actual_pred_ids: Vec<TypeId> = preds.iter().map(|p| p.trait_ty.ty).collect();
|
||||
assert_typeid_set_eq(&actual_pred_ids, expected_pred_ids);
|
||||
}
|
||||
|
||||
// dyn Send
|
||||
{
|
||||
let preds = preds_of::<dyn Send>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn Send>()]);
|
||||
|
||||
let p = pred(preds, TypeId::of::<dyn Send>());
|
||||
assert!(p.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn A<i32>
|
||||
{
|
||||
let preds = preds_of::<dyn A<i32>>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn A<i32>>()]);
|
||||
|
||||
let p = pred(preds, TypeId::of::<dyn A<i32>>());
|
||||
assert!(!p.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn B<5, Foo = i32>
|
||||
{
|
||||
let preds = preds_of::<dyn B<5, Foo = i32>>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn B<5, Foo = i32>>()]);
|
||||
|
||||
let e = pred(preds, TypeId::of::<dyn B<5, Foo = i32>>());
|
||||
assert!(!e.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn for<'a> FooTrait<'a, 'a, 7>
|
||||
{
|
||||
let preds = preds_of::<dyn for<'a> FooTrait<'a, 'a, 7>>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>()]);
|
||||
|
||||
let foo = pred(preds, TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>());
|
||||
assert!(!foo.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn FooTrait<'static, 'static, 7>
|
||||
{
|
||||
let preds = preds_of::<dyn FooTrait<'static, 'static, 7>>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn FooTrait<'static, 'static, 7>>()]);
|
||||
|
||||
let foo = pred(preds, TypeId::of::<dyn FooTrait<'static, 'static, 7>>());
|
||||
assert!(!foo.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn for<'a, 'b> FooTrait<'a, 'b, 7>
|
||||
{
|
||||
let preds = preds_of::<dyn for<'a, 'b> FooTrait<'a, 'b, 7>>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn for<'a, 'b> FooTrait<'a, 'b, 7>>()]);
|
||||
|
||||
let foo = pred(preds, TypeId::of::<dyn for<'a, 'b> FooTrait<'a, 'b, 7>>());
|
||||
assert!(!foo.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn for<'a, 'b> ProjectorTrait<'a, 'b>
|
||||
{
|
||||
let preds = preds_of::<dyn for<'a, 'b> ProjectorTrait<'a, 'b>>();
|
||||
assert_predicates_exact(preds, &[TypeId::of::<dyn for<'a, 'b> ProjectorTrait<'a, 'b>>()]);
|
||||
|
||||
let proj = pred(preds, TypeId::of::<dyn for<'a, 'b> ProjectorTrait<'a, 'b>>());
|
||||
assert!(!proj.trait_ty.is_auto);
|
||||
}
|
||||
|
||||
// dyn for<'a> FooTrait<'a, 'a, 7> + Send + Sync
|
||||
{
|
||||
let preds = preds_of::<dyn for<'a> FooTrait<'a, 'a, 7> + Send + Sync>();
|
||||
assert_predicates_exact(
|
||||
preds,
|
||||
&[
|
||||
TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>(),
|
||||
TypeId::of::<dyn Send>(),
|
||||
TypeId::of::<dyn Sync>(),
|
||||
],
|
||||
);
|
||||
|
||||
let foo = pred(preds, TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>());
|
||||
assert!(!foo.trait_ty.is_auto);
|
||||
|
||||
let send = pred(preds, TypeId::of::<dyn Send>());
|
||||
assert!(send.trait_ty.is_auto);
|
||||
|
||||
let sync = pred(preds, TypeId::of::<dyn Sync>());
|
||||
assert!(sync.trait_ty.is_auto);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `dep_2_reexport::Type: dependency::Trait` is not satisfied
|
||||
--> replaced
|
||||
|
|
||||
LL | do_something(Type);
|
||||
| ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
|
||||
| ------------ ^^^^ the trait `dependency::Trait` is not implemented for `dep_2_reexport::Type`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
|
@ -17,7 +17,7 @@ LL | pub trait Trait {
|
|||
LL | pub trait Trait {
|
||||
| --------------- this is the found trait
|
||||
= help: you can use `cargo tree` to explore your dependency tree
|
||||
help: the trait `Trait` is implemented for `dependency::Type`
|
||||
help: the trait `dependency::Trait` is implemented for `dependency::Type`
|
||||
--> replaced
|
||||
|
|
||||
LL | impl Trait for Type {
|
||||
|
|
@ -64,11 +64,11 @@ LL | pub trait Trait {
|
|||
| --------------- this is the trait that was imported
|
||||
= help: you can use `cargo tree` to explore your dependency tree
|
||||
|
||||
error[E0277]: the trait bound `OtherType: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `OtherType: dependency::Trait` is not satisfied
|
||||
--> replaced
|
||||
|
|
||||
LL | do_something(OtherType);
|
||||
| ------------ ^^^^^^^^^ the trait `Trait` is not implemented for `OtherType`
|
||||
| ------------ ^^^^^^^^^ the trait `dependency::Trait` is not implemented for `OtherType`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
|
@ -83,7 +83,7 @@ LL | pub trait Trait {
|
|||
LL | pub trait Trait {
|
||||
| --------------- this is the found trait
|
||||
= help: you can use `cargo tree` to explore your dependency tree
|
||||
help: the trait `Trait` is implemented for `dependency::Type`
|
||||
help: the trait `dependency::Trait` is implemented for `dependency::Type`
|
||||
--> replaced
|
||||
|
|
||||
LL | impl Trait for Type {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> remapped/errors/auxiliary/trait-diag.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait-doc.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait-macro.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> remapped/errors/auxiliary/trait-diag.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait-doc.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ help: the trait `std::fmt::Display` is not implemented for `A`
|
|||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
note: required by a bound in `r#trait::Trait`
|
||||
--> $DIR/auxiliary/trait-macro.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Trait: std::fmt::Display {}
|
||||
|
|
|
|||
|
|
@ -115,11 +115,11 @@ fn main() {
|
|||
|
||||
m::m!();
|
||||
|
||||
m::leak_anon1(); //~ ERROR trait `Trait` is private
|
||||
m::leak_anon1(); //~ ERROR trait `m::Trait` is private
|
||||
m::leak_anon2(); //~ ERROR type `Priv` is private
|
||||
m::leak_anon3(); //~ ERROR type `Priv` is private
|
||||
|
||||
m::leak_dyn1(); //~ ERROR trait `Trait` is private
|
||||
m::leak_dyn1(); //~ ERROR trait `m::Trait` is private
|
||||
m::leak_dyn2(); //~ ERROR type `Priv` is private
|
||||
m::leak_dyn3(); //~ ERROR type `Priv` is private
|
||||
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ LL | m::m!();
|
|||
|
|
||||
= note: this error originates in the macro `m::m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: trait `Trait` is private
|
||||
error: trait `m::Trait` is private
|
||||
--> $DIR/private-inferred-type.rs:118:5
|
||||
|
|
||||
LL | m::leak_anon1();
|
||||
|
|
@ -190,7 +190,7 @@ error: type `Priv` is private
|
|||
LL | m::leak_anon3();
|
||||
| ^^^^^^^^^^^^^^^ private type
|
||||
|
||||
error: trait `Trait` is private
|
||||
error: trait `m::Trait` is private
|
||||
--> $DIR/private-inferred-type.rs:122:5
|
||||
|
|
||||
LL | m::leak_dyn1();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ LL | type P<X> = [u8];
|
|||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
note: required by a bound in `Trait::P`
|
||||
note: required by a bound in `main::Trait::P`
|
||||
--> $DIR/suggest-maybe-sized-bound.rs:13:9
|
||||
|
|
||||
LL | type P<X>;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `usize: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `usize: on_structs_and_enums_xc::Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-xc.rs:7:15
|
||||
|
|
||||
LL | fn explode(x: Foo<usize>) {}
|
||||
| ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
|
||||
| ^^^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `usize`
|
||||
|
|
||||
note: required by a bound in `Foo`
|
||||
--> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18
|
||||
|
|
@ -10,11 +10,11 @@ note: required by a bound in `Foo`
|
|||
LL | pub struct Foo<T:Trait> {
|
||||
| ^^^^^ required by this bound in `Foo`
|
||||
|
||||
error[E0277]: the trait bound `f32: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `f32: on_structs_and_enums_xc::Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-xc.rs:10:14
|
||||
|
|
||||
LL | fn kaboom(y: Bar<f32>) {}
|
||||
| ^^^^^^^^ the trait `Trait` is not implemented for `f32`
|
||||
| ^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `f32`
|
||||
|
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `{integer}: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `{integer}: on_structs_and_enums_xc::Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-xc1.rs:9:12
|
||||
|
|
||||
LL | x: 3
|
||||
| ^ the trait `Trait` is not implemented for `{integer}`
|
||||
| ^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `{integer}`
|
||||
|
|
||||
note: required by a bound in `Foo`
|
||||
--> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18
|
||||
|
|
@ -10,11 +10,11 @@ note: required by a bound in `Foo`
|
|||
LL | pub struct Foo<T:Trait> {
|
||||
| ^^^^^ required by this bound in `Foo`
|
||||
|
||||
error[E0277]: the trait bound `f64: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `f64: on_structs_and_enums_xc::Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-xc1.rs:12:14
|
||||
|
|
||||
LL | let bar: Bar<f64> = return;
|
||||
| ^^^^^^^^ the trait `Trait` is not implemented for `f64`
|
||||
| ^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `f64`
|
||||
|
|
||||
note: required by a bound in `Bar`
|
||||
--> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Issue #148892.
|
||||
//@ aux-crate:crate1=crate1.rs
|
||||
|
||||
struct MyStruct; //~ HELP the trait `Trait` is not implemented for `MyStruct`
|
||||
struct MyStruct; //~ HELP the trait `crate1::Trait` is not implemented for `MyStruct`
|
||||
|
||||
fn main() {
|
||||
crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: Trait` is not satisfied
|
||||
crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: crate1::Trait` is not satisfied
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the trait bound `MyStruct: Trait` is not satisfied
|
||||
error[E0277]: the trait bound `MyStruct: crate1::Trait` is not satisfied
|
||||
--> $DIR/wrong-multiple-different-versions-of-a-crate.rs:11:17
|
||||
|
|
||||
LL | crate1::foo(MyStruct);
|
||||
|
|
@ -6,7 +6,7 @@ LL | crate1::foo(MyStruct);
|
|||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
help: the trait `Trait` is not implemented for `MyStruct`
|
||||
help: the trait `crate1::Trait` is not implemented for `MyStruct`
|
||||
--> $DIR/wrong-multiple-different-versions-of-a-crate.rs:8:1
|
||||
|
|
||||
LL | struct MyStruct;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ error[E0432]: unresolved import `Trait`
|
|||
LL | use Trait;
|
||||
| ^^^^^ no `Trait` in the root
|
||||
|
|
||||
help: consider importing this trait instead
|
||||
help: consider importing one of these items instead
|
||||
|
|
||||
LL | use std::mem::type_info::Trait;
|
||||
| +++++++++++++++++++++
|
||||
LL | use a::Trait;
|
||||
| +++
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy`
|
||||
error[E0119]: conflicting implementations of trait `aux::Trait` for type `LocalTy`
|
||||
--> $DIR/unstable_impl_coherence.rs:14:1
|
||||
|
|
||||
LL | impl aux::Trait for LocalTy {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: conflicting implementation in crate `unstable_impl_coherence_aux`:
|
||||
- impl<T> Trait for T
|
||||
- impl<T> aux::Trait for T
|
||||
where feature(foo) is enabled;
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy`
|
||||
error[E0119]: conflicting implementations of trait `aux::Trait` for type `LocalTy`
|
||||
--> $DIR/unstable_impl_coherence.rs:14:1
|
||||
|
|
||||
LL | impl aux::Trait for LocalTy {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: conflicting implementation in crate `unstable_impl_coherence_aux`:
|
||||
- impl<T> Trait for T
|
||||
- impl<T> aux::Trait for T
|
||||
where feature(foo) is enabled;
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ use aux::Trait;
|
|||
struct LocalTy;
|
||||
|
||||
impl aux::Trait for LocalTy {}
|
||||
//~^ ERROR: conflicting implementations of trait `Trait` for type `LocalTy`
|
||||
//~^ ERROR: conflicting implementations of trait `aux::Trait` for type `LocalTy`
|
||||
|
||||
fn main(){}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ error[E0283]: type annotations needed
|
|||
LL | vec![].foo();
|
||||
| ^^^ cannot infer type for struct `Vec<_>`
|
||||
|
|
||||
= note: multiple `impl`s satisfying `Vec<_>: Trait` found in the `unstable_impl_method_selection_aux` crate:
|
||||
- impl Trait for Vec<u32>;
|
||||
- impl Trait for Vec<u64>
|
||||
= note: multiple `impl`s satisfying `Vec<_>: aux::Trait` found in the `unstable_impl_method_selection_aux` crate:
|
||||
- impl aux::Trait for Vec<u32>;
|
||||
- impl aux::Trait for Vec<u64>
|
||||
where feature(bar) is enabled;
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ error[E0574]: expected struct, variant or union type, found trait `Trait`
|
|||
|
|
||||
LL | Trait { x: 42 } => ()
|
||||
| ^^^^^ not a struct, variant or union type
|
||||
|
|
||||
help: consider importing this struct instead
|
||||
|
|
||||
LL + use std::mem::type_info::Trait;
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue