Skip to content

Commit e836a4c

Browse files
committed
Prevent Error::type_id overrides
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 rust-lang#60784
1 parent 4f53b5c commit e836a4c

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/libstd/error.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,19 @@ pub trait Error: Debug + Display {
201201
#[unstable(feature = "error_type_id",
202202
reason = "this is memory unsafe to override in user code",
203203
issue = "60784")]
204-
fn type_id(&self) -> TypeId where Self: 'static {
204+
fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static {
205205
TypeId::of::<Self>()
206206
}
207207
}
208208

209+
mod private {
210+
// this is a hack to prevent type_id from being overridden by Error
211+
// implementations, since that can enable unsound downcasting.
212+
#[unstable(feature = "error_type_id", issue = "60784")]
213+
#[derive(Debug)]
214+
pub struct Internal;
215+
}
216+
209217
#[stable(feature = "rust1", since = "1.0.0")]
210218
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
211219
/// Converts a type of [`Error`] into a box of dyn [`Error`].
@@ -575,7 +583,7 @@ impl dyn Error + 'static {
575583
let t = TypeId::of::<T>();
576584

577585
// Get TypeId of the type in the trait object
578-
let boxed = self.type_id();
586+
let boxed = self.type_id(private::Internal);
579587

580588
// Compare both TypeIds on equality
581589
t == boxed

0 commit comments

Comments
 (0)