summaryrefslogtreecommitdiffstats
path: root/third_party/rust/derive_more-impl/src/as_mut.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/derive_more-impl/src/as_mut.rs')
-rw-r--r--third_party/rust/derive_more-impl/src/as_mut.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/third_party/rust/derive_more-impl/src/as_mut.rs b/third_party/rust/derive_more-impl/src/as_mut.rs
new file mode 100644
index 0000000000..1d05adc505
--- /dev/null
+++ b/third_party/rust/derive_more-impl/src/as_mut.rs
@@ -0,0 +1,81 @@
+use crate::utils::{
+ add_where_clauses_for_new_ident, AttrParams, MultiFieldData, State,
+};
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+use syn::{parse::Result, DeriveInput};
+
+pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
+ let as_mut_type = format_ident!("__AsMutT");
+ let state = State::with_type_bound(
+ input,
+ trait_name,
+ "as_mut".into(),
+ AttrParams::ignore_and_forward(),
+ false,
+ )?;
+ let MultiFieldData {
+ fields,
+ input_type,
+ members,
+ infos,
+ trait_path,
+ impl_generics,
+ ty_generics,
+ where_clause,
+ ..
+ } = state.enabled_fields_data();
+ let sub_items: Vec<_> = infos
+ .iter()
+ .zip(members.iter())
+ .zip(fields)
+ .map(|((info, member), field)| {
+ let field_type = &field.ty;
+ if info.forward {
+ let trait_path = quote! { #trait_path<#as_mut_type> };
+ let type_where_clauses = quote! {
+ where #field_type: #trait_path
+ };
+ let new_generics = add_where_clauses_for_new_ident(
+ &input.generics,
+ &[field],
+ &as_mut_type,
+ type_where_clauses,
+ false,
+ );
+ let (impl_generics, _, where_clause) = new_generics.split_for_impl();
+ let casted_trait = quote! { <#field_type as #trait_path> };
+ (
+ quote! { #casted_trait::as_mut(&mut #member) },
+ quote! { #impl_generics },
+ quote! { #where_clause },
+ quote! { #trait_path },
+ quote! { #as_mut_type },
+ )
+ } else {
+ (
+ quote! { &mut #member },
+ quote! { #impl_generics },
+ quote! { #where_clause },
+ quote! { #trait_path<#field_type> },
+ quote! { #field_type },
+ )
+ }
+ })
+ .collect();
+ let bodies = sub_items.iter().map(|i| &i.0);
+ let impl_genericses = sub_items.iter().map(|i| &i.1);
+ let where_clauses = sub_items.iter().map(|i| &i.2);
+ let trait_paths = sub_items.iter().map(|i| &i.3);
+ let return_types = sub_items.iter().map(|i| &i.4);
+
+ Ok(quote! {#(
+ #[automatically_derived]
+ impl #impl_genericses #trait_paths for #input_type #ty_generics #where_clauses {
+ #[inline]
+ fn as_mut(&mut self) -> &mut #return_types {
+ #bodies
+ }
+ }
+ )*})
+}