///|
/// Helper function to determine if a type represents a simple anonymous parameter
/// that should be printed without "_ :" prefix
fn is_simple_anonymous_type(ty : @syntax.Type) -> Bool {
match ty {
// Simple built-in types are likely anonymous parameters
Name(constr_id~, ..) =>
match constr_id.id {
Ident(name~) =>
// Common simple types that are typically anonymous
name == "String" ||
name == "Int" ||
name == "Bool" ||
name == "Double" ||
name == "Float" ||
name == "Char" ||
name == "Unit" ||
name == "Bytes"
_ => false
}
// Complex types (Self, generic types, etc.) should use explicit "_ :"
_ => false
}
}
///|
/// Function and Type Declaration printing
fn print_parameter(param : @syntax.Parameter, logger : StringBuilder) -> Unit {
match param {
DiscardPositional(ty~, ..) =>
// For discarded positional parameters
// Heuristic: Simple type names (like String, Int) in anonymous contexts should omit "_ :"
// Complex types (like Self) or when no type provided should include "_ :"
match ty {
Some(t) =>
// Check if this looks like a simple anonymous parameter
if is_simple_anonymous_type(t) {
// Print just the type for anonymous parameters
print_type(t, logger)
} else {
// Print "_ : Type" for explicit discard parameters
logger.write_string("_")
logger.write_string(" : ")
print_type(t, logger)
}
None => logger.write_string("_")
}
Positional(binder~, ty~) => {
print_binder(binder, logger)
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
Labelled(binder~, ty~) => {
print_binder(binder, logger)
logger.write_string("~")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
Optional(binder~, default~, ty~) => {
print_binder(binder, logger)
logger.write_string("?")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
logger.write_string(" = ")
print_expr(default, logger)
}
QuestionOptional(binder~, ty~) => {
print_binder(binder, logger)
logger.write_string("?")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
}
}
///|
/// Function and Type Declaration printing
fn print_impl_parameter(
param : @syntax.Parameter,
logger : StringBuilder,
) -> Unit {
match param {
DiscardPositional(ty~, ..) =>
// For discarded positional parameters, always show "_" or "_ : Type"
match ty {
Some(t) => {
logger.write_string("_")
logger.write_string(" : ")
print_type(t, logger)
}
None => logger.write_string("_")
}
Positional(binder~, ty~) =>
// If binder is "_", always show "_" or "_ : Ty", don't just show the type
if binder.name == "_" {
logger.write_string("_")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
} else {
print_binder(binder, logger)
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
Labelled(binder~, ty~) => {
print_binder(binder, logger)
logger.write_string("~")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
Optional(binder~, default~, ty~) => {
print_binder(binder, logger)
logger.write_string("?")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
logger.write_string(" = ")
print_expr(default, logger)
}
QuestionOptional(binder~, ty~) => {
print_binder(binder, logger)
logger.write_string("?")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
}
}
///|
/// Function and Type Declaration printing
fn print_trait_method_parameter(
param : @syntax.Parameter,
logger : StringBuilder,
) -> Unit {
match param {
DiscardPositional(ty~, ..) =>
// For discarded positional parameters, always print just the type
match ty {
Some(t) => print_type(t, logger)
None => logger.write_string("_")
}
Positional(binder~, ty~) =>
// If binder is "_", just print the typename without "_ : Ty"
if binder.name == "_" {
match ty {
Some(t) => print_type(t, logger)
None => logger.write_string("_")
}
} else {
print_binder(binder, logger)
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
Labelled(binder~, ty~) => {
print_binder(binder, logger)
logger.write_string("~")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
Optional(binder~, default~, ty~) => {
print_binder(binder, logger)
logger.write_string("?")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
logger.write_string(" = ")
print_expr(default, logger)
}
QuestionOptional(binder~, ty~) => {
print_binder(binder, logger)
logger.write_string("?")
match ty {
Some(t) => {
logger.write_string(" : ")
print_type(t, logger)
}
None => ()
}
}
}
}
///|
fn print_fun_decl(fun_decl : @syntax.FunDecl, logger : StringBuilder) -> Unit {
print_visibility(fun_decl.vis, logger)
logger.write_string("fn")
// fn[A] id(x : A) -> A { ... }
// ^^
// quantifiers
if not(fun_decl.quantifiers.is_empty()) {
logger.write_string("[")
print_list(fun_decl.quantifiers, print_type_var_binder, ", ", logger)
logger.write_string("]")
}
match fun_decl.type_name {
Some(type_name) => {
logger.write_string(" ")
print_type_name(type_name, logger)
logger.write_string("::")
}
None => logger.write_string(" ")
}
print_binder(fun_decl.name, logger)
logger.write_string("(")
match fun_decl.decl_params {
Some(params) => print_list(params, print_parameter, ", ", logger)
None => ()
}
logger.write_string(")")
match fun_decl.return_type {
Some(ret_ty) => {
logger.write_string(" -> ")
print_type(ret_ty, logger)
}
None => ()
}
print_error_type(fun_decl.error_type, logger)
}
///|
fn print_decl_body(body : @syntax.DeclBody, logger : StringBuilder) -> Unit {
match body {
DeclBody(expr~, ..) => {
logger.write_string("{ ")
print_expr(expr, logger)
logger.write_string(" }")
}
DeclStubs(stubs) =>
match stubs {
Import(module_name~, func_name~) => {
logger.write_string(" = \"")
logger.write_string(module_name)
logger.write_string("\" \"")
logger.write_string(func_name)
logger.write_string("\"")
}
Embedded(..) => logger.write_string(" = { /* embedded code */ }")
}
}
}
///|
fn print_type_decl(
type_decl : @syntax.TypeDecl,
logger : StringBuilder,
) -> Unit {
print_visibility(type_decl.type_vis, logger)
match type_decl.components {
Record(fields) => {
logger.write_string("struct ")
logger.write_string(type_decl.tycon)
logger.write_string(" { ")
for field in fields {
print_visibility(field.vis, logger)
if field.mut_ {
logger.write_string("mut ")
}
logger.write_string(field.name.label)
logger.write_string(" : ")
print_type(field.ty, logger)
logger.write_string("; ")
}
logger.write_string("}")
}
Variant(constructors) => {
logger.write_string("enum ")
logger.write_string(type_decl.tycon)
logger.write_string(" { ")
for constr in constructors {
logger.write_string(constr.name.name)
match constr.args {
Some(args) => {
logger.write_string("(")
let mut first = true
for arg in args.iter() {
if not(first) {
logger.write_string(", ")
}
first = false
print_type(arg.ty, logger)
}
logger.write_string(")")
}
None => ()
}
logger.write_string("; ")
}
logger.write_string("}")
}
Abstract => {
// FIXME
logger.write_string("type ")
logger.write_string(type_decl.tycon)
}
Extern => {
// FIXME
logger.write_string("extern type")
logger.write_string(type_decl.tycon)
}
Newtype(ty) => {
// FIXME: need add type param
logger.write_string("type ")
logger.write_string(type_decl.tycon)
logger.write_string(" ")
print_type(ty, logger)
}
Error(exception_decl) => {
logger.write_string("suberror ")
logger.write_string(type_decl.tycon)
match exception_decl {
NoPayload => ()
SinglePayload(ty) => {
logger.write_string("(")
print_type(ty, logger)
logger.write_string(")")
}
EnumPayload(constructors) => {
logger.write_string(" { ")
for constr in constructors {
logger.write_string(constr.name.name)
match constr.args {
Some(args) => {
logger.write_string("(")
let mut first = true
for arg in args.iter() {
if not(first) {
logger.write_string(", ")
}
first = false
print_type(arg.ty, logger)
}
logger.write_string(")")
}
None => ()
}
logger.write_string("; ")
}
logger.write_string("}")
}
}
}
TupleStruct(types) => {
logger.write_string("struct ")
logger.write_string(type_decl.tycon)
logger.write_string("(")
let mut first = true
for ty in types {
if not(first) {
logger.write_string(", ")
}
first = false
print_type(ty, logger)
}
logger.write_string(")")
}
Alias(ty) => {
logger.write_string("typealias ")
print_type(ty, logger)
logger.write_string(" as ")
logger.write_string(type_decl.tycon)
}
}
}