More Cartesian housekeeping, plus implementation of copy!

- Cleans up `@ngenerate` to add return-type annotation
- Adds `@nsplat` to generate specialized versions of functions that avoid splatting
- Adds quite a few new tests of type inference
- Implements cartesian `copy!` for faster performance on SubArrays

The addition of `@nsplat` is not strictly necessary; I could ditch that and write them out by hand, if desired. The main motivation for adding it was to automatically synchronize the use of splatting with changes in CARTESIAN_DIMS.

Performance gain on `copy!` is the usual:
Master:
```
julia> A = rand(1000,1000,50);

julia> B = zeros(1000,1000,50);

julia> S = sub(B, :, :, :);

julia> @time copy!(S, A);
elapsed time: 2.144633973 seconds (48 bytes allocated)
```
This branch:
```
julia> @time copy!(S, A);
elapsed time: 0.399700238 seconds (48 bytes allocated)
```

CC @carlobaldassi.