code: func Ast(x interface{}) (formatted []byte, err error) {
  
  	ast.WalkNodes(x, func(x ast.Node) bool {
  		if b, ok := x.(ast.Body); ok {
  			if len(b) == 0 {
  				return false
  			}
  		}
  		if x.Loc() == nil {
  			x.SetLoc(defaultLocation(x))
  		}
  		return false
  	})
  
  	w := &writer{indent: "\t"}
  	switch x := x.(type) {
  	case *ast.Module:
  		w.writeModule(x)
  	case *ast.Package:
  		w.writePackage(x, nil)
  	case *ast.Import:
  		w.writeImports([]*ast.Import{x}, nil)
  	case *ast.Rule:
  		w.writeRule(x, false, nil)
  	case *ast.Head:
  		w.writeHead(x, false, nil)
  	case ast.Body:
  		w.writeBody(x, nil)
  	case *ast.Expr:
  		w.writeExpr(x, nil)
  	case *ast.With:
  		w.writeWith(x, nil)
  	case *ast.Term:
  		w.writeTerm(x, nil)
  	case ast.Value:
  		w.writeTerm(&ast.Term{Value: x, Location: &ast.Location{}}, nil)
  	case *ast.Comment:
  		w.writeComments([]*ast.Comment{x})
  	default:
  		return nil, fmt.Errorf("not an ast element: %v", x)
  	}
  
  	return squashTrailingNewlines(w.buf.Bytes()), nil
  }
docs: // Ast formats a Rego AST element. If the passed value is not a valid AST
  // element, Ast returns nil and an error. Ast relies on all AST elements having
  // non-nil Location values. If an AST element with a nil Location value is
  // encountered, a default location will be set on the AST node.