Skip to content

Commit a3062aa

Browse files
committed
Only encode hir::Safety::Safe in metadata.
While `Unsafe` is much less common, a failure to encode it would make downstream crates default to `Safe` and think a thing marked as unsafe is actually safe
1 parent 6974191 commit a3062aa

File tree

5 files changed

+42
-13
lines changed

5 files changed

+42
-13
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4186,8 +4186,13 @@ impl<'hir> Item<'hir> {
41864186
}
41874187

41884188
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4189-
#[derive(Encodable, Decodable, HashStable_Generic)]
4189+
#[derive(Encodable, Decodable, HashStable_Generic, Default)]
41904190
pub enum Safety {
4191+
/// This is the default variant, because the compiler messing up
4192+
/// metadata encoding and failing to encode a `Safe` flag, means
4193+
/// downstream crates think a thing is `Unsafe` instead of silently
4194+
/// treating an unsafe thing as safe.
4195+
#[default]
41914196
Unsafe,
41924197
Safe,
41934198
}

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,7 @@ impl<'a> CrateMetadataRef<'a> {
11871187
}
11881188

11891189
fn get_safety(self, id: DefIndex) -> Safety {
1190-
self.root.tables.safety.get(self, id).unwrap_or_else(|| self.missing("safety", id))
1190+
self.root.tables.safety.get(self, id)
11911191
}
11921192

11931193
fn get_default_field(self, id: DefIndex) -> Option<DefId> {

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1697,7 +1697,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16971697
}));
16981698

16991699
for field in &variant.fields {
1700-
self.tables.safety.set_some(field.did.index, field.safety);
1700+
self.tables.safety.set(field.did.index, field.safety);
17011701
}
17021702

17031703
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ define_tables! {
402402
cross_crate_inlinable: Table<DefIndex, bool>,
403403
asyncness: Table<DefIndex, ty::Asyncness>,
404404
constness: Table<DefIndex, hir::Constness>,
405+
safety: Table<DefIndex, hir::Safety>,
405406

406407
- optional:
407408
attributes: Table<DefIndex, LazyArray<hir::Attribute>>,
@@ -411,7 +412,6 @@ define_tables! {
411412
associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>,
412413
def_kind: Table<DefIndex, DefKind>,
413414
visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
414-
safety: Table<DefIndex, hir::Safety>,
415415
def_span: Table<DefIndex, LazyValue<Span>>,
416416
def_ident_span: Table<DefIndex, LazyValue<Span>>,
417417
lookup_stability: Table<DefIndex, LazyValue<hir::Stability>>,

compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,17 @@ impl IsDefault for ty::Asyncness {
3737
impl IsDefault for hir::Constness {
3838
fn is_default(&self) -> bool {
3939
match self {
40-
rustc_hir::Constness::Const => false,
41-
rustc_hir::Constness::NotConst => true,
40+
hir::Constness::Const => false,
41+
hir::Constness::NotConst => true,
42+
}
43+
}
44+
}
45+
46+
impl IsDefault for hir::Safety {
47+
fn is_default(&self) -> bool {
48+
match self {
49+
hir::Safety::Safe => false,
50+
hir::Safety::Unsafe => true,
4251
}
4352
}
4453
}
@@ -204,13 +213,6 @@ fixed_size_enum! {
204213
}
205214
}
206215

207-
fixed_size_enum! {
208-
hir::Safety {
209-
( Unsafe )
210-
( Safe )
211-
}
212-
}
213-
214216
fixed_size_enum! {
215217
hir::CoroutineKind {
216218
( Coroutine(hir::Movability::Movable) )
@@ -343,6 +345,28 @@ impl FixedSizeEncoding for hir::Constness {
343345
}
344346
}
345347

348+
impl FixedSizeEncoding for hir::Safety {
349+
type ByteArray = [u8; 1];
350+
351+
#[inline]
352+
fn from_bytes(b: &[u8; 1]) -> Self {
353+
match b[0] {
354+
0 => hir::Safety::Unsafe,
355+
1 => hir::Safety::Safe,
356+
_ => unreachable!(),
357+
}
358+
}
359+
360+
#[inline]
361+
fn write_to_bytes(self, b: &mut [u8; 1]) {
362+
debug_assert!(!self.is_default());
363+
b[0] = match self {
364+
hir::Safety::Unsafe => 0,
365+
hir::Safety::Safe => 1,
366+
}
367+
}
368+
}
369+
346370
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
347371
// generic `LazyValue<T>` impl, but in the general case we might not need / want
348372
// to fit every `usize` in `u32`.

0 commit comments

Comments
 (0)