Modify derive_label to support no_std environments (#15465)
				
					
				
			# Objective - Contributes to #15460 ## Solution - Wrap `derive_label` `quote!` in an anonymous constant which contains an `extern crate alloc` statement, allowing use of the `alloc` namespace even when a user has not brought in the crate themselves. ## Testing - CI passed locally. ## Notes We can't generate code that uses `::std::boxed::Box` in `no_std` environments, but we also can't rely on `::alloc::boxed::Box` either, since the user might not have declared `extern crate alloc`. To resolve this, the generated code is wrapped in an anonymous constant which contains the `extern crate alloc` invocation. This does mean the macro is no longer hygienic against cases where the user provides an alternate `alloc` crate, however I believe this is an acceptable compromise. Additionally, this crate itself doesn't need to be `no_std`, it just needs to _generate_ `no_std` compatible code. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
		
							parent
							
								
									60cf7ca025
								
							
						
					
					
						commit
						6963b58eba
					
				| @ -81,21 +81,26 @@ pub fn derive_label( | |||||||
|         .unwrap(), |         .unwrap(), | ||||||
|     ); |     ); | ||||||
|     quote! { |     quote! { | ||||||
|         impl #impl_generics #trait_path for #ident #ty_generics #where_clause { |         // To ensure alloc is available, but also prevent its name from clashing, we place the implementation inside an anonymous constant
 | ||||||
|             fn dyn_clone(&self) -> ::std::boxed::Box<dyn #trait_path> { |         const _: () = { | ||||||
|                 ::std::boxed::Box::new(::core::clone::Clone::clone(self)) |             extern crate alloc; | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             fn as_dyn_eq(&self) -> &dyn #dyn_eq_path { |             impl #impl_generics #trait_path for #ident #ty_generics #where_clause { | ||||||
|                 self |                 fn dyn_clone(&self) -> alloc::boxed::Box<dyn #trait_path> { | ||||||
|             } |                     alloc::boxed::Box::new(::core::clone::Clone::clone(self)) | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|             fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) { |                 fn as_dyn_eq(&self) -> &dyn #dyn_eq_path { | ||||||
|                 let ty_id = ::core::any::TypeId::of::<Self>(); |                     self | ||||||
|                 ::core::hash::Hash::hash(&ty_id, &mut state); |                 } | ||||||
|                 ::core::hash::Hash::hash(self, &mut state); | 
 | ||||||
|  |                 fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) { | ||||||
|  |                     let ty_id = ::core::any::TypeId::of::<Self>(); | ||||||
|  |                     ::core::hash::Hash::hash(&ty_id, &mut state); | ||||||
|  |                     ::core::hash::Hash::hash(self, &mut state); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         }; | ||||||
|     } |     } | ||||||
|     .into() |     .into() | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zachary Harrold
						Zachary Harrold