Skip to content

Commit

Permalink
refactor(core): remove the TypeId: const PartialEq wrapper
Browse files Browse the repository at this point in the history
`core::any::TypeId` implements `const PartialEq` as of
[rust-lang/rust#101698][1].

[1]: rust-lang/rust#101698
  • Loading branch information
yvt committed Mar 18, 2023
1 parent ab05db4 commit 8b64feb
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 55 deletions.
17 changes: 0 additions & 17 deletions doc/toolchain_limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,23 +430,6 @@ const _: () = assert!(PartialEq::eq(&(A..A), &(A..A)));
```


### `[tag:type_id_partial_eq]` `TypeId: !const PartialEq`

The standard library doesn't provide a `const` trait implementation of `PartialEq` for `core::any::TypeId`.

```rust
use core::any::TypeId;
assert!(TypeId::of::<()>() == TypeId::of::<()>());
```

```rust,compile_fail,E0277
#![feature(const_type_id)]
use core::any::TypeId;
// error[E0277]: can't compare `TypeId` with `_` in const contexts
const _: () = assert!(TypeId::of::<()>() == TypeId::of::<()>());
```


### `[tag:range_const_iterator]` `Range<T>: !~const Iterator`

The standard library doesn't provide a `const` trait implementation of `Range<T>: Iterator`.
Expand Down
39 changes: 1 addition & 38 deletions src/r3_core/src/bag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! A heterogeneous collection to store property values.
use core::mem::transmute;
use core::{any::TypeId, mem::transmute};

/// A heterogeneous collection to store property values.
#[const_trait]
Expand Down Expand Up @@ -88,40 +88,3 @@ mod private {
impl<Head: 'static, Tail: ~const Bag> const Sealed for super::List<Head, Tail> {}
impl<Left: ~const Bag, Right: ~const Bag> const Sealed for super::Either<Left, Right> {}
}

// `TypeId` doesn't implement `const PartialEq` [ref:type_id_partial_eq]
/// A wrapper of [`core::any::TypeId`] that is usable in a constant context.
struct TypeId {
inner: core::any::TypeId,
}

impl TypeId {
#[inline]
const fn of<T: 'static>() -> Self {
Self {
inner: core::any::TypeId::of::<T>(),
}
}

#[inline]
const fn eq(&self, other: &Self) -> bool {
// This relies on the implementation details of `TypeId`, but I think
// we're are okay judging by the fact that WebRender is doing the same
// <https://github.com/rust-lang/rust/pull/75923#issuecomment-683090745>
unsafe {
type TypeIdBytes = [u8; core::mem::size_of::<core::any::TypeId>()];
let x: TypeIdBytes = transmute(self.inner);
let y: TypeIdBytes = transmute(other.inner);
// Can't just do `x == y` due to [ref:array_const_partial_eq].
// A non-idiomatic loop must be used due to [ref:const_for].
let mut i = 0;
while i < x.len() {
if x[i] != y[i] {
return false;
}
i += 1;
}
true
}
}
}

0 comments on commit 8b64feb

Please sign in to comment.