RankedTensorOf and TensorRankOf (in Tablegen files) now generate code that uses RankedTensorType instead of TensorType. This gives us more accurate type information (e.g., when calling op.getType()).
Also use restrict tensor.expand_shape/tensor.collapse_shape/tensor.pad to ranked tensors. Only cast ops should deal with unranked tensors.
Also improves a few places in the code base (e.g., Toy tutorial) where a ranked tensor is assumed (e.g., because getRank is called) but a TensorType is currently used: cast to RankedTensorType directly, so that the assertion is triggered directly at the cast.