Hi, good question about this. The answer of why it's not implemented is that I didn't yet see an important use case for it and I thought it better to have it throw an error instead, to make sure users weren't accidentally multiplying together tensors they didn't mean to.
But the cases you mention are good uses. So I think I should define them, especially since I think internally the contractions can be done very efficiently due to the simple sparse structure.
So I'll add it to my list of priorities to get into ITensor. Please write back here or email me if a few weeks go by and I haven't added it, or if you need it for a particularly urgent reason.
Finally, if you are feeling motivated, you can try implementing this feature yourself. The diagonal sparse ITensors are implemented by the Diag storage class in itensor/itdata/diag.h. What is needed is a definition of the function doTask(Contract, Diag, Diag). It could be a bit tricky though because one might want to handle the case of two indices and the case of all diag values being the same separately. But the other methods defined there are mostly fairly straightforward to follow as examples I think.
Miles