You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: common.rs
    path of file: ./repos/prusti-dev/prusti-contracts/prusti-specs/src
    
    the code of the file until where you have to start completion: //! Common code for spec-rewriting

use proc_macro2::Ident;
pub(crate) use receiver_rewriter::*;
use rustc_hash::FxHashMap;
pub(crate) use self_type_rewriter::*;
use std::borrow::BorrowMut;
use syn::{parse_quote, punctuated::Punctuated, spanned::Spanned, GenericParam, TypeParam};
pub(crate) use syn_extensions::*;
use uuid::Uuid;

/// Module which provides various extension traits for syn types.
/// These allow for writing of generic code over these types.
mod syn_extensions {
    use syn::{
        Attribute, ForeignItemFn, Generics, ImplItemMacro, ImplItemMethod, ItemFn, ItemImpl,
        ItemStruct, ItemTrait, Macro, Signature, TraitItemMacro, TraitItemMethod,
    };

    /// Trait which signals that the corresponding syn item contains generics
    pub(crate) trait HasGenerics {
        fn generics(&self) -> &Generics;
        fn generics_mut(&mut self) -> &mut Generics;
    }

    impl HasGenerics for Generics {
        fn generics(&self) -> &Gen
    
pub(crate) fn add_phantom_data_for_generic_params(item_struct: &mut syn::ItemStruct) {
    let mut fields = vec![];

    let need_named_fields = matches!(item_struct.fields, syn::Fields::Named(_));

    let generate_field_ident = |span: proc_macro2::Span| {
        if need_named_fields {
            let uuid = Uuid::new_v4().simple();
            let field_name = format!("prusti_injected_phantom_field_{uuid}");
            return Some(syn::Ident::new(field_name.as_str(), span));
        }
        None
    };

    for generic_param in item_struct.generics.params.iter() {
        let ty: Option<syn::Type> = match generic_param {
            syn::GenericParam::Type(type_param) => {
                let ty_ident = &type_param.ident;
                let ty: syn::Type = parse_quote!(::core::marker::PhantomData<#ty_ident>);
                Some(ty)
            }
            syn::GenericParam::Lifetime(lt_def) => {
                let lt = &lt_def.lifetime;
                let ty: syn::Type = parse_quote!(&#lt ::core::marker::PhantomData<()>);
                Some(ty)
            }
            _ => None,
        };

        if ty.is_none() {
            continue;
        }
        let ty = ty.unwrap();

        let field = syn::Field {
            vis: syn::Visibility::Inherited,
            attrs: Vec::default(),
            ident: generate_field_ident(generic_param.span()),
            colon_token: None,
            ty,
        };
        fields.push(field);
    }

    if matches!(item_struct.fields, syn::Fields::Unit) {
        let field_types: Vec<syn::Type> = fields.into_iter().map(|field| field.ty).collect();
        let fields_unnamed: syn::FieldsUnnamed = parse_quote!((#(#field_types),*));
        item_struct.fields = syn::Fields::Unnamed(fields_unnamed);
    } else {
        match item_struct.fields.borrow_mut() {
            syn::Fields::Named(named_fields) => {
                named_fields.named.extend(fields);
            }
            syn::Fields::Unnamed(unnamed_fields) => {
                unnamed_fields.unnamed.extend(fields);
            }
            syn::Fields::Unit => unreachable!(),
        };
    }
}