1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
//! Checks the basic functionality of `std::any::type_name` for primitive types
//! and simple generic structs.
//@ run-pass
#![allow(dead_code)]
use std::any::{Any, type_name, type_name_of_val};
use std::borrow::Cow;
struct Foo<T>(T);
struct Bar<'a>(&'a u32);
struct Baz<'a, T>(&'a T);
trait TrL<'a> {}
trait TrLA<'a> {
type A;
}
trait TrLT<'a, T> {}
trait TrLTA<'a, T> {
type A;
}
macro_rules! t {
($ty:ty, $str:literal) => {
assert_eq!(type_name::<$ty>(), $str);
}
}
macro_rules! v {
($v:expr, $str:literal) => {
assert_eq!(type_name_of_val(&$v), $str);
}
}
pub fn main() {
t!(bool, "bool");
t!(char, "char");
t!(u8, "u8");
t!(u16, "u16");
t!(u32, "u32");
t!(u64, "u64");
t!(u128, "u128");
t!(usize, "usize");
t!(i8, "i8");
t!(i16, "i16");
t!(i32, "i32");
t!(i64, "i64");
t!(i128, "i128");
t!(isize, "isize");
t!(String, "alloc::string::String");
t!(str, "str");
t!(&str, "&str");
t!(&'static str, "&str");
t!((u16, u32, u64), "(u16, u32, u64)");
t!([usize; 4], "[usize; 4]");
t!([usize], "[usize]");
t!(&[usize], "&[usize]");
t!(*const bool, "*const bool");
t!(*mut u64, "*mut u64");
t!(Vec<Vec<u32>>, "alloc::vec::Vec<alloc::vec::Vec<u32>>");
t!(Foo<usize>, "type_name_basic::Foo<usize>");
t!(Bar<'static>, "type_name_basic::Bar<'_>");
t!(Baz<'static, u32>, "type_name_basic::Baz<'_, u32>");
t!(dyn TrL<'static>, "dyn type_name_basic::TrL<'_>");
t!(dyn TrLA<'static, A = u32>, "dyn type_name_basic::TrLA<'_, A = u32>");
t!(
dyn TrLT<'static, Cow<'static, ()>>,
"dyn type_name_basic::TrLT<'_, alloc::borrow::Cow<'_, ()>>"
);
t!(
dyn TrLTA<'static, u32, A = Cow<'static, ()>>,
"dyn type_name_basic::TrLTA<'_, u32, A = alloc::borrow::Cow<'_, ()>>"
);
t!(fn(i32) -> i32, "fn(i32) -> i32");
t!(fn(&'static u32), "fn(&u32)");
// FIXME: these are sub-optimal, ideally the `for<...>` would be printed.
t!(for<'a> fn(&'a u32), "fn(&'_ u32)");
t!(for<'a, 'b> fn(&'a u32, &'b u32), "fn(&'_ u32, &'_ u32)");
t!(for<'a> fn(for<'b> fn(&'a u32, &'b u32)), "fn(fn(&'_ u32, &'_ u32))");
struct S<'a, T>(&'a T);
impl<'a, T: Clone> S<'a, T> {
fn test() {
t!(Cow<'a, T>, "alloc::borrow::Cow<'_, u32>");
}
}
S::<u32>::test();
struct Wrap<T>(T);
impl Wrap<&()> {
fn get(&self) -> impl Any {
struct Info;
Info
}
}
let a = Wrap(&()).get();
v!(a, "type_name_basic::main::Wrap<&()>::get::Info");
struct Issue146249<T>(T);
impl Issue146249<Box<dyn FnOnce()>> {
pub fn bar(&self) {
let f = || {};
v!(
f,
"type_name_basic::main::Issue146249<\
alloc::boxed::Box<dyn core::ops::function::FnOnce()>\
>::bar::{{closure}}"
);
}
}
let v: Issue146249<Box<dyn FnOnce()>> = Issue146249(Box::new(|| {}));
v.bar();
}
|