Quoting from the source code of Composer's "semver" version parser [1]:
// X Range // // Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple. // A partial version range is treated as an X-Range, so the special character is in fact optional. [1] https://github.com/composer/semver/blob/f8c5a07/src/VersionParser.php#L408,L411