| //! 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(); | |
| } |