Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
277 changes: 247 additions & 30 deletions compiler/rustc_const_eval/src/const_eval/type_info.rs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ symbols! {
CoercePointeeValidated,
CoerceUnsized,
Command,
Const,
ConstParamTy,
ConstParamTy_,
Context,
Expand Down Expand Up @@ -290,6 +291,7 @@ symbols! {
IteratorMap,
Layout,
Left,
Lifetime,
LinkedList,
LintDiagnostic,
LintPass,
Expand Down Expand Up @@ -369,6 +371,7 @@ symbols! {
Stdin,
Str,
String,
Struct,
StructuralPartialEq,
SubdiagMessage,
Subdiagnostic,
Expand All @@ -392,6 +395,7 @@ symbols! {
Ty,
TyCtxt,
TyKind,
Type,
Unknown,
Unsize,
UnsizedConstParamTy,
Expand Down Expand Up @@ -1080,6 +1084,7 @@ symbols! {
ffi_returns_twice,
field,
field_init_shorthand,
fields,
file,
file_options,
flags,
Expand Down Expand Up @@ -1168,6 +1173,7 @@ symbols! {
generic_const_parameter_types,
generic_param_attrs,
generic_pattern_types,
generics,
get_context,
global_alloc_ty,
global_allocator,
Expand Down
56 changes: 56 additions & 0 deletions library/core/src/mem/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub enum TypeKind {
Tuple(Tuple),
/// Arrays.
Array(Array),
/// Structs.
Struct(Struct),
/// Primitive boolean type.
Bool(Bool),
/// Primitive character type.
Expand Down Expand Up @@ -75,6 +77,8 @@ pub struct Tuple {
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Field {
/// The name of the field.
pub name: &'static str,
/// The field's type.
pub ty: TypeId,
/// Offset in bytes from the parent type
Expand All @@ -92,6 +96,58 @@ pub struct Array {
pub len: usize,
}

/// Compile-time type information about arrays.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Struct {
/// Instantiated generics of the struct.
pub generics: &'static [Generic],
/// All fields of the struct.
pub fields: &'static [Field],
/// Whether the struct is non-exhaustive.
pub non_exhaustive: bool,
}

/// Compile-time type information about instantiated generics of structs, enum and union variants.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub enum Generic {
/// Lifetimes.
Lifetime(Lifetime),
/// Types.
Type(GenericType),
/// Const parameters.
Const(Const),
}

/// Compile-time type information about generic lifetimes.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Lifetime {
// No additional information to provide for now.
}

/// Compile-time type information about instantiated generic types.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct GenericType {
/// The const's type.
pub ty: TypeId,
}

/// Compile-time type information about generic const parameters.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Const {
/// The const's type.
pub ty: TypeId,
}

/// Compile-time type information about `bool`.
#[derive(Debug)]
#[non_exhaustive]
Expand Down
56 changes: 56 additions & 0 deletions library/coretests/tests/mem/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,62 @@ fn test_tuples() {
}
}

#[test]
fn test_structs() {
use TypeKind::*;

struct TestStruct {
first: u8,
second: u16,
}
#[non_exhaustive]
struct NonExhaustive {
a: u8,
}
struct TupleStruct(u8, u16);
struct Generics<'a, A, B, const C: u64> {
a: A,
b: B,
l: &'a (), // FIXME(type_info): offset of this field is dumped as 0, which may not be correct
}

let Type { kind: Struct(ty), size, .. } = (const { Type::of::<TestStruct>() }) else {
panic!()
};
assert_eq!(size, Some(size_of::<TestStruct>()));
assert!(!ty.non_exhaustive);
assert_eq!(ty.fields.len(), 2);
assert_eq!(ty.fields[0].name, "first");
assert_eq!(ty.fields[1].name, "second");

let Type { kind: Struct(ty), size, .. } = (const { Type::of::<NonExhaustive>() }) else {
panic!()
};
assert_eq!(size, Some(1));
assert!(ty.non_exhaustive);

let Type { kind: Struct(ty), size, .. } = (const { Type::of::<TupleStruct>() }) else {
panic!()
};
assert_eq!(ty.fields.len(), 2);
assert_eq!(ty.fields[0].name, "0");
assert_eq!(ty.fields[1].name, "1");

let Type { kind: Struct(ty), size, .. } =
(const { Type::of::<Generics<'static, i32, u32, 1>>() })
else {
panic!()
};
assert_eq!(ty.fields.len(), 3);
let Generic::Lifetime(_) = ty.generics[0] else { panic!() };
let Generic::Type(GenericType { ty: generic_ty }) = ty.generics[1] else { panic!() };
let TypeKind::Int(generic_ty) = generic_ty.info().kind else { panic!() };
assert_eq!(generic_ty.bits, 32);
let Generic::Type(GenericType { ty: generic_ty }) = ty.generics[2] else { panic!() };
let TypeKind::Int(generic_ty) = generic_ty.info().kind else { panic!() };
assert_eq!(generic_ty.bits, 32);
}

#[test]
fn test_primitives() {
use TypeKind::*;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/generics/wrong-number-of-args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ mod r#trait {
//~| HELP remove

type D = Box<dyn GenericType>;
//~^ ERROR missing generics for trait `GenericType`
//~^ ERROR missing generics for trait `r#trait::GenericType`
//~| HELP add missing

type E = Box<dyn GenericType<String, usize>>;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/generics/wrong-number-of-args.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ note: trait defined here, with 1 lifetime parameter: `'a`
LL | trait GenericLifetime<'a> {
| ^^^^^^^^^^^^^^^ --

error[E0107]: missing generics for trait `GenericType`
error[E0107]: missing generics for trait `r#trait::GenericType`
--> $DIR/wrong-number-of-args.rs:129:22
|
LL | type D = Box<dyn GenericType>;
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/missing-trait-bounds/issue-69725.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0599]: the method `clone` exists for struct `Struct<A>`, but its trait bounds were not satisfied
error[E0599]: the method `clone` exists for struct `issue_69725::Struct<A>`, but its trait bounds were not satisfied
--> $DIR/issue-69725.rs:9:32
|
LL | let _ = Struct::<A>::new().clone();
| ^^^^^ method cannot be called on `Struct<A>` due to unsatisfied trait bounds
| ^^^^^ method cannot be called on `issue_69725::Struct<A>` due to unsatisfied trait bounds
|
::: $DIR/auxiliary/issue-69725.rs:2:1
|
LL | pub struct Struct<A>(A);
| -------------------- doesn't satisfy `Struct<A>: Clone`
| -------------------- doesn't satisfy `issue_69725::Struct<A>: Clone`
|
= note: the following trait bounds were not satisfied:
`A: Clone`
which is required by `Struct<A>: Clone`
which is required by `issue_69725::Struct<A>: Clone`
help: consider restricting the type parameter to satisfy the trait bound
|
LL | fn crash<A>() where A: Clone {
Expand Down
105 changes: 104 additions & 1 deletion tests/ui/reflection/dump.bit32.run.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ Type {
Tuple {
fields: [
Field {
name: "0",
ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
offset: 0,
},
Field {
name: "1",
ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
offset: 1,
},
Field {
name: "2",
ty: TypeId(0x41223169ff28813ba79b7268a2a968d9),
offset: 2,
},
Expand Down Expand Up @@ -143,7 +146,19 @@ Type {
),
}
Type {
kind: Other,
kind: Struct(
Struct {
generics: [],
fields: [
Field {
name: "a",
ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7),
offset: 0,
},
],
non_exhaustive: false,
},
),
size: Some(
4,
),
Expand All @@ -154,6 +169,94 @@ Type {
12,
),
}
Type {
kind: Struct(
Struct {
generics: [],
fields: [
Field {
name: "a",
ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7),
offset: 0,
},
],
non_exhaustive: true,
},
),
size: Some(
4,
),
}
Type {
kind: Struct(
Struct {
generics: [],
fields: [
Field {
name: "0",
ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7),
offset: 8,
},
Field {
name: "1",
ty: TypeId(0x9ed91be891e304132cb86891e578f4a5),
offset: 0,
},
],
non_exhaustive: false,
},
),
size: Some(
12,
),
}
Type {
kind: Struct(
Struct {
generics: [
Lifetime(
Lifetime,
),
Type(
GenericType {
ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013),
},
),
Type(
GenericType {
ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7),
},
),
Const(
Const {
ty: TypeId(0x9ed91be891e304132cb86891e578f4a5),
},
),
],
fields: [
Field {
name: "a",
ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013),
offset: 4,
},
Field {
name: "b",
ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7),
offset: 8,
},
Field {
name: "l",
ty: TypeId(0x5d686ae9be5f6232dca1f88c0b941fd9),
offset: 0,
},
],
non_exhaustive: false,
},
),
size: Some(
12,
),
}
Type {
kind: Reference(
Reference {
Expand Down
Loading
Loading