Skip to content

Commit c70ca54

Browse files
committed
Add dummy self pointer arg to emitted const fn
1 parent b5a6295 commit c70ca54

2 files changed

Lines changed: 44 additions & 31 deletions

File tree

compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,23 +126,42 @@ pub(crate) fn expand_deriving_eq(
126126

127127
let self_ty =
128128
self_ty.unwrap_or_else(|| cx.dcx().span_bug(span, "missing self type in `derive(Eq)`"));
129-
let assert_stmts = eq_assert_stmts_from_item(cx, span, item, ReplaceSelfTyVisitor(self_ty));
129+
let assert_stmts =
130+
eq_assert_stmts_from_item(cx, span, item, ReplaceSelfTyVisitor(self_ty.clone()));
130131

131132
// Skip generating `assert_fields_are_eq` impl if there are no assertions to make
132133
if assert_stmts.is_empty() {
133134
return;
134135
}
135136

136137
StripConstTraitBoundsVisitor.visit_generics(&mut fn_generics);
137-
push(Annotatable::Item(expand_const_item_block(cx, span, fn_generics, assert_stmts)));
138+
push(Annotatable::Item(expand_const_item_block(cx, span, fn_generics, self_ty, assert_stmts)));
138139
}
139140

140141
fn expand_const_item_block(
141142
cx: &ExtCtxt<'_>,
142143
span: Span,
143144
fn_generics: ast::Generics,
145+
self_ty: Box<ast::Ty>,
144146
assert_stmts: ThinVec<ast::Stmt>,
145147
) -> Box<ast::Item> {
148+
// We need a dummy const pointer to Self argument to ensure well-formedness of the Self type.
149+
// This doesn't add overhead because the fn itself is never called, and in fact should not
150+
// even have any runtime code generated for it as it's an inline const fn.
151+
let const_self_ptr_ty =
152+
cx.ty(span, ast::TyKind::Ptr(ast::MutTy { mutbl: ast::Mutability::Not, ty: self_ty }));
153+
let fn_args = thin_vec![cx.param(span, Ident::new(kw::Underscore, span), const_self_ptr_ty)];
154+
let fn_sig = ast::FnSig {
155+
header: ast::FnHeader {
156+
constness: ast::Const::Yes(span),
157+
coroutine_kind: None,
158+
safety: ast::Safety::Default,
159+
ext: ast::Extern::None,
160+
},
161+
decl: cx.fn_decl(fn_args, ast::FnRetTy::Default(span)),
162+
span,
163+
};
164+
146165
cx.item(
147166
span,
148167
ast::AttrVec::new(),
@@ -151,10 +170,9 @@ fn expand_const_item_block(
151170
id: ast::DUMMY_NODE_ID,
152171
block: cx.block(
153172
span,
154-
thin_vec![ast::Stmt {
173+
thin_vec![cx.stmt_item(
155174
span,
156-
id: ast::DUMMY_NODE_ID,
157-
kind: ast::StmtKind::Item(Box::new(ast::Item {
175+
Box::new(ast::Item {
158176
span,
159177
id: ast::DUMMY_NODE_ID,
160178
attrs: thin_vec![
@@ -175,23 +193,14 @@ fn expand_const_item_block(
175193
defaultness: ast::Defaultness::Implicit,
176194
ident: Ident::new(sym::assert_fields_are_eq, span),
177195
generics: fn_generics,
178-
sig: ast::FnSig {
179-
header: ast::FnHeader {
180-
constness: ast::Const::Yes(span),
181-
coroutine_kind: None,
182-
safety: ast::Safety::Default,
183-
ext: ast::Extern::None,
184-
},
185-
decl: cx.fn_decl(ThinVec::new(), ast::FnRetTy::Default(span)),
186-
span,
187-
},
196+
sig: fn_sig,
188197
contract: None,
189198
define_opaque: None,
190199
body: Some(cx.block(span, assert_stmts)),
191200
eii_impls: ThinVec::new(),
192201
}))
193-
}))
194-
},],
202+
})
203+
),],
195204
),
196205
}),
197206
)

tests/ui/deriving/deriving-all-codegen.stdout

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ const {
138138
#[doc(hidden)]
139139
#[coverage(off)]
140140
#[inline]
141-
const fn assert_fields_are_eq() {
141+
const fn assert_fields_are_eq(_: *const Point) {
142142
let _: ::core::cmp::AssertParamIsEq<u32>;
143143
}
144144
}
@@ -227,7 +227,7 @@ const {
227227
#[doc(hidden)]
228228
#[coverage(off)]
229229
#[inline]
230-
const fn assert_fields_are_eq() {
230+
const fn assert_fields_are_eq(_: *const PackedPoint) {
231231
let _: ::core::cmp::AssertParamIsEq<u32>;
232232
}
233233
}
@@ -311,7 +311,7 @@ const {
311311
#[doc(hidden)]
312312
#[coverage(off)]
313313
#[inline]
314-
const fn assert_fields_are_eq() {
314+
const fn assert_fields_are_eq(_: *const TupleSingleField) {
315315
let _: ::core::cmp::AssertParamIsEq<u32>;
316316
}
317317
}
@@ -387,7 +387,7 @@ const {
387387
#[doc(hidden)]
388388
#[coverage(off)]
389389
#[inline]
390-
const fn assert_fields_are_eq() {
390+
const fn assert_fields_are_eq(_: *const SingleField) {
391391
let _: ::core::cmp::AssertParamIsEq<bool>;
392392
}
393393
}
@@ -493,7 +493,7 @@ const {
493493
#[doc(hidden)]
494494
#[coverage(off)]
495495
#[inline]
496-
const fn assert_fields_are_eq() {
496+
const fn assert_fields_are_eq(_: *const Big) {
497497
let _: ::core::cmp::AssertParamIsEq<u32>;
498498
}
499499
}
@@ -690,7 +690,7 @@ const {
690690
#[doc(hidden)]
691691
#[coverage(off)]
692692
#[inline]
693-
const fn assert_fields_are_eq() {
693+
const fn assert_fields_are_eq(_: *const Recursive) {
694694
let _: ::core::cmp::AssertParamIsEq<Option<Box<Recursive>>>;
695695
}
696696
}
@@ -793,7 +793,7 @@ const {
793793
#[doc(hidden)]
794794
#[coverage(off)]
795795
#[inline]
796-
const fn assert_fields_are_eq() {
796+
const fn assert_fields_are_eq(_: *const Unsized) {
797797
let _: ::core::cmp::AssertParamIsEq<[u32]>;
798798
}
799799
}
@@ -891,7 +891,8 @@ const {
891891
#[coverage(off)]
892892
#[inline]
893893
const fn assert_fields_are_eq<T: ::core::cmp::Eq + Trait,
894-
U: ::core::cmp::Eq>() where T::A: ::core::cmp::Eq {
894+
U: ::core::cmp::Eq>(_: *const Generic<T, U>) where
895+
T::A: ::core::cmp::Eq {
895896
let _: ::core::cmp::AssertParamIsEq<T>;
896897
let _: ::core::cmp::AssertParamIsEq<T::A>;
897898
let _: ::core::cmp::AssertParamIsEq<U>;
@@ -990,7 +991,8 @@ const {
990991
#[doc(hidden)]
991992
#[coverage(off)]
992993
#[inline]
993-
const fn assert_fields_are_eq<'a, T: ::core::cmp::Eq + Trait>() {
994+
const fn assert_fields_are_eq<'a, T: ::core::cmp::Eq +
995+
Trait>(_: *const GenericLifetime<'a, T>) {
994996
let _: ::core::cmp::AssertParamIsEq<&'a T>;
995997
}
996998
}
@@ -1095,7 +1097,8 @@ const {
10951097
#[coverage(off)]
10961098
#[inline]
10971099
const fn assert_fields_are_eq<T: ::core::cmp::Eq + ::core::marker::Copy +
1098-
Trait, U: ::core::cmp::Eq + ::core::marker::Copy>() where
1100+
Trait, U: ::core::cmp::Eq +
1101+
::core::marker::Copy>(_: *const PackedGeneric<T, U>) where
10991102
T::A: ::core::cmp::Eq + ::core::marker::Copy {
11001103
let _: ::core::cmp::AssertParamIsEq<T>;
11011104
let _: ::core::cmp::AssertParamIsEq<T::A>;
@@ -1247,7 +1250,7 @@ const {
12471250
#[doc(hidden)]
12481251
#[coverage(off)]
12491252
#[inline]
1250-
const fn assert_fields_are_eq() {
1253+
const fn assert_fields_are_eq(_: *const Enum1) {
12511254
let _: ::core::cmp::AssertParamIsEq<u32>;
12521255
}
12531256
}
@@ -1491,7 +1494,7 @@ const {
14911494
#[doc(hidden)]
14921495
#[coverage(off)]
14931496
#[inline]
1494-
const fn assert_fields_are_eq() {
1497+
const fn assert_fields_are_eq(_: *const Mixed) {
14951498
let _: ::core::cmp::AssertParamIsEq<u32>;
14961499
let _: ::core::cmp::AssertParamIsEq<Option<u32>>;
14971500
let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
@@ -1690,7 +1693,7 @@ const {
16901693
#[doc(hidden)]
16911694
#[coverage(off)]
16921695
#[inline]
1693-
const fn assert_fields_are_eq() {
1696+
const fn assert_fields_are_eq(_: *const Fielded) {
16941697
let _: ::core::cmp::AssertParamIsEq<u32>;
16951698
let _: ::core::cmp::AssertParamIsEq<bool>;
16961699
let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
@@ -1814,7 +1817,8 @@ const {
18141817
#[doc(hidden)]
18151818
#[coverage(off)]
18161819
#[inline]
1817-
const fn assert_fields_are_eq<T: ::core::cmp::Eq, U: ::core::cmp::Eq>() {
1820+
const fn assert_fields_are_eq<T: ::core::cmp::Eq,
1821+
U: ::core::cmp::Eq>(_: *const EnumGeneric<T, U>) {
18181822
let _: ::core::cmp::AssertParamIsEq<T>;
18191823
let _: ::core::cmp::AssertParamIsEq<U>;
18201824
}

0 commit comments

Comments
 (0)