method class_type =
                  fun f ct ->
                    let () = o#node f ct Ast.loc_of_class_type
                    in
                      match ct with
                      | Ast.CtCon (_, Ast.ViNil, i, (Ast.TyNil _)) ->
                          pp f "@[<2>%a@]" o#ident i
                      | Ast.CtCon (_, Ast.ViNil, i, t) ->
                          pp f "@[<2>[@,%a@]@,]@ %a" o#class_params t 
                            o#ident i
                      | Ast.CtCon (_, Ast.ViVirtual, (Ast.IdLid (_, i)),
                          (Ast.TyNil _)) -> pp f "@[<2>virtual@ %a@]" o#var i
                      | Ast.CtCon (_, Ast.ViVirtual, (Ast.IdLid (_, i)), t)
                          ->
                          pp f "@[<2>virtual@ [@,%a@]@,]@ %a" o#class_params
                            t o#var i
                      | Ast.CtFun (_, t, ct) ->
                          pp f "@[<2>%a@ ->@ %a@]" o#simple_ctyp t
                            o#class_type ct
                      | Ast.CtSig (_, (Ast.TyNil _), csg) ->
                          pp f "@[<hv0>@[<hv2>object@ %a@]@ end@]"
                            o#class_sig_item csg
                      | Ast.CtSig (_, t, csg) ->
                          pp f
                            "@[<hv0>@[<hv2>object @[<1>(%a)@]@ %a@]@ end@]"
                            o#ctyp t o#class_sig_item csg
                      | Ast.CtAnt (_, s) -> o#anti f s
                      | Ast.CtAnd (_, ct1, ct2) ->
                          (o#class_type f ct1;
                           pp f o#andsep;
                           o#class_type f ct2)
                      | Ast.CtCol (_, ct1, ct2) ->
                          pp f "%a :@ %a" o#class_type ct1 o#class_type ct2
                      | Ast.CtEq (_, ct1, ct2) ->
                          pp f "%a =@ %a" o#class_type ct1 o#class_type ct2
                      | _ -> assert false