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: generalize.rs
    path of file: ./repos/gluon/check/src/typecheck
    
    the code of the file until where you have to start completion: use crate::base::{
    ast::{self, MutVisitor, SpannedExpr, SpannedIdent},
    fnv::{FnvMap, FnvSet},
    pos::{BytePos, Span},
    symbol::Symbol,
    types::{self, AppVec, ArcType, BuiltinType, Flags, Generic, Type, TypeContext, TypePtr},
};

use crate::{substitution::Substitution, typ::RcType, typecheck::Typecheck};

pub(crate) struct TypeGeneralizer<'a, 'b: 'a, 'ast> {
    level: u32,
    unbound_variables: FnvMap<u32, RcType>,
    /// We delay updating the substitution until after all recursive bindings have been typechecked
    /// to ensure that they get can figure out which variable got generalized for each binding
    delayed_generalizations: Vec<(u32, RcType)>,
    variable_generator: Option<TypeVariableGenerator>,
    top_type: RcType,
    pub tc: &'a mut Typ
    
    fn new(subs: &Substitution<RcType>, typ: &RcType) -> TypeVariableGenerator {
        fn gather_foralls(map: &mut FnvSet<Symbol>, subs: &Substitution<RcType>, typ: &RcType) {
            if !typ
                .flags()
                .intersects(Flags::HAS_VARIABLES | Flags::HAS_FORALL)
            {
                return;
            }
            let typ = subs.real(typ);
            if let Type::Forall(ref params, _) = **typ {
                map.extend(params.iter().map(|param| param.id.clone()));
            }
            types::walk_type_(
                typ,
                &mut types::ControlVisitation(|typ: &RcType| {
                    gather_foralls(map, subs, typ);
                }),
            );
        }
        let mut map = FnvSet::default();
        gather_foralls(&mut map, subs, typ);
        TypeVariableGenerator {
            map,
            name: String::new(),
            i: 0,
        }
    }