Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0fa70c3

Browse files
committed
safe transmute: revise Hash, PartialEq impls on VariantDef, FieldDef
Exhaustively destructure parameter(s) so that changes to type definitions will lead to compile errors, thus reminding contributors to re-assess the assumptions underpinning these impls. ref: rust-lang#92268 ref: rust-lang#92268
1 parent 8c5c291 commit 0fa70c3

File tree

1 file changed

+61
-12
lines changed
  • compiler/rustc_middle/src/ty

1 file changed

+61
-12
lines changed

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,23 +1724,56 @@ impl VariantDef {
17241724
}
17251725
}
17261726

1727-
/// There should be only one VariantDef for each `def_id`, therefore
1728-
/// it is fine to implement `PartialEq` only based on `def_id`.
17291727
impl PartialEq for VariantDef {
17301728
#[inline]
17311729
fn eq(&self, other: &Self) -> bool {
1732-
self.def_id == other.def_id
1730+
// There should be only one `VariantDef` for each `def_id`, therefore
1731+
// it is fine to implement `PartialEq` only based on `def_id`.
1732+
//
1733+
// Below, we exhaustively destructure `self` and `other` so that if the
1734+
// definition of `VariantDef` changes, a compile-error will be produced,
1735+
// reminding us to revisit this assumption.
1736+
1737+
let Self {
1738+
def_id: lhs_def_id,
1739+
ctor_def_id: _,
1740+
name: _,
1741+
discr: _,
1742+
fields: _,
1743+
ctor_kind: _,
1744+
flags: _,
1745+
} = &self;
1746+
1747+
let Self {
1748+
def_id: rhs_def_id,
1749+
ctor_def_id: _,
1750+
name: _,
1751+
discr: _,
1752+
fields: _,
1753+
ctor_kind: _,
1754+
flags: _,
1755+
} = other;
1756+
1757+
lhs_def_id == rhs_def_id
17331758
}
17341759
}
17351760

17361761
impl Eq for VariantDef {}
17371762

1738-
/// There should be only one VariantDef for each `def_id`, therefore
1739-
/// it is fine to implement `Hash` only based on `def_id`.
17401763
impl Hash for VariantDef {
17411764
#[inline]
17421765
fn hash<H: Hasher>(&self, s: &mut H) {
1743-
self.def_id.hash(s)
1766+
// There should be only one `VariantDef` for each `def_id`, therefore
1767+
// it is fine to implement `Hash` only based on `def_id`.
1768+
//
1769+
// Below, we exhaustively destructure `self` so that if the definition
1770+
// of `VariantDef` changes, a compile-error will be produced, reminding
1771+
// us to revisit this assumption.
1772+
1773+
let Self { def_id, ctor_def_id: _, name: _, discr: _, fields: _, ctor_kind: _, flags: _ } =
1774+
&self;
1775+
1776+
def_id.hash(s)
17441777
}
17451778
}
17461779

@@ -1764,23 +1797,39 @@ pub struct FieldDef {
17641797
pub vis: Visibility,
17651798
}
17661799

1767-
/// There should be only one FieldDef for each `did`, therefore
1768-
/// it is fine to implement `PartialEq` only based on `did`.
17691800
impl PartialEq for FieldDef {
17701801
#[inline]
17711802
fn eq(&self, other: &Self) -> bool {
1772-
self.did == other.did
1803+
// There should be only one `FieldDef` for each `did`, therefore it is
1804+
// fine to implement `PartialEq` only based on `did`.
1805+
//
1806+
// Below, we exhaustively destructure `self` so that if the definition
1807+
// of `FieldDef` changes, a compile-error will be produced, reminding
1808+
// us to revisit this assumption.
1809+
1810+
let Self { did: lhs_did, name: _, vis: _ } = &self;
1811+
1812+
let Self { did: rhs_did, name: _, vis: _ } = other;
1813+
1814+
lhs_did == rhs_did
17731815
}
17741816
}
17751817

17761818
impl Eq for FieldDef {}
17771819

1778-
/// There should be only one FieldDef for each `did`, therefore
1779-
/// it is fine to implement `Hash` only based on `did`.
17801820
impl Hash for FieldDef {
17811821
#[inline]
17821822
fn hash<H: Hasher>(&self, s: &mut H) {
1783-
self.did.hash(s)
1823+
// There should be only one `FieldDef` for each `did`, therefore it is
1824+
// fine to implement `Hash` only based on `did`.
1825+
//
1826+
// Below, we exhaustively destructure `self` so that if the definition
1827+
// of `FieldDef` changes, a compile-error will be produced, reminding
1828+
// us to revisit this assumption.
1829+
1830+
let Self { did, name: _, vis: _ } = &self;
1831+
1832+
did.hash(s)
17841833
}
17851834
}
17861835

0 commit comments

Comments
 (0)