about summary refs log tree commit diff
path: root/tests/ui/type/type-name-basic.rs
blob: 2c41cb80aea8f10bee324ef9e56efd5048c3953a (plain)
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();
}