This works.
import macros
import typetraits
macro t1() : untyped =
  return nnkStmtList.newTree(
    nnkDiscardStmt.newTree(
    newEmptyNode()
  )
  )
t1()
 But if I add:
macro t2(): untyped =
  result = t1()
#t2()
It breaks with the error message: Error: expression 'discard' has no type (or is ambiguous). Why can't I pass the result of one macro to another? I have a feeling I'm missing something fundamental here about how macros work. Even stranger if I comment out t1 and add discard.
macro t1() : untyped =
  discard
  #return nnkStmtList.newTree(
  #  nnkDiscardStmt.newTree(
  # newEmptyNode()
 # )
  #)
It gives the error not unused.
This works:
macro t2(): untyped =
  result = getAst(t1())
#t2()
 A macro produces an abstract syntax tree (AST) of nodes, that's what is assigned to its result variable. A macro call like t1() is replaced with the code representation of this AST, not with the AST itself. If you need the AST, and you do in result = t1() because t2 is supposed to return an AST, wrap it with getAST. Alternatively, t1 could become a proc.
Even stranger if I comment out t1 and add discard...
The compiler just warns about t2 not being used because the call to it is commented out, not sure what you mean.