Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions library/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub trait Error: Debug + Display {
reason = "this is memory-unsafe to override in user code",
issue = "60784"
)]
fn type_id(&self, _: private::Internal) -> TypeId
final fn type_id(&self) -> TypeId
where
Self: 'static,
{
Expand Down Expand Up @@ -260,14 +260,6 @@ pub trait Error: Debug + Display {
fn provide<'a>(&'a self, request: &mut Request<'a>) {}
}

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;
}

#[unstable(feature = "never_type", issue = "35121")]
impl Error for ! {}

Expand All @@ -281,7 +273,7 @@ impl dyn Error + 'static {
let t = TypeId::of::<T>();

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

// Compare both `TypeId`s on equality.
t == concrete
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
#![feature(f16)]
#![feature(f128)]
#![feature(field_projections)]
#![feature(final_associated_functions)]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR uses final to make Error::type_id un-overridable and this should helps the stabilization of Error::type_id.

(Wouldn't that be publicly exposing unstable language surface via a stable API? Anyway, not a library reviewer)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, Error::type_id is not a stable API?

#![feature(freeze_impls)]
#![feature(fundamental)]
#![feature(funnel_shifts)]
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/std/impl-error-type-id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![feature(error_type_id)]

#[derive(Debug)]
struct T;

impl std::fmt::Display for T {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "T")
}
}

impl std::error::Error for T {
fn type_id(&self) -> std::any::TypeId {
//~^ ERROR cannot override `type_id` because it already has a `final` definition in the trait
std::any::TypeId::of::<Self>()
}
}

fn main() {}
11 changes: 11 additions & 0 deletions tests/ui/std/impl-error-type-id.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: cannot override `type_id` because it already has a `final` definition in the trait
--> $DIR/impl-error-type-id.rs:13:5
|
LL | fn type_id(&self) -> std::any::TypeId {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `type_id` is marked final here
--> $SRC_DIR/core/src/error.rs:LL:COL

error: aborting due to 1 previous error

Loading