Add support for trait object types in type_info reflection

This commit is contained in:
theiz 2026-01-27 19:49:09 -04:00
parent e96bb7e44f
commit a1893d3187
29 changed files with 399 additions and 42 deletions

View 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(())
}
}

View file

@ -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;

View file

@ -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(..)

View file

@ -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,

View file

@ -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]

View file

@ -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);
}
}

View file

@ -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 {

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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

View file

@ -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();

View file

@ -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>;

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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;

View file

@ -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;
| +++

View file

@ -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

View file

@ -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

View file

@ -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(){}

View file

@ -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

View file

@ -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