Okay I have managed to find a typechecker bug.

```
type Foo = {I32, @A}

fn thing(i: I32, x: @A): Foo =
    $Foo {i, x}
end

fn main(): I32 =
    let f2: Foo = thing(4, true)
    3
end
```

This typechecks and probably shouldn't, but if I change the signature to
`fn thing(i: I32, x: @B): Foo` then it doesn't.
M fml/src/ast.rs +1 -0
@@ 121,6 121,7 @@ pub enum Decl {
     },
     TypeDef {
         name: String,
+        params: Vec<String>,
         ty: Type,
     },
 }

          
M fml/src/parser.rs +7 -3
@@ 375,9 375,11 @@ impl<'input> Parser<'input> {
     /// typedef = "type" ident "=" type
     fn parse_typedef(&mut self) -> ast::Decl {
         let name = self.expect_ident();
+        let params = vec![];
+
         self.expect(T::Equals);
         let ty = self.parse_type();
-        ast::Decl::TypeDef { name, ty }
+        ast::Decl::TypeDef { name, params, ty }
     }
 
     fn parse_fn(&mut self) -> ast::Decl {

          
@@ 517,9 519,11 @@ impl<'input> Parser<'input> {
             T::Dollar => {
                 self.drop();
                 let name = self.expect_ident();
-                self.expect(T::LParen);
+                // BUGGO TODO: This is potentially ambiguous 'cause we could have
+                // $Foo(Type) expr
+                // or we could have
+                // $Foo (expr)
                 let body = self.parse_expr(0)?;
-                self.expect(T::RParen);
                 ast::ExprNode::new(ast::Expr::TypeCtor { name, body })
             }
 

          
M fml/src/typeck.rs +5 -1
@@ 529,7 529,11 @@ pub fn typecheck(ast: &ast::Ast) {
                     panic!("Error while typechecking function {}:\n{:?}", name, e)
                 });
             }
-            TypeDef { name, ty } => symtbl.add_type(name, ty),
+            TypeDef {
+                name,
+                params: _,
+                ty,
+            } => symtbl.add_type(name, ty),
         }
     }
     // Print out toplevel symbols

          
M fml/tests/main.rs +12 -0
@@ 95,6 95,12 @@ fn test_typedef2() {
 }
 
 #[test]
+fn test_typedef3() {
+    let src = include_str!("test_typedef3.gt");
+    let _output = fml::compile("test_typedef3.gt", src);
+}
+
+#[test]
 fn test_struct1() {
     let src = include_str!("test_struct1.gt");
     let _output = fml::compile("test_struct1.gt", src);

          
@@ 112,3 118,9 @@ fn test_struct3() {
     let src = include_str!("test_struct3.gt");
     let _output = fml::compile("test_struct3.gt", src);
 }
+
+#[test]
+fn test_struct4() {
+    let src = include_str!("test_struct4.gt");
+    let _output = fml::compile("test_struct4.gt", src);
+}

          
M fml/tests/test_struct1.gt +2 -2
@@ 10,10 10,10 @@ end
 
 
 fn main(): I32 =
-    let f1: Foo = id($Foo(struct {
+    let f1: Foo = id($Foo struct {
         a = 3,
         b = false
-    }))
+    })
     let f2: struct a: I32, b: Bool end = id(struct { a = 3, b = false })
     3
 end

          
M fml/tests/test_struct2.gt +4 -4
@@ 5,18 5,18 @@ type Foo = struct
 end
 
 fn thing(i: I32): Foo =
-    $Foo(struct {
+    $Foo struct {
         a = i,
         b = false,
-    })
+    }
 end
 
 
 fn main(): I32 =
-    let f1: Foo = $Foo(struct {
+    let f1: Foo = $Foo struct {
         a = 3,
         b = false
-    })
+    }
     let f2: Foo = thing(4)
     3
 end

          
M fml/tests/test_struct3.gt +4 -4
@@ 5,17 5,17 @@ type Foo = struct
 end
 
 fn thing(i: I32): Foo =
-    $Foo(struct {
+    $Foo struct {
         a = i,
         b = false,
-    })
+    }
 end
 
 
 fn main(): I32 =
-    let f1: Foo = $Foo(struct {
+    let f1: Foo = $Foo struct {
         a = 3,
-    })
+    }
     let f2: Foo = thing(4)
     3
 end

          
M fml/tests/test_struct4.gt +1 -1
@@ 13,7 13,7 @@ fn main(): I32 =
     let f1: Foo(I32) = id($Foo(I32) struct {
         a = 3,
         b = false
-    }))
+    })
     --let f2: struct a: I32, b: Bool end = id(struct { a = 3, b = false })
     3
 end

          
M fml/tests/test_typedef1.gt +1 -1
@@ 7,7 7,7 @@ end
 
 
 fn main(): I32 =
-    let f1: Foo = $Foo(3)
+    let f1: Foo = $Foo 3
     let f2: Foo = thing(4)
     3
 end

          
M fml/tests/test_typedef2.gt +1 -1
@@ 7,7 7,7 @@ end
 
 
 fn main(): I32 =
-    let f1: Foo = $Foo({3, true})
+    let f1: Foo = $Foo {3, true}
     let f2: Foo = thing(4)
     3
 end

          
A => fml/tests/test_typedef3.gt +13 -0
@@ 0,0 1,13 @@ 
+
+type Foo = {I32, @A}
+
+fn thing(i: I32, x: @A): Foo =
+    $Foo {i, x}
+end
+
+
+fn main(): I32 =
+    --let f1: Foo = $Foo {3, true}
+    let f2: Foo = thing(4, true)
+    3
+end