Repository navigation
Tracking issue for stabilizing Error::type_id #60784
Description
Activity
- addedC-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
on May 13, 2019 Here's an unbaked thought: Can we make an extension
unsafe trait ErrorTypeIdExttoError, seal that extension trait (meaning that users cannot implement it), and then provide a blanket implementation forError?I think my unbaked idea is not implementable in current Rust:
trait Error { ... fn as_dyn_any(&self) -> &dyn Any where Self: 'static { self as _ } fn as_mut_dyn_any(&mut self) -> &mut dyn Any where Self: 'static { self as _ } }The only problem is we can't add a "where Self:Sized" bound to the "{ self as _ }" part.
It’s tempting to make
Anya super-trait ofError, and rely onAny::type_id. This would be sound becauseAnyalready has a blanket impl that covers every possible impl, so it cannot be overridden.However
Anyrequires'staticbutErrordoesn’t (only itsTypeId-related methods do), so this plan doesn’t work as-is.@SimonSapin Wasn't relating Any's bound discussed at some point?
On unstable we have
#[marker]traits which cannot override anything in their impls -- if they were allowed to define associated items with defaults in their trait definition, it would be another way to do this, though that considered too large a change to make with just a PR in #53693 (comment).- added a commit that references this issue
on May 13, 2019 I'm not sure why this functionality should be left to the library at all. Maybe we really need a
type_id_valpaired to the existingintrinsics::type_id()? (Similar tosize_ofandsize_of_val.)Reacted by LifeIsStrange, William Douglas, Nico Burns, bwo, Félix, Aaron Hill and Adoo@skade Yes, this was discussed to say that it would be unsound: #41875 (comment)
@cuviper This sounds doable, but would require a
TypeIdvalue to be stored in every trait object vtable. This has some code size cost. The size and alignment of the underlying type (and pointer todrop_in_place<U>) are already special-cased like this, to allowBox<dyn Trait>to exist for any trait and be dropped/deallocated correctly. Having thetype_idmethod be part of theErrortrait puts (a way to get) theTypeIdin vtables fordyn Errortoday.If we add
fn type_id_of_val<T: ?Sized>(x: &T) -> TypeIdwe’d also need to carefully define its semantics. Withfoo: &dyn SomeTraitcoerced from&UwhereU: SomeTrait, what’s interesting is hereTypeId::of<T>(). Butdyn SomeTraitis also a type, soTypeId::of<dyn SomeTrait>()also exists. Iftype_id_of_val(foo)returns the former, what shouldtype_id_of_val(bar)return whenT: Sizedtype? WhenTis a[X]slice?If rust-lang/rfcs#2580 is accepted and implemented we could have
T: std::ptr::Pointee<Metadata = &'static VTable>to restrict a type parameter todyn SomeTraittrait objects. Or more simply for this case, atype_idmethod onVTable(which in that RFC can be accessed through thestd::ptr::metadatafunction.)Reacted by Josh Stone30 remaining items
- addedC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCB-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.and removedI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessC-bugCategory: This is a bug.Category: This is a bug.
on May 20, 2019 I wouldn't want to stabilize this with the private type hack it currently uses, so I think a blocker on stabilizing this API is one of these two things:
- Making non-overrideable methods in traits.
- Making methods which are unsafe to implement (not to call) without making the entire trait unsafe to implement.
what about something like:
pub unsafe trait ErrorTypeId { fn type_id(&self) -> TypeId where Self: 'static { TypeId::of::<Self>() } } unsafe impl<T: ?Sized> ErrorTypeId for T {} pub trait Error: Debug + Display + ErrorTypeId { // ... }
@programmerjake I've slightly extended this by making it not specific to Error and wrote up an RFC. rust-lang/rfcs#2738
@programmerjake I've slightly extended this by making it not specific to Error and wrote up an RFC. rust-lang/rfcs#2738
@leo60228 Thanks!
Reacted by leo60228- addedI-libs-radarLibs issues that are tracked on the team's radar.Libs issues that are tracked on the team's radar.
on Jul 30, 2020 - addedPG-error-handlingProject group: Error handling (https://github.com/rust-lang/project-error-handling)Project group: Error handling (https://github.com/rust-lang/project-error-handling)
on Sep 27, 2021 What's going on on this?
trait method
implrestrictions rust-lang/rfcs#3678 would allow stabilizing this with a nice interface:pub impl(self) fn type_id(&self) -> TypeId { ... }
- addedT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.and removedT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
on Aug 12, 2026
View all comments
Updated Issue
This is a tracking issue for stabilizing the functionality of
Error::type_idsomehow. The subject of a historical security advisory the API was recently changed to prevent memory unsafety issues on all channels including nightly. The functionality, however, is still unstable, so we should stabilize it at some point!Original issue.
Reported by @seanmonstar to the security mailing list recently, it was discovered that the recent stabilization of
Error::type_idin Rust 1.34.0 is actually not memory safe. Described in a recent security announcement the stabilization ofError::type_idhas been reverted for stable, beta, and master.This leaves us, however, with the question of what to do about this API?
Error::type_idhas been present since the inception of theErrortrait, all the way back to 1.0.0. It's unstable, however, and is pretty rare as well to have a manual implementation of thetype_idfunction. Despite this we would ideally still like a path to stability which includes safety at some point.This tracking issue is intended to serve as a location to discuss this issue and determine the best way forward to fully removing
Error::type_id(so even nightly users are not affected by this memory safety issue) and having a stable mechanism for the functionality.