-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Erase query result types #107937
Erase query result types #107937
Changes from 1 commit
77eb2be
97befd4
65f0ce0
96f07a7
e4a6b06
3d9ce6c
6efc404
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/// Remaps the type with a different lifetime for 'tcx if applicable. | ||
pub trait Remap { | ||
type Remap<'a>; | ||
} | ||
|
||
impl Remap for u32 { | ||
type Remap<'a> = u32; | ||
} | ||
|
||
impl<T: Remap> Remap for Option<T> { | ||
type Remap<'a> = Option<T::Remap<'a>>; | ||
} | ||
|
||
impl Remap for () { | ||
type Remap<'a> = (); | ||
} | ||
|
||
impl<T0: Remap, T1: Remap> Remap for (T0, T1) { | ||
type Remap<'a> = (T0::Remap<'a>, T1::Remap<'a>); | ||
} | ||
|
||
impl<T0: Remap, T1: Remap, T2: Remap> Remap for (T0, T1, T2) { | ||
type Remap<'a> = (T0::Remap<'a>, T1::Remap<'a>, T2::Remap<'a>); | ||
} | ||
|
||
impl<T0: Remap, T1: Remap, T2: Remap, T3: Remap> Remap for (T0, T1, T2, T3) { | ||
type Remap<'a> = (T0::Remap<'a>, T1::Remap<'a>, T2::Remap<'a>, T3::Remap<'a>); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "rustc_erase" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this inside a new crate and not just in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // This is a separate crate so that we can `allow(incomplete_features)` for just `generic_const_exprs` There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, didn't see that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that |
||
version = "0.0.0" | ||
edition = "2021" | ||
|
||
[lib] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// This is a separate crate so that we can `allow(incomplete_features)` for just `generic_const_exprs` | ||
#![feature(generic_const_exprs)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess to explicitly answer
extremely very not stable 😅 |
||
#![allow(incomplete_features)] | ||
|
||
#[cfg(debug_assertions)] | ||
use std::intrinsics::type_name; | ||
use std::{ | ||
fmt, | ||
mem::{size_of, transmute_copy, MaybeUninit}, | ||
}; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct Erased<const N: usize> { | ||
data: MaybeUninit<[u8; N]>, | ||
#[cfg(debug_assertions)] | ||
type_id: &'static str, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we prefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That requires |
||
} | ||
|
||
impl<const N: usize> fmt::Debug for Erased<N> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "Erased<{}>", N) | ||
} | ||
} | ||
|
||
pub type Erase<T> = Erased<{ size_of::<T>() }>; | ||
|
||
#[inline(always)] | ||
pub fn erase<T: Copy>(src: T) -> Erased<{ size_of::<T>() }> { | ||
Erased { | ||
// SAFETY:: Is it safe to transmute to MaybeUninit | ||
data: unsafe { transmute_copy(&src) }, | ||
#[cfg(debug_assertions)] | ||
type_id: type_name::<T>(), | ||
} | ||
} | ||
|
||
/// Restores an erased value. | ||
/// | ||
/// This is only safe if `value` is a valid instance of `T`. | ||
/// For example if `T` was erased with `erase` previously. | ||
#[inline(always)] | ||
pub unsafe fn restore<T: Copy>(value: Erased<{ size_of::<T>() }>) -> T { | ||
#[cfg(debug_assertions)] | ||
assert_eq!(value.type_id, type_name::<T>()); | ||
unsafe { transmute_copy(&value.data) } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is
rustc_middle::ty::parametrized::ParameterizedOverTcx
that does the same thing.