为什么这个模板可以在单个文件中使用,但不能跨文件使用?

Why does this template work in a single file but not across files?

考虑 array.sats:

#include "share/atspre_staload.hats"
fun {a:t@ype} make: (int, a) -> void

array.dats:

#include "share/atspre_staload.hats"
staload "./array.sats"

implement {a} make(n: int, x: a) = ()

和example.dats:

staload Array = "./array.sats"
implement main0() = () where {
        val arr = $Array.make<int>(10, 42)
}

这些编译失败,出现一堆模板错误:

$ make clean all
rm -fv *_[sd]ats.[co] example
removed 'array_dats.c'
removed 'array_dats.o'
removed 'array_sats.c'
removed 'array_sats.o'
removed 'example_dats.c'
patscc -DATS_MEMALLOC_GCBDW -c array.sats
clang: warning: argument unused during compilation: '-L/usr/local/lib/ats2-postiats-0.3.9/ccomp/atslib/lib' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-L/usr/local/lib/ats2-postiats-0.3.9/ccomp/atslib/lib64' [-Wunused-command-line-argument]
patscc -DATS_MEMALLOC_GCBDW -c array.dats
clang: warning: argument unused during compilation: '-L/usr/local/lib/ats2-postiats-0.3.9/ccomp/atslib/lib' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-L/usr/local/lib/ats2-postiats-0.3.9/ccomp/atslib/lib64' [-Wunused-command-line-argument]
patscc -DATS_MEMALLOC_GCBDW -o example example.dats -lgc
example_dats.c:169:23: error: use of undeclared identifier 'PMVtmpltcstmat'
ATSINSmove_void(tmp1, PMVtmpltcstmat[0](make<S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int))>)(ATSPMVi0nt(10), ATSPMVi0nt(42))) ;
                      ^
example_dats.c:169:46: warning: implicit declaration of function 'S2Eapp' is invalid in C99 [-Wimplicit-function-declaration]
ATSINSmove_void(tmp1, PMVtmpltcstmat[0](make<S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int))>)(ATSPMVi0nt(10), ATSPMVi0nt(42))) ;
                                             ^
example_dats.c:169:53: warning: implicit declaration of function 'S2Ecst' is invalid in C99 [-Wimplicit-function-declaration]
ATSINSmove_void(tmp1, PMVtmpltcstmat[0](make<S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int))>)(ATSPMVi0nt(10), ATSPMVi0nt(42))) ;
                                                    ^
example_dats.c:169:60: error: use of undeclared identifier 'g0int_t0ype'
ATSINSmove_void(tmp1, PMVtmpltcstmat[0](make<S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int))>)(ATSPMVi0nt(10), ATSPMVi0nt(42))) ;
                                                           ^
example_dats.c:169:41: error: use of undeclared identifier 'make'
ATSINSmove_void(tmp1, PMVtmpltcstmat[0](make<S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int))>)(ATSPMVi0nt(10), ATSPMVi0nt(42))) ;
                                        ^
example_dats.c:169:99: error: expected expression
ATSINSmove_void(tmp1, PMVtmpltcstmat[0](make<S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int))>)(ATSPMVi0nt(10), ATSPMVi0nt(42))) ;
                                                                                                  ^
2 warnings and 4 errors generated.
make: *** [example] Error 1

同时在单个文件中编译和运行相同的内容没有错误:

#include "share/atspre_staload.hats"
extern fun {a:t@ype} make: (int, a) -> void

#include "share/atspre_staload.hats"
implement {a} make(n: int, x: a) = ()

implement main0() = () where {
        val arr = make<int>(10, 42)
}

分开的代码有什么问题? $UNSAFE 文件中非常相似的代码似乎适用于模板和命名空间。

你还需要staload array.dats:

staload Array = "./array.sats"
staload _(*Array*) = "./array.dats"
implement main0() = () where {
        val arr = $Array.make<int>(10, 42)
}