fn generalize_variables<'i>(
        &mut self,
        args: &mut Iterator<Item = &'i mut SpannedIdent<Symbol>>,
        expr: &mut SpannedExpr<Symbol>,
    ) {
        self.tc.type_variables.enter_scope();

        // Replaces all type variables with their inferred types
        struct ReplaceVisitor<'a: 'c, 'b: 'a, 'c> {
            generalizer: &'c mut TypeGeneralizer<'a, 'b>,
        }

        impl<'a, 'b, 'c, 'd> MutVisitor<'d> for ReplaceVisitor<'a, 'b, 'c> {
            type Ident = Symbol;

            fn visit_expr(&mut self, e: &'d mut SpannedExpr<Self::Ident>) {
                self.generalizer.tc.type_variables.enter_scope();
                self.generalizer.span = e.span;
                ast::walk_mut_expr(self, e);
                self.generalizer.tc.type_variables.exit_scope();
            }

            fn visit_spanned_typed_ident(&mut self, id: &mut SpannedIdent<Symbol>) {
                self.generalizer.span = id.span;
                self.visit_ident(&mut id.value)
            }
            fn visit_typ(&mut self, typ: &mut ArcType) {
                {
                    let type_cache = &self.generalizer.tc.type_cache;
                    self.generalizer.tc.type_variables.extend(
                        typ.forall_params()
                            .map(|param| (param.id.clone(), type_cache.hole())),
                    );
                }
                if let Some(finished) = self.generalizer.generalize_type(typ) {
                    *typ = finished;
                }
            }
        }

        {
            let mut visitor = ReplaceVisitor { generalizer: self };
            visitor.visit_expr(expr);
            for arg in &mut *args {
                visitor.visit_typ(&mut arg.value.typ)
            }
        }

        self.tc.type_variables.exit_scope();
    }
/// Generalizing updates all variables which are above `level` into "generic variables". A
/// generic variable is instantiated with a fresh type variable each time it is refered to.
///
/// Generalzing is a crucial part when inferring types as types will otherwise be less general
/// than they need to. Consider the following expression.
/// ```f#
/// let id x = x
/// in id 2
/// ```
/// If the variable in `id` was not generalized before the `id 2` call the variable would be
/// unified to an `Int` which is not what we want. Generalazing before checking the body of the
/// `let` basically infers that the variables in `id` does not refer to anything outside the
/// `let` scope and can thus be "generalized" into `a -> a` which is instantiated with a fresh
/// type variable in the `id 2` call.
Generalizing updates all variables which are above `level` into "generic variables". A
generic variable is instantiated with a fresh type variable each time it is refered to.

Generalzing is a crucial part when inferring types as types will otherwise be less general
than they need to. Consider the following expression.
Generalizing updates all variables which are above ` level ` into " generic variables " . A generic variable is instantiated with a fresh type variable each time it is refered to . Generalzing is a crucial part when inferring types as types will otherwise be less general than they need to . Consider the following expression .
fn generalize_variables<'i>(
        &mut self,
        args: &mut Iterator<Item = &'i mut SpannedIdent<Symbol>>,
        expr: &mut SpannedExpr<Symbol>,
    ) {
        self.tc.type_variables.enter_scope();
        // Replaces all type variables with their inferred types
        struct ReplaceVisitor<'a: 'c, 'b: 'a, 'c> {
            generalizer: &'c mut TypeGeneralizer<'a, 'b>,
        }
        impl<'a, 'b, 'c, 'd> MutVisitor<'d> for ReplaceVisitor<'a, 'b, 'c> {
            type Ident = Symbol;
            fn visit_expr(&mut self, e: &'d mut SpannedExpr<Self::Ident>) {
                self.generalizer.tc.type_variables.enter_scope();
                self.generalizer.span = e.span;
                ast::walk_mut_expr(self, e);
                self.generalizer.tc.type_variables.exit_scope();
            }
            fn visit_spanned_typed_ident(&mut self, id: &mut SpannedIdent<Symbol>) {
                self.generalizer.span = id.span;
                self.visit_ident(&mut id.value)
            }
            fn visit_typ(&mut self, typ: &mut ArcType) {
                {
                    let type_cache = &self.generalizer.tc.type_cache;
                    self.generalizer.tc.type_variables.extend(
                        typ.forall_params()
                            .map(|param| (param.id.clone(), type_cache.hole())),
                    );
                }
                if let Some(finished) = self.generalizer.generalize_type(typ) {
                    *typ = finished;
                }
            }
        }
        {
            let mut visitor = ReplaceVisitor { generalizer: self };
            visitor.visit_expr(expr);
            for arg in &mut *args {
                visitor.visit_typ(&mut arg.value.typ)
            }
        }
        self.tc.type_variables.exit_scope();
    }
fn generalize_variables < ' i > ( & mut self , args : & mut Iterator < Item = & ' i mut SpannedIdent < Symbol > > , expr : & mut SpannedExpr < Symbol > , ) { self . tc . type_variables . enter_scope ( ) ; // Replaces all type variables with their inferred types struct ReplaceVisitor < ' a : ' c , ' b : ' a , ' c > { generalizer : & ' c mut TypeGeneralizer < ' a , ' b > , } impl < ' a , ' b , ' c , ' d > MutVisitor < ' d > for ReplaceVisitor < ' a , ' b , ' c > { type Ident = Symbol ; fn visit_expr ( & mut self , e : & ' d mut SpannedExpr < Self :: Ident > ) { self . generalizer . tc . type_variables . enter_scope ( ) ; self . generalizer . span = e . span ; ast :: walk_mut_expr ( self , e ) ; self . generalizer . tc . type_variables . exit_scope ( ) ; } fn visit_spanned_typed_ident ( & mut self , id : & mut SpannedIdent < Symbol > ) { self . generalizer . span = id . span ; self . visit_ident ( & mut id . value ) } fn visit_typ ( & mut self , typ : & mut ArcType ) { { let type_cache = & self . generalizer . tc . type_cache ; self . generalizer . tc . type_variables . extend ( typ . forall_params ( ) . map ( | param | ( param . id . clone ( ) , type_cache . hole ( ) ) ) , ) ; } if let Some ( finished ) = self . generalizer . generalize_type ( typ ) { * typ = finished ; } } } { let mut visitor = ReplaceVisitor { generalizer : self } ; visitor . visit_expr ( expr ) ; for arg in & mut * args { visitor . visit_typ ( & mut arg . value . typ ) } } self . tc . type_variables . exit_scope ( ) ; }
Generalizing updates all variables which are above `level` into "generic variables".
Generalizing updates all variables which are above ` level ` into " generic variables " .
&mut self
args
&mut Iterator<Item = &'i mut SpannedIdent<Symbol>>
expr
&mut SpannedExpr<Symbol>