Closed alecmocatta closed 2 years ago
It would be cool if this calls get inlined in -C opt-level=1
. This would improve performance of debug builds of engines like bevy, compiled with weak optimizations.
Another problem is that ParialEq::eq isn't inlined even if I use #[inline(always)]
. Also, manual implementation of PartialEq would remove ability to use it in pattern matching like:
[godbolt](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(fontScale:14,fontUsePx:'0',j:1,lang:rust,selection:(endColumn:6,endLineNumber:11,positionColumn:6,positionLineNumber:8,selectionStartColumn:6,selectionStartLineNumber:11,startColumn:6,startLineNumber:8),source:'%23!!%5Bfeature(const_type_id)%5D%0A%0A%23%5Binline(always)%5D%0Apub+const+fn+is_bool%3CT:+!'static%3E()-%3Ebool%7B%0A++++use+std::any::TypeId%3B%0A%0A++++const+BOOL_ID:+TypeId+%3D+TypeId::of::%3Cbool%3E()%3B%0A++++match+TypeId::of::%3CT%3E()%7B%0A++++++++BOOL_ID+%3D%3E+true,%0A++++++++_+%3D%3E+false,%0A++++%7D%0A%7D%0A%0Apub+fn+good()-%3Ebool%7B%0A++++is_bool::%3Cbool%3E()%0A%7D%0A%0Apub+fn+bad()-%3Ebool%7B%0A++++is_bool::%3Cu8%3E()%0A%7D'),l:'5',n:'0',o:'Rust+source+%231',t:'0')),k:45.59471365638767,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:nightly,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'1',libraryCode:'1',trim:'1'),fontScale:14,fontUsePx:'0',j:1,lang:rust,libs:!(),options:'-Copt-level%3D1',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'rustc+nightly+(Editor+%231,+Compiler+%231)+Rust',t:'0')),k:54.40528634361234,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)
#![feature(const_type_id)]
#[inline(always)]
pub const fn is_bool<T: 'static>()->bool{
use std::any::TypeId;
const BOOL_ID: TypeId = TypeId::of::<bool>();
match TypeId::of::<T>(){
BOOL_ID => true,
_ => false,
}
}
pub fn good()->bool{
is_bool::<bool>()
}
pub fn bad()->bool{
is_bool::<u8>()
}
I think, we should close this issue in favor of https://github.com/rust-lang/rust/issues/77125
Or in favor of https://github.com/rust-lang/rust/issues/31844 which allows write such code:
#![feature(specialization)]
use std::marker::PhantomData;
struct IsSameType<T0: 'static, T1: 'static>(PhantomData<T0>, PhantomData<T1>);
trait IsSameTypeTrait{
const IS_SAME: bool;
}
impl<T0: 'static, T1: 'static> IsSameTypeTrait for IsSameType<T0, T1>{
default const IS_SAME: bool = false;
}
impl<T> IsSameTypeTrait for IsSameType<T, T>{
const IS_SAME: bool = true;
}
I decided to add #[inline]
because we unlikely to get #77125 resolved soon, and #31844 still has soundness problems.
Adding #[inline]
wouldn't have any effect without optimizations unfortunately because there must run InlinerPass which doesn't run on debug.
With New Pass Manager (which I hope would stabilized soon), users may set opt-level=1
for fast debug builds and get profits from this change.
TypeId
can be used to specialize code by comparing types explicitly (TypeId::of::<u8>() == TypeId::of::<T>()
, examples in the wild) or implicitly (<dyn Any>::downcast_mut
).In release mode this works well; in debug mode though the unused impl is unnecessarily monomorphized and codegened, slowing compile time as well as run time.
It isn't a major issue as it only affects debug mode, but I wondered if it was worth marking
TypeId::of
,<TypeId as PartialEq>::eq
,<dyn Any>::is
and the various downcast methods asinline(always)
to potentially reduce compile times and provide a nice debug mode runtime boost?See e.g.
abort
is present in IR/assembly: Playground