Minor notes and cleanup.

Did a read-through from start to end and you know, it's not terrible.
M src/backend/rust.rs +3 -4
@@ 1,8 1,7 @@ 
 //! Compile our HIR to Rust.
 //! This is kinda silly, but hey why not.
 //!
-//!
-//! Potential improvements:
+//! Potential optimizations:
 //!  * Use something smarter than strings to collect output -- could just
 //!    output to a stream like the formatter does.  This is a little weird though 'cause
 //!    we often want to build pieces of code, and then combine them together at the end.

          
@@ 96,7 95,7 @@ fn compile_typename(t: &Type) -> Cow<'st
             //         }
             //         accm += ")";
             //         accm.into()
-            passes::generate_type_name(t).into()
+            passes::mangled_type_name(t).into()
         }
         Enum(_things) => {
             // Construct names for anonymous enums by concat'ing the member

          
@@ 109,7 108,7 @@ fn compile_typename(t: &Type) -> Cow<'st
             //     accm += &*nm.val();
             // }
             // accm.into()
-            passes::generate_type_name(t).into()
+            passes::mangled_type_name(t).into()
         }
         Generic(s) => mangle_name(&s.val()).into(),
         Array(t, len) => format!("[{};{}]", compile_typename(t), len).into(),

          
M src/bin/garnetfmt.rs +1 -0
@@ 1,4 1,5 @@ 
 //! A code formatter.
+//! Very simple and dumb.
 
 use std::io::{self, Cursor};
 use std::path::PathBuf;

          
M src/builtins.rs +0 -3
@@ 1,8 1,5 @@ 
 //! A place for us to stick compiler builtins and the metadata they need,
 //! instead of having them scattered all over.
-//!
-//! TODO: We would really benefit from having a function that can take in a single
-//! number type and output all the math/binary/logic ops for that number.
 
 use std::collections::BTreeMap;
 

          
M src/hir.rs +10 -9
@@ 288,6 288,8 @@ impl Expr {
         Self::TupleCtor { body: vec![] }
     }
 
+    /// Write the given HIR expr as a slightly-jank sexpr-y format.
+    /// It's not too pretty, but is way easier to eyeball than derive(Debug) output.
     pub fn write(&self, indent: usize, f: &mut dyn fmt::Write) -> fmt::Result {
         use Expr::*;
         for _ in 0..(indent * 2) {

          
@@ 483,23 485,20 @@ impl Expr {
 impl ExprNode {
     /// Shortcut function for making literal bools
     pub fn bool(b: bool) -> Self {
-        Self::new(Expr::Lit {
-            val: Literal::Bool(b),
-        })
+        Self::new(Expr::bool(b))
     }
 
     /// Shortcut function for making literal integers
     pub fn int(i: i128) -> Self {
-        Self::new(Expr::Lit {
-            val: Literal::Integer(i),
-        })
+        Self::new(Expr::int(i))
     }
 
     /// Shortcut function for making literal unit
     pub fn unit() -> Self {
-        Self::new(Expr::TupleCtor { body: vec![] })
+        Self::new(Expr::unit())
     }
 }
+
 /// A top-level declaration in the source file.
 /// Like ExprNode, contains a type annotation.
 #[derive(Debug, Clone, PartialEq)]

          
@@ 618,7 617,7 @@ fn lower_expr(expr: &ast::Expr) -> ExprN
         }
         E::If { cases, falseblock } => {
             // One of the actual transformations, this makes all if/else statements
-            // into essentially a switch: `if ... else if ... else if ... else if true ... end`
+            // into essentially a cond: `if ... else if ... else if ... else if true ... end`
             // This is more consistent and easier to handle for typechecking.
             assert!(!cases.is_empty(), "Should never happen");
             let mut cases: Vec<_> = cases

          
@@ 644,7 643,7 @@ fn lower_expr(expr: &ast::Expr) -> ExprN
         }
         E::While { cond, body } => {
             // While loops just get turned into a Loop containing
-            // if not cond then break end
+            // `if not cond then break end`
             let inverted_cond = E::UniOp {
                 op: UOp::Not,
                 rhs: cond.clone(),

          
@@ 742,6 741,7 @@ fn lower_expr(expr: &ast::Expr) -> ExprN
 fn lower_exprs(exprs: &[ast::Expr]) -> Vec<ExprNode> {
     exprs.iter().map(lower_expr).collect()
 }
+
 fn lower_typedef(accm: &mut Vec<Decl>, name: Sym, ty: &Type, params: &[Sym]) {
     use Decl::*;
     match ty {

          
@@ 785,6 785,7 @@ fn lower_typedef(accm: &mut Vec<Decl>, n
             };
             accm.push(new_constdef);
         }
+
         // For `type Foo = sum X {}, Y Thing end`
         // synthesize
         // const Foo = {

          
M src/lib.rs +3 -3
@@ 1,4 1,4 @@ 
-//! Garnet compiler guts.
+//! Garnet compiler driver functions and utility funcs.
 
 //#![deny(missing_docs)]
 

          
@@ 66,7 66,7 @@ impl PrimType {
 ///
 /// TODO someday: We should make a consistent and very good
 /// name-mangling scheme for types, will make some backend stuff
-/// simpler.
+/// simpler.  Also see passes::generate_type_name.
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum Type {
     /// Primitive type with no subtypes

          
@@ 609,7 609,7 @@ impl Cx {
 
 /// Main driver function.
 /// Compile a given source string to Rust source code, or return an error.
-/// TODO: Better parser errors with locations
+/// TODO: Better errors with locations
 ///
 /// Parse -> lower to IR -> run transformation passes
 /// -> typecheck -> more passes -> codegen

          
M src/passes.rs +12 -10
@@ 86,7 86,7 @@ fn id<T>(thing: T) -> T {
 ///
 /// To handle multiple expressions this will turn more into a fold()
 /// than a map(), it will take an accumulator that gets threaded through
-/// everything...  That gets *very weird* though and I manage to pour
+/// everything...  That gets *very weird* though and I managed to pour
 /// my coffee on my cat this morning so let's give that a miss for now.
 /// As it is, this can only transform subtrees into other subtrees.
 ///

          
@@ 389,7 389,9 @@ fn signature_map(sig: hir::Signature, f:
     }
 }
 
-pub fn generate_type_name(typ: &Type) -> String {
+/// Generates a mangled type name for the given type that is unique (hopefully) and
+/// printable.  See also TODO on crate::Type.
+pub fn mangled_type_name(typ: &Type) -> String {
     match typ {
         Type::Enum(fields) => {
             let fieldnames: Vec<_> = fields

          
@@ 400,17 402,17 @@ pub fn generate_type_name(typ: &Type) ->
             format!("__Enum{}", fieldstr)
         }
         Type::Func(params, rettype, typeparams) => {
-            let paramnames: Vec<String> = params.iter().map(generate_type_name).collect();
+            let paramnames: Vec<String> = params.iter().map(mangled_type_name).collect();
             let paramstr = paramnames.join("_");
-            let retname = generate_type_name(rettype);
-            let tparamnames: Vec<String> = typeparams.iter().map(generate_type_name).collect();
+            let retname = mangled_type_name(rettype);
+            let tparamnames: Vec<String> = typeparams.iter().map(mangled_type_name).collect();
             let tparamstr = tparamnames.join("_");
             format!("__Func__{}__{}_{}", paramstr, retname, tparamstr)
         }
         Type::Struct(body, _) => {
             let fieldnames: Vec<_> = body
                 .iter()
-                .map(|(nm, ty)| format!("{}_{}", nm, generate_type_name(ty)))
+                .map(|(nm, ty)| format!("{}_{}", nm, mangled_type_name(ty)))
                 .collect();
             let fieldstr = fieldnames.join("_");
             format!("__Struct__{}", fieldstr)

          
@@ 418,7 420,7 @@ pub fn generate_type_name(typ: &Type) ->
         Type::Sum(body, _) => {
             let fieldnames: Vec<_> = body
                 .iter()
-                .map(|(nm, ty)| format!("{}_{}", nm, generate_type_name(ty)))
+                .map(|(nm, ty)| format!("{}_{}", nm, mangled_type_name(ty)))
                 .collect();
             let fieldstr = fieldnames.join("_");
             format!("__Sum__{}", fieldstr)

          
@@ 427,17 429,17 @@ pub fn generate_type_name(typ: &Type) ->
             format!("__G{}", name)
         }
         Type::Named(name, fields) => {
-            let field_names: Vec<_> = fields.iter().map(generate_type_name).collect();
+            let field_names: Vec<_> = fields.iter().map(mangled_type_name).collect();
             let field_str = field_names.join("_");
             format!("__Named{}__{}", name, field_str)
         }
         Type::Prim(p) => p.get_name().into_owned(),
         Type::Never => format!("!"),
         Type::Array(t, len) => {
-            format!("__Arr{}__{}", generate_type_name(t), len)
+            format!("__Arr{}__{}", mangled_type_name(t), len)
         }
         Type::Uniq(t) => {
-            format!("__Uniq__{}", generate_type_name(t))
+            format!("__Uniq__{}", mangled_type_name(t))
         }
     }
 }

          
M src/passes/double_typeck.rs +3 -0
@@ 2,6 2,9 @@ 
 //! Doesn't actually change anything, just walks through
 //! the entire IR tree and makes sure that every expression
 //! has a real type.
+//!
+//! Technically unnecessary but occasionally useful for
+//! debugging stuff.
 
 use crate::hir::*;
 use crate::passes::*;

          
M src/typeck.rs +8 -10
@@ 130,7 130,7 @@ pub enum TypeError {
     },
     TypeListMismatch {
         // We can't necessarily display TypeId's sensibly, so I guess
-        // we haven to turn them into strings
+        // we have to turn them into strings
         expected: String,
         got: String,
     },

          
@@ 216,7 216,9 @@ impl std::fmt::Display for TypeError {
 }
 
 impl TypeError {
-    /// TODO: This should just be turned into the Display impl
+    /// TODO: This should just be turned into the Display impl.
+    /// But we might need access to the Tck sometimes?  Do we make
+    /// it so that has to happen when the error is created?  I guess so
     pub fn format(&self) -> String {
         match self {
             TypeError::UnknownVar(sym) => format!("Unknown var: {}", sym.val()),

          
@@ 358,6 360,7 @@ impl Tck {
             )
         })
     }
+
     /// Save the type variable associated with the given expr.
     /// Panics if it is redefining the expr's type.
     fn set_expr_type(&mut self, expr: &hir::ExprNode, ty: TypeId) {

          
@@ 483,15 486,10 @@ impl Tck {
     }
 
     /// Same as `get_struct_field_type()` but takes a tuple type and an integer.
-    pub fn get_tuple_field_type(
-        &mut self,
-        symtbl: &Symtbl,
-        tuple_type: TypeId,
-        n: usize,
-    ) -> TypeId {
+    pub fn get_tuple_field_type(&mut self, tuple_type: TypeId, n: usize) -> TypeId {
         use TypeInfo::*;
         match self.get(&tuple_type).clone() {
-            Ref(t) => self.get_tuple_field_type(symtbl, t, n),
+            Ref(t) => self.get_tuple_field_type(t, n),
             Named(nm, tys) if &*nm.val() == "Tuple" => tys.get(n).cloned().unwrap_or_else(|| {
                 panic!("Tuple has no field {}, valid fields are: {:#?}", n, tys)
             }),

          
@@ 1356,7 1354,7 @@ fn typecheck_expr(
         TupleRef { expr: e, elt } => {
             typecheck_expr(tck, symtbl, func_rettype, e)?;
             let tuple_type = tck.get_expr_type(e);
-            let field_type = tck.get_tuple_field_type(symtbl, tuple_type, *elt);
+            let field_type = tck.get_tuple_field_type(tuple_type, *elt);
             trace!(
                 "Heckin tuple ref...  Type of {:?}.{} is {:?}",
                 e,