This is what i get with VS13:
uint8_t var = 0xFF; 00346602 mov byte ptr [ebp-51h],0FFh uint16_t var2 = var << 8; 00346606 movzx eax,byte ptr [ebp-51h] 0034660A shl eax,8 0034660D mov word ptr [ebp-60h],ax
When you load the value from var into the register, it doesn't care how large the variable was, the value from it now resides in a 32/64 bit register. When it does the shift, it's doing it in a 32/64 bit context. Storing it into var2 just means it's going to take the bottom 16bits, truncating if necessary.