"-swift-version 3" means Swift 3.1, not 3.0. (#7883)

Put in a general mechanism for mapping user-specified "compatibility
versions" to proper "effective versions" (what #if and @available
checking should respect). This may still be different from the
intrinsic "language version"; right now master is considered a "3.1"
compiler with a "Swift 4 mode", and we plan to ship a "4.0" compiler
with a "Swift 3 mode" that will have a version number of something
like "3.2".

rdar://problem/29884401 / SR-3791
This commit is contained in:
Jordan Rose
2017-03-03 13:28:01 -08:00
committed by GitHub
parent bc6ea5b00f
commit 3456d04925
7 changed files with 130 additions and 42 deletions

View File

@@ -242,16 +242,11 @@ Version Version::getCurrentCompilerVersion() {
}
Version Version::getCurrentLanguageVersion() {
#ifndef SWIFT_VERSION_STRING
#error Swift language version is not set!
#if SWIFT_VERSION_PATCHLEVEL
return {SWIFT_VERSION_MAJOR, SWIFT_VERSION_MINOR, SWIFT_VERSION_PATCHLEVEL};
#else
return {SWIFT_VERSION_MAJOR, SWIFT_VERSION_MINOR};
#endif
auto currentVersion = Version::parseVersionString(
SWIFT_VERSION_STRING, SourceLoc(), nullptr);
assert(currentVersion.hasValue() &&
"Embedded Swift language version couldn't be parsed: '"
SWIFT_VERSION_STRING
"'");
return currentVersion.getValue();
}
raw_ostream &operator<<(raw_ostream &os, const Version &version) {
@@ -304,18 +299,35 @@ Version::operator clang::VersionTuple() const
}
}
bool Version::isValidEffectiveLanguageVersion() const {
for (auto verStr : getValidEffectiveVersions()) {
auto v = parseVersionString(verStr, SourceLoc(), nullptr);
assert(v.hasValue());
// In this case, use logical-equality _and_ precision-equality. We do not
// want to permit users requesting effective language versions more precise
// than our whitelist (eg. we permit 3 but not 3.0 or 3.0.0), since
// accepting such an argument promises more than we're able to deliver.
if (v == *this && v.getValue().size() == size())
return true;
Optional<Version> Version::getEffectiveLanguageVersion() const {
switch (size()) {
case 0:
return None;
case 1:
break;
default:
// We do not want to permit users requesting more precise effective language
// versions since accepting such an argument promises more than we're able
// to deliver.
return None;
}
// FIXME: When we switch to Swift 4 by default, the "3" case should return
// a version newer than any released 3.x compiler (probably "3.2"), and the
// "4" case should start returning getCurrentLanguageVersion. We should
// also check for the presence of SWIFT_VERSION_PATCHLEVEL, and if that's
// set apply it to the "3" case, so that Swift 4.0.1 will automatically
// have a compatibility mode of 3.2.1.
switch (Components[0]) {
case 3:
static_assert(SWIFT_VERSION_MAJOR == 3,
"getCurrentLanguageVersion is no longer correct here");
return Version::getCurrentLanguageVersion();
case 4:
return Version{4, 0};
default:
return None;
}
return false;
}
Version Version::asMajorVersion() const {