*/
ProductType join(ProductType that) {
int left=types.length, right=that.types.length, n=left+right-2;
if (left<=1 && right<=1) return zero; // We try to do the best we can, in the face of precondition violation
if (n<0) throw new OutOfMemoryError(); // This means the addition overflowed!
final PrimSig a=types[left-1], b=that.types[0], c=a.intersect(b);
if (c==NONE) return new ProductType(n, c);
final PrimSig[] types = new PrimSig[n];
int j=0;
for(int i=0; i<left-1; i++, j++) { types[j]=this.types[i]; }
for(int i=1; i<right; i++, j++) { types[j]=that.types[i]; }