Skip to content

Commit 8b6f468

Browse files
committed
Simplify provider api to improve llvm ir
1 parent cf9de23 commit 8b6f468

File tree

1 file changed

+23
-26
lines changed

1 file changed

+23
-26
lines changed

core/src/error.rs

+23-26
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,9 @@ fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reifi
404404
where
405405
I: tags::Type<'a>,
406406
{
407-
let mut tagged = TaggedOption::<'a, I>(None);
407+
let mut tagged = Tagged { tag_id: TypeId::of::<I>(), value: TaggedOption::<'a, I>(None) };
408408
err.provide(tagged.as_request());
409-
tagged.0
409+
tagged.value.0
410410
}
411411

412412
///////////////////////////////////////////////////////////////////////////////
@@ -507,16 +507,9 @@ where
507507
///
508508
#[unstable(feature = "error_generic_member_access", issue = "99301")]
509509
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
510-
pub struct Request<'a>(dyn Erased<'a> + 'a);
510+
pub struct Request<'a>(Tagged<dyn Erased<'a> + 'a>);
511511

512512
impl<'a> Request<'a> {
513-
/// Create a new `&mut Request` from a `&mut dyn Erased` trait object.
514-
fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Request<'a> {
515-
// SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Request<'a>` is safe since
516-
// `Request` is repr(transparent).
517-
unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Request<'a>) }
518-
}
519-
520513
/// Provide a value or other type with only static lifetimes.
521514
///
522515
/// # Examples
@@ -940,37 +933,38 @@ pub(crate) mod tags {
940933
#[repr(transparent)]
941934
pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option<I::Reified>);
942935

943-
impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> {
936+
impl<'a, I: tags::Type<'a>> Tagged<TaggedOption<'a, I>> {
944937
pub(crate) fn as_request(&mut self) -> &mut Request<'a> {
945-
Request::new(self as &mut (dyn Erased<'a> + 'a))
938+
let erased = self as &mut Tagged<dyn Erased<'a> + 'a>;
939+
// SAFETY: transmuting `&mut Tagged<dyn Erased<'a> + 'a>` to `&mut Request<'a>` is safe since
940+
// `Request` is repr(transparent).
941+
unsafe { &mut *(erased as *mut Tagged<dyn Erased<'a>> as *mut Request<'a>) }
946942
}
947943
}
948944

949945
/// Represents a type-erased but identifiable object.
950946
///
951947
/// This trait is exclusively implemented by the `TaggedOption` type.
952-
unsafe trait Erased<'a>: 'a {
953-
/// The `TypeId` of the erased type.
954-
fn tag_id(&self) -> TypeId;
955-
}
948+
unsafe trait Erased<'a>: 'a {}
956949

957-
unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {
958-
fn tag_id(&self) -> TypeId {
959-
TypeId::of::<I>()
960-
}
950+
unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {}
951+
952+
struct Tagged<E: ?Sized> {
953+
tag_id: TypeId,
954+
value: E,
961955
}
962956

963-
impl<'a> dyn Erased<'a> + 'a {
957+
impl<'a> Tagged<dyn Erased<'a> + 'a> {
964958
/// Returns some reference to the dynamic value if it is tagged with `I`,
965959
/// or `None` otherwise.
966960
#[inline]
967961
fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
968962
where
969963
I: tags::Type<'a>,
970964
{
971-
if self.tag_id() == TypeId::of::<I>() {
965+
if self.tag_id == TypeId::of::<I>() {
972966
// SAFETY: Just checked whether we're pointing to an I.
973-
Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
967+
Some(&unsafe { &*(self as *const Self).cast::<Tagged<TaggedOption<'a, I>>>() }.value)
974968
} else {
975969
None
976970
}
@@ -983,9 +977,12 @@ impl<'a> dyn Erased<'a> + 'a {
983977
where
984978
I: tags::Type<'a>,
985979
{
986-
if self.tag_id() == TypeId::of::<I>() {
987-
// SAFETY: Just checked whether we're pointing to an I.
988-
Some(unsafe { &mut *(self as *mut Self).cast::<TaggedOption<'a, I>>() })
980+
if self.tag_id == TypeId::of::<I>() {
981+
Some(
982+
// SAFETY: Just checked whether we're pointing to an I.
983+
&mut unsafe { &mut *(self as *mut Self).cast::<Tagged<TaggedOption<'a, I>>>() }
984+
.value,
985+
)
989986
} else {
990987
None
991988
}

0 commit comments

Comments
 (0)