@@ -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
140141fn 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 )
0 commit comments