diff --git a/src/main/wacc/Main.scala b/src/main/wacc/Main.scala
index dcc7e6d..a271c3c 100644
--- a/src/main/wacc/Main.scala
+++ b/src/main/wacc/Main.scala
@@ -34,7 +34,7 @@ def compile(contents: String): Int = {
   parser.parse(contents) match {
     case Success(ast) =>
       given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
-      val names = renamer.rename(ast)
+      renamer.rename(ast)
       // given ctx: types.TypeCheckerCtx[List[Error]] =
       //   types.TypeCheckerCtx(names, errors)
       // types.check(ast)
diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala
index 2457c8f..123adb5 100644
--- a/src/main/wacc/ast.scala
+++ b/src/main/wacc/ast.scala
@@ -27,10 +27,10 @@ object ast {
   case class StrLiter(v: String)(pos: Position) extends Expr6
   object StrLiter extends ParserBridgePos1[String, StrLiter]
   case class PairLiter()(pos: Position) extends Expr6
-  object PairLiter extends Expr6 with ParserBridgePos0[PairLiter]
-  case class Ident(v: String, var uid: Int = -1) extends Expr6 with LValue
+  object PairLiter extends ParserBridgePos0[PairLiter]
+  case class Ident(v: String, var uid: Int = -1)(pos: Position) extends Expr6 with LValue
   object Ident extends ParserBridgePos1[String, Ident] {
-    def apply(x1: String): Ident = new Ident(x1)
+    def apply(v: String)(pos: Position): Ident = new Ident(v)(pos)
   }
   case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position)
       extends Expr6
@@ -46,18 +46,15 @@ object ast {
   sealed trait UnaryOp extends Expr {
     val x: Expr
   }
-  sealed trait UnaryOp extends Expr {
-    val x: Expr
-  }
-  case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
+  case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
   object Negate extends ParserBridgePos1[Expr6, Negate]
-  case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
+  case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
   object Not extends ParserBridgePos1[Expr6, Not]
-  case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
+  case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
   object Len extends ParserBridgePos1[Expr6, Len]
-  case class Ord(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
+  case class Ord(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
   object Ord extends ParserBridgePos1[Expr6, Ord]
-  case class Chr(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
+  case class Chr(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
   object Chr extends ParserBridgePos1[Expr6, Chr]
 
   // Binary operators
diff --git a/src/main/wacc/renamer.scala b/src/main/wacc/renamer.scala
index e46d9dd..77e0bd6 100644
--- a/src/main/wacc/renamer.scala
+++ b/src/main/wacc/renamer.scala
@@ -41,30 +41,34 @@ object renamer {
   ): Map[Ident, SemType] =
     given globalNames: mutable.Map[Ident, SemType] = mutable.Map.empty
     given globalNumbering: mutable.Map[String, Int] = mutable.Map.empty
-    rename(Scope(mutable.Map.empty, Map.empty))(prog)
+    val scope = Scope(mutable.Map.empty, Map.empty)
+    val Program(funcs, main) = prog
+    funcs
+      .map { case FuncDecl(retType, name, params, body) =>
+        val paramTypes = params.map { param =>
+          val paramType = SemType(param.paramType)
+          paramType
+        }
+        scope.add(KnownType.Func(SemType(retType), paramTypes), name, IdentType.Func)
+        (params zip paramTypes, body)
+      }
+      .foreach { case (params, body) =>
+        val functionScope = scope.subscope
+        params.foreach { case (param, paramType) =>
+          functionScope.add(paramType, param.name, IdentType.Var)
+        }
+        body.toList.foreach(rename(functionScope.subscope)) // body can shadow function params
+      }
+    main.toList.foreach(rename(scope))
     globalNames.toMap
 
   private def rename(scope: Scope)(
-      node: Program | FuncDecl | Ident | Stmt | LValue | RValue
+      node: Ident | Stmt | LValue | RValue
   )(using
       globalNames: mutable.Map[Ident, SemType],
       globalNumbering: mutable.Map[String, Int],
       errors: mutable.Builder[Error, List[Error]]
   ): Unit = node match {
-    case Program(funcs, main) => {
-      funcs.foreach(rename(scope))
-      main.toList.foreach(rename(scope))
-    }
-    case FuncDecl(retType, name, params, body) => {
-      val functionScope = scope.subscope
-      val paramTypes = params.map { param =>
-        val paramType = SemType(param.paramType)
-        functionScope.add(paramType, param.name, IdentType.Var)
-        paramType
-      }
-      scope.add(KnownType.Func(SemType(retType), paramTypes), name, IdentType.Func)
-      body.toList.foreach(rename(functionScope))
-    }
     case VarDecl(synType, name, value) => {
       // Order matters here. Variable isn't declared until after the value is evaluated.
       rename(scope)(value)
@@ -112,7 +116,7 @@ object renamer {
     }
     // Default to variables. Only `call` uses IdentType.Func.
     case id: Ident => renameIdent(scope, id, IdentType.Var)
-    case IntLiter(_) | BoolLiter(_) | CharLiter(_) | StrLiter(_) | PairLiter | Skip => ()
+    case IntLiter(_) | BoolLiter(_) | CharLiter(_) | StrLiter(_) | PairLiter() | Skip() => ()
   }
 
   private def renameIdent(scope: Scope, ident: Ident, identType: IdentType)(using
diff --git a/src/main/wacc/types.scala b/src/main/wacc/types.scala
index 388416f..e62f0db 100644
--- a/src/main/wacc/types.scala
+++ b/src/main/wacc/types.scala
@@ -17,14 +17,14 @@ object types {
 
   object SemType {
     def apply(synType: Type | PairElemType): KnownType = synType match {
-      case IntType    => KnownType.Int
-      case BoolType   => KnownType.Bool
-      case CharType   => KnownType.Char
-      case StringType => KnownType.String
+      case IntType()    => KnownType.Int
+      case BoolType()   => KnownType.Bool
+      case CharType()   => KnownType.Char
+      case StringType() => KnownType.String
       case ArrayType(elemType, dimension) =>
         (0 until dimension).foldLeft(SemType(elemType))((acc, _) => KnownType.Array(acc))
       case PairType(fst, snd) => KnownType.Pair(SemType(fst), SemType(snd))
-      case UntypedPairType    => KnownType.Pair(?, ?)
+      case UntypedPairType()  => KnownType.Pair(?, ?)
     }
   }
 }