lang: Strengthen RFC 3391 guarantees to match T-lang consensus · rust-lang/rust@7baf066 (original) (raw)

1

1

`//@ build-pass

`

``

2

`+

/*!

`

``

3

+

``

4

`+

The guarantees in RFC 3391 were strengthened as a result of the 2024 Oct 09 T-lang meeting^1

`

``

5

`+

following the precedent of T-lang's guaranteeing^2 ABI compatibility for "Option-like" enums^2.

`

``

6

`+

We now guarantee ABI compatibility for enums that conform to these rules described by scottmcm:

`

``

7

+

``

8

`` +

``

``

9

`` +

``

``

10

`` +

``

``

11

`+

`

``

12

+

``

13

`+

Where "all" fields includes "there aren't any fields, so they're vacuously all 1-ZSTs".

`

``

14

+

``

15

`+

Note: "1-ZST" means a type of size 0 and alignment 1.

`

``

16

+

``

17

`+

The reason alignment of the zero-sized type matters is it can affect the alignment of the enum,

`

``

18

`+

which also will affect its size if the enum has a non-zero size.

`

``

19

+

``

20

`+

`

``

21

`+

`

``

22

+

``

23

`+

*/

`

``

24

+

2

25

`#![allow(dead_code)]

`

3

26

`#![deny(improper_ctypes)]

`

4

27

`#![feature(ptr_internals)]

`

`@@ -59,4 +82,52 @@ extern "C" {

`

59

82

`fn result_1zst_exhaustive_no_field_e(x: Result<NoField, num::NonZero>);

`

60

83

`}

`

61

84

``

``

85

`+

// Custom "Result-like" enum for testing custom "Option-like" types are also accepted

`

``

86

`+

enum Either<L, R> {

`

``

87

`+

Left(L),

`

``

88

`+

Right(R),

`

``

89

`+

}

`

``

90

+

``

91

`+

extern "C" {

`

``

92

`+

fn either_ref_t(x: Either<&'static u8, ()>);

`

``

93

`+

fn either_fn_t(x: Either<extern "C" fn(), ()>);

`

``

94

`+

fn either_nonnull_t(x: Either<std::ptr::NonNull, ()>);

`

``

95

`+

fn either_unique_t(x: Either<std::ptr::Unique, ()>);

`

``

96

`+

fn either_nonzero_u8_t(x: Either<num::NonZero, ()>);

`

``

97

`+

fn either_nonzero_u16_t(x: Either<num::NonZero, ()>);

`

``

98

`+

fn either_nonzero_u32_t(x: Either<num::NonZero, ()>);

`

``

99

`+

fn either_nonzero_u64_t(x: Either<num::NonZero, ()>);

`

``

100

`+

fn either_nonzero_usize_t(x: Either<num::NonZero, ()>);

`

``

101

`+

fn either_nonzero_i8_t(x: Either<num::NonZero, ()>);

`

``

102

`+

fn either_nonzero_i16_t(x: Either<num::NonZero, ()>);

`

``

103

`+

fn either_nonzero_i32_t(x: Either<num::NonZero, ()>);

`

``

104

`+

fn either_nonzero_i64_t(x: Either<num::NonZero, ()>);

`

``

105

`+

fn either_nonzero_isize_t(x: Either<num::NonZero, ()>);

`

``

106

`+

fn either_transparent_struct_t(x: Either<TransparentStruct<num::NonZero>, ()>);

`

``

107

`+

fn either_transparent_enum_t(x: Either<TransparentEnum<num::NonZero>, ()>);

`

``

108

`+

fn either_phantom_t(x: Either<num::NonZero, std:📑:PhantomData<()>>);

`

``

109

`+

fn either_1zst_exhaustive_no_variant_t(x: Either<num::NonZero, Z>);

`

``

110

`+

fn either_1zst_exhaustive_no_field_t(x: Either<num::NonZero, NoField>);

`

``

111

+

``

112

`+

fn either_ref_e(x: Either<(), &'static u8>);

`

``

113

`+

fn either_fn_e(x: Either<(), extern "C" fn()>);

`

``

114

`+

fn either_nonnull_e(x: Either<(), std::ptr::NonNull>);

`

``

115

`+

fn either_unique_e(x: Either<(), std::ptr::Unique>);

`

``

116

`+

fn either_nonzero_u8_e(x: Either<(), num::NonZero>);

`

``

117

`+

fn either_nonzero_u16_e(x: Either<(), num::NonZero>);

`

``

118

`+

fn either_nonzero_u32_e(x: Either<(), num::NonZero>);

`

``

119

`+

fn either_nonzero_u64_e(x: Either<(), num::NonZero>);

`

``

120

`+

fn either_nonzero_usize_e(x: Either<(), num::NonZero>);

`

``

121

`+

fn either_nonzero_i8_e(x: Either<(), num::NonZero>);

`

``

122

`+

fn either_nonzero_i16_e(x: Either<(), num::NonZero>);

`

``

123

`+

fn either_nonzero_i32_e(x: Either<(), num::NonZero>);

`

``

124

`+

fn either_nonzero_i64_e(x: Either<(), num::NonZero>);

`

``

125

`+

fn either_nonzero_isize_e(x: Either<(), num::NonZero>);

`

``

126

`+

fn either_transparent_struct_e(x: Either<(), TransparentStruct<num::NonZero>>);

`

``

127

`+

fn either_transparent_enum_e(x: Either<(), TransparentEnum<num::NonZero>>);

`

``

128

`+

fn either_phantom_e(x: Either<num::NonZero, std:📑:PhantomData<()>>);

`

``

129

`+

fn either_1zst_exhaustive_no_variant_e(x: Either<Z, num::NonZero>);

`

``

130

`+

fn either_1zst_exhaustive_no_field_e(x: Either<NoField, num::NonZero>);

`

``

131

`+

}

`

``

132

+

62

133

`pub fn main() {}

`