Skip to content

Commit

Permalink
Prevent Error::type_id overrides
Browse files Browse the repository at this point in the history
type_id now takes an argument that can't be named outside of the
std::error module, which prevents any implementations from overriding
it. It's a pretty grody solution, and there's no way we can stabilize
the method with this API, but it avoids the soudness issue!

Closes #60784
  • Loading branch information
sfackler committed May 17, 2019
1 parent 4f53b5c commit e836a4c
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/libstd/error.rs
Expand Up @@ -201,11 +201,19 @@ pub trait Error: Debug + Display {
#[unstable(feature = "error_type_id",
reason = "this is memory unsafe to override in user code",
issue = "60784")]
fn type_id(&self) -> TypeId where Self: 'static {
fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static {
TypeId::of::<Self>()
}
}

mod private {
// this is a hack to prevent type_id from being overridden by Error
// implementations, since that can enable unsound downcasting.
#[unstable(feature = "error_type_id", issue = "60784")]
#[derive(Debug)]
pub struct Internal;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
/// Converts a type of [`Error`] into a box of dyn [`Error`].
Expand Down Expand Up @@ -575,7 +583,7 @@ impl dyn Error + 'static {
let t = TypeId::of::<T>();

// Get TypeId of the type in the trait object
let boxed = self.type_id();
let boxed = self.type_id(private::Internal);

// Compare both TypeIds on equality
t == boxed
Expand Down

0 comments on commit e836a4c

Please sign in to comment.