BEHOLD MY POWER MUAHAHAAHAHHAHAHAHAAAAAA
5 files changed, 44 insertions(+), 6 deletions(-)

M fml/src/ast.rs
M fml/src/parser.rs
M fml/src/typeck.rs
M fml/tests/main.rs
A => fml/tests/test_let1.gt
M fml/src/ast.rs +1 -1
@@ 78,7 78,7 @@ pub enum Expr {
     },
     Let {
         varname: String,
-        typename: Type,
+        typename: Option<Type>,
         init: ExprNode,
     },
     Lambda {

          
M fml/src/parser.rs +5 -2
@@ 626,8 626,11 @@ impl<'input> Parser<'input> {
     fn parse_let(&mut self) -> ast::ExprNode {
         self.expect(T::Let);
         let varname = self.expect_ident();
-        self.expect(T::Colon);
-        let typename = self.parse_type();
+        let typename = if self.peek_expect(T::Colon.discr()) {
+            Some(self.parse_type())
+        } else {
+            None
+        };
         self.expect(T::Equals);
         let init = self
             .parse_expr(0)

          
M fml/src/typeck.rs +7 -3
@@ 214,6 214,8 @@ impl Tck {
                     // rather than "unknown name".  Guess it works for now though.
                     //
                     // TODO: The scoping here is still bananas, figure it out
+                    // I think we need to get the generic names from the function call
+                    // and figure 'em out, rather than just casually adding 'em in here
                     let tid = self.insert(TypeInfo::Unknown);
                     named_types.insert(s.clone(), tid);
                     TypeInfo::Ref(tid)

          
@@ 405,7 407,11 @@ fn typecheck_expr(
         } => {
             typecheck_expr(tck, symtbl, init)?;
             let init_expr_type = tck.get_expr_type(init);
-            let var_type = tck.insert_known(typename);
+            let var_type = if let Some(t) = typename {
+                tck.insert_known(t)
+            } else {
+                tck.insert(TypeInfo::Unknown)
+            };
             tck.unify(symtbl, init_expr_type, var_type)?;
 
             // TODO: Make this expr return unit instead of the

          
@@ 521,8 527,6 @@ fn typecheck_expr(
             tck.unify(symtbl, tid, body_type)?;
             println!("Done unifying type ctor");
             // The type the expression returns
-            // TODO: Generic params for type constructors
-            //let constructed_type = tck.insert_known(&Type::Named(name.clone(), vec![]));
             let constructed_type =
                 tck.insert_known(&Type::Named(name.clone(), type_params.clone()));
             tck.set_expr_type(expr, constructed_type);

          
M fml/tests/main.rs +6 -0
@@ 138,3 138,9 @@ fn test_struct5() {
     let src = include_str!("test_struct5.gt");
     let _output = fml::compile("test_struct5.gt", src);
 }
+
+#[test]
+fn test_let1() {
+    let src = include_str!("test_let1.gt");
+    let _output = fml::compile("test_let1.gt", src);
+}

          
A => fml/tests/test_let1.gt +25 -0
@@ 0,0 1,25 @@ 
+
+type Foo(@Thing) = struct
+    a: @Thing,
+    b: Bool
+end
+
+fn id(x: @T): @T =
+    x
+end
+
+
+fn main(): I32 =
+    let f1 = id($Foo(I32) {
+        .a = 3,
+        .b = false
+    })
+
+    let f2 = id($Foo(Bool) {
+        .a = true,
+        .b = false
+    })
+
+    let f3 = f1
+    3
+end