diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index bfd27d2722dbc..931d751a03459 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -28,16 +28,6 @@ function(add_dependencies_multiple_targets) endif() endfunction() -# Compute the library subdirectory to use for the given sdk and -# architecture, placing the result in 'result_var_name'. -function(compute_library_subdir result_var_name sdk arch) - if(sdk IN_LIST SWIFT_APPLE_PLATFORMS OR sdk STREQUAL "MACCATALYST") - set("${result_var_name}" "${SWIFT_SDK_${sdk}_LIB_SUBDIR}" PARENT_SCOPE) - else() - set("${result_var_name}" "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}" PARENT_SCOPE) - endif() -endfunction() - function(_compute_lto_flag option out_var) string(TOLOWER "${option}" lowercase_option) if (lowercase_option STREQUAL "full") @@ -163,9 +153,12 @@ function(_add_variant_c_compile_link_flags) endif() if(IS_DARWIN) + # We collate -F with the framework path to avoid unwanted deduplication + # of options by target_compile_options -- this way no undesired + # side effects are introduced should a new search path be added. list(APPEND result "-arch" "${CFLAGS_ARCH}" - "-F" "${SWIFT_SDK_${CFLAGS_SDK}_PATH}/../../../Developer/Library/Frameworks") + "-F${SWIFT_SDK_${CFLAGS_SDK}_PATH}/../../../Developer/Library/Frameworks") set(add_explicit_version TRUE) @@ -264,18 +257,6 @@ function(_add_variant_c_compile_flags) endif() if("${CFLAGS_SDK}" STREQUAL "WINDOWS") - # MSVC doesn't support -Xclang. We don't need to manually specify - # the dependent libraries as `cl` does so. - if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") - list(APPEND result -Xclang;--dependent-lib=oldnames) - # TODO(compnerd) handle /MT, /MTd - if("${CFLAGS_BUILD_TYPE}" STREQUAL "Debug") - list(APPEND result -Xclang;--dependent-lib=msvcrtd) - else() - list(APPEND result -Xclang;--dependent-lib=msvcrt) - endif() - endif() - # MSVC/clang-cl don't support -fno-pic or -fms-compatibility-version. if(NOT SWIFT_COMPILER_IS_MSVC_LIKE) list(APPEND result -fno-pic) @@ -363,14 +344,9 @@ function(_add_variant_c_compile_flags) swift_android_libcxx_include_paths(CFLAGS_CXX_INCLUDES) swift_android_include_for_arch("${CFLAGS_ARCH}" "${CFLAGS_ARCH}_INCLUDE") foreach(path IN LISTS CFLAGS_CXX_INCLUDES ${CFLAGS_ARCH}_INCLUDE) - list(APPEND result -isystem;${path}) + list(APPEND result "SHELL:${CMAKE_INCLUDE_SYSTEM_FLAG_C}${path}") endforeach() list(APPEND result "-D__ANDROID_API__=${SWIFT_ANDROID_API_LEVEL}") - elseif(CFLAGS_SDK STREQUAL WINDOWS) - swift_windows_include_for_arch(${CFLAGS_ARCH} ${CFLAGS_ARCH}_INCLUDE) - foreach(path ${${CFLAGS_ARCH}_INCLUDE}) - list(APPEND result "\"${CMAKE_INCLUDE_FLAG_C}${path}\"") - endforeach() endif() set("${CFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE) @@ -422,8 +398,11 @@ function(_add_variant_swift_compile_flags endif() if(IS_DARWIN) + # We collate -F with the framework path to avoid unwanted deduplication + # of options by target_compile_options -- this way no undesired + # side effects are introduced should a new search path be added. list(APPEND result - "-F" "${SWIFT_SDK_${sdk}_ARCH_${arch}_PATH}/../../../Developer/Library/Frameworks") + "-F${SWIFT_SDK_${sdk}_ARCH_${arch}_PATH}/../../../Developer/Library/Frameworks") endif() is_build_type_optimized("${build_type}" optimized) @@ -910,11 +889,9 @@ function(_add_swift_library_single target name) if("${SWIFTLIB_SINGLE_SDK}" STREQUAL "WINDOWS") if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") - swift_windows_generate_sdk_vfs_overlay(SWIFTLIB_SINGLE_VFS_OVERLAY_FLAGS) - foreach(flag ${SWIFTLIB_SINGLE_VFS_OVERLAY_FLAGS}) - list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS -Xcc;${flag}) - list(APPEND SWIFTLIB_SINGLE_C_COMPILE_FLAGS ${flag}) - endforeach() + swift_windows_get_sdk_vfs_overlay(SWIFTLIB_SINGLE_VFS_OVERLAY) + list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS + -Xcc;-Xclang;-Xcc;-ivfsoverlay;-Xcc;-Xclang;-Xcc;${SWIFTLIB_SINGLE_VFS_OVERLAY}) endif() swift_windows_include_for_arch(${SWIFTLIB_SINGLE_ARCHITECTURE} SWIFTLIB_INCLUDE) foreach(directory ${SWIFTLIB_INCLUDE}) @@ -1390,6 +1367,25 @@ function(_add_swift_library_single target name) endif() # Set compilation and link flags. + if(SWIFTLIB_SINGLE_SDK STREQUAL WINDOWS) + swift_windows_include_for_arch(${SWIFTLIB_SINGLE_ARCHITECTURE} + ${SWIFTLIB_SINGLE_ARCHITECTURE}_INCLUDE) + target_include_directories(${target} SYSTEM PRIVATE + ${${SWIFTLIB_SINGLE_ARCHITECTURE}_INCLUDE}) + + if(NOT ${CMAKE_C_COMPILER_ID} STREQUAL MSVC) + swift_windows_get_sdk_vfs_overlay(SWIFTLIB_SINGLE_VFS_OVERLAY) + target_compile_options(${target} PRIVATE + "SHELL:-Xclang -ivfsoverlay -Xclang ${SWIFTLIB_SINGLE_VFS_OVERLAY}") + + # MSVC doesn't support -Xclang. We don't need to manually specify + # the dependent libraries as `cl` does so. + target_compile_options(${target} PRIVATE + "SHELL:-Xclang --dependent-lib=oldnames" + # TODO(compnerd) handle /MT, /MTd + "SHELL:-Xclang --dependent-lib=msvcrt$<$:d>") + endif() + endif() target_include_directories(${target} SYSTEM PRIVATE ${SWIFT_${SWIFTLIB_SINGLE_SDK}_${SWIFTLIB_SINGLE_ARCHITECTURE}_ICU_UC_INCLUDE} ${SWIFT_${SWIFTLIB_SINGLE_SDK}_${SWIFTLIB_SINGLE_ARCHITECTURE}_ICU_I18N_INCLUDE}) @@ -2575,6 +2571,21 @@ function(_add_swift_executable_single name) ${SWIFTEXE_SINGLE_DEPENDS}) llvm_update_compile_flags("${name}") + if(SWIFTEXE_SINGLE_SDK STREQUAL WINDOWS) + swift_windows_include_for_arch(${SWIFTEXE_SINGLE_ARCHITECTURE} + ${SWIFTEXE_SINGLE_ARCHITECTURE}_INCLUDE) + target_include_directories(${name} SYSTEM PRIVATE + ${${SWIFTEXE_SINGLE_ARCHITECTURE}_INCLUDE}) + + if(NOT ${CMAKE_C_COMPILER_ID} STREQUAL MSVC) + # MSVC doesn't support -Xclang. We don't need to manually specify + # the dependent libraries as `cl` does so. + target_compile_options(${name} PRIVATE + "SHELL:-Xclang --dependent-lib=oldnames" + # TODO(compnerd) handle /MT, /MTd + "SHELL:-Xclang --dependent-lib=msvcrt$<$:d>") + endif() + endif() target_compile_options(${name} PRIVATE ${c_compile_flags}) target_link_directories(${name} PRIVATE diff --git a/cmake/modules/SwiftSource.cmake b/cmake/modules/SwiftSource.cmake index 818a03c1e46cc..004d26b0fa8d3 100644 --- a/cmake/modules/SwiftSource.cmake +++ b/cmake/modules/SwiftSource.cmake @@ -1,6 +1,16 @@ include(macCatalystUtils) include(SwiftUtils) +# Compute the library subdirectory to use for the given sdk and +# architecture, placing the result in 'result_var_name'. +function(compute_library_subdir result_var_name sdk arch) + if(sdk IN_LIST SWIFT_APPLE_PLATFORMS OR sdk STREQUAL "MACCATALYST") + set("${result_var_name}" "${SWIFT_SDK_${sdk}_LIB_SUBDIR}" PARENT_SCOPE) + else() + set("${result_var_name}" "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}" PARENT_SCOPE) + endif() +endfunction() + # Process the sources within the given variable, pulling out any Swift # sources to be compiled with 'swift' directly. This updates # ${sourcesvar} in place with the resulting list and ${externalvar} with the diff --git a/cmake/modules/SwiftWindowsSupport.cmake b/cmake/modules/SwiftWindowsSupport.cmake index ffb6f7da6b70c..7d97cdbadcec7 100644 --- a/cmake/modules/SwiftWindowsSupport.cmake +++ b/cmake/modules/SwiftWindowsSupport.cmake @@ -49,7 +49,7 @@ function(swift_windows_lib_for_arch arch var) set(${var} ${paths} PARENT_SCOPE) endfunction() -function(swift_windows_generate_sdk_vfs_overlay flags) +function(swift_windows_get_sdk_vfs_overlay overlay) get_filename_component(VCToolsInstallDir ${VCToolsInstallDir} ABSOLUTE) get_filename_component(UniversalCRTSdkDir ${UniversalCRTSdkDir} ABSOLUTE) set(UCRTVersion ${UCRTVersion}) @@ -58,10 +58,8 @@ function(swift_windows_generate_sdk_vfs_overlay flags) configure_file("${SWIFT_SOURCE_DIR}/utils/WindowsSDKVFSOverlay.yaml.in" "${CMAKE_CURRENT_BINARY_DIR}/windows-sdk-vfs-overlay.yaml" @ONLY) - - set(${flags} - -Xclang;-ivfsoverlay;-Xclang;"${CMAKE_CURRENT_BINARY_DIR}/windows-sdk-vfs-overlay.yaml" - PARENT_SCOPE) + set(${overlay} ${CMAKE_CURRENT_BINARY_DIR}/windows-sdk-vfs-overlay.yaml + PARENT_SCOPE) endfunction() function(swift_verify_windows_VCVAR var) diff --git a/include/swift/AST/SemanticAttrs.def b/include/swift/AST/SemanticAttrs.def index 0069674b8a030..e810eb99c94e4 100644 --- a/include/swift/AST/SemanticAttrs.def +++ b/include/swift/AST/SemanticAttrs.def @@ -34,6 +34,8 @@ SEMANTICS_ATTR(STRING_PLUS_EQUALS, "string.plusequals") SEMANTICS_ATTR(FIND_STRING_SWITCH_CASE, "findStringSwitchCase") SEMANTICS_ATTR(FIND_STRING_SWITCH_CASE_WITH_CACHE, "findStringSwitchCaseWithCache") +SEMANTICS_ATTR(BINARY_INTEGER_DESCRIPTION, "binaryInteger.description") + SEMANTICS_ATTR(SWIFT_CONCURRENT_ASYNC, "swift.concurrent.async") SEMANTICS_ATTR(SWIFT_CONCURRENT_SAFE, "swift.concurrent.safe") SEMANTICS_ATTR(SWIFT_CONCURRENT, "swift.concurrent") diff --git a/include/swift/Runtime/Mutex.h b/include/swift/Runtime/Mutex.h index 1b320e9d22a6e..a24c555ccca03 100644 --- a/include/swift/Runtime/Mutex.h +++ b/include/swift/Runtime/Mutex.h @@ -24,6 +24,8 @@ #include "swift/Runtime/MutexPThread.h" #elif defined(_WIN32) #include "swift/Runtime/MutexWin32.h" +#elif defined(__wasi__) +#include "swift/Runtime/MutexWASI.h" #else #error "Implement equivalent of MutexPThread.h/cpp for your platform." #endif diff --git a/include/swift/Runtime/MutexWASI.h b/include/swift/Runtime/MutexWASI.h new file mode 100644 index 0000000000000..153a5f87b11dd --- /dev/null +++ b/include/swift/Runtime/MutexWASI.h @@ -0,0 +1,69 @@ +//===--- MutexWASI.h - -----------------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// No-op implementation of locks for the WebAssembly System Interface. The +// implementation does not need to perform locking, because as of January 2020 +// WebAssembly does not support threads. +// See the current status at https://github.com/WebAssembly/proposals and +// https://github.com/webassembly/threads +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_RUNTIME_MUTEX_WASI_H +#define SWIFT_RUNTIME_MUTEX_WASI_H + +namespace swift { + +typedef void* ConditionHandle; +typedef void* MutexHandle; +typedef void* ReadWriteLockHandle; + +#define SWIFT_CONDITION_SUPPORTS_CONSTEXPR 1 +#define SWIFT_MUTEX_SUPPORTS_CONSTEXPR 1 +#define SWIFT_READWRITELOCK_SUPPORTS_CONSTEXPR 1 + +struct ConditionPlatformHelper { + static constexpr ConditionHandle staticInit() { + return nullptr; + }; + static void init(ConditionHandle &condition) {} + static void destroy(ConditionHandle &condition) {} + static void notifyOne(ConditionHandle &condition) {} + static void notifyAll(ConditionHandle &condition) {} + static void wait(ConditionHandle &condition, MutexHandle &mutex); +}; + +struct MutexPlatformHelper { + static constexpr MutexHandle staticInit() { return nullptr; } + static void init(MutexHandle &mutex, bool checked = false) {} + static void destroy(MutexHandle &mutex) {} + static void lock(MutexHandle &mutex) {} + static void unlock(MutexHandle &mutex) {} + static bool try_lock(MutexHandle &mutex) { return true; } + static void unsafeLock(MutexHandle &mutex) {} + static void unsafeUnlock(MutexHandle &mutex) {} +}; + +struct ReadWriteLockPlatformHelper { + static constexpr ReadWriteLockHandle staticInit() { return nullptr; } + static void init(ReadWriteLockHandle &rwlock) {} + static void destroy(ReadWriteLockHandle &rwlock) {} + static void readLock(ReadWriteLockHandle &rwlock) {} + static bool try_readLock(ReadWriteLockHandle &rwlock) { return true; } + static void readUnlock(ReadWriteLockHandle &rwlock) {} + static void writeLock(ReadWriteLockHandle &rwlock) {} + static bool try_writeLock(ReadWriteLockHandle &rwlock) { return true; } + static void writeUnlock(ReadWriteLockHandle &rwlock) {} +}; +} + +#endif diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index bf2ec20779d8d..8a1f16b00d8ef 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -1360,10 +1360,19 @@ OriginallyDefinedInAttr::isActivePlatform(const ASTContext &ctx) const { Result.Platform = Platform; Result.Version = MovedVersion; Result.ModuleName = OriginalModuleName; - if (isPlatformActive(Platform, ctx.LangOpts)) { + if (isPlatformActive(Platform, ctx.LangOpts, /*TargetVariant*/false)) { Result.IsSimulator = ctx.LangOpts.Target.isSimulatorEnvironment(); return Result; } + + // Also check if the platform is active by using target variant. This ensures + // we emit linker directives for multiple platforms when building zippered + // libraries. + if (ctx.LangOpts.TargetVariant.hasValue() && + isPlatformActive(Platform, ctx.LangOpts, /*TargetVariant*/true)) { + Result.IsSimulator = ctx.LangOpts.TargetVariant->isSimulatorEnvironment(); + return Result; + } return None; } diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp index 488a44b6ff8a4..bb58412049496 100644 --- a/lib/AST/GenericSignatureBuilder.cpp +++ b/lib/AST/GenericSignatureBuilder.cpp @@ -4361,6 +4361,8 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement( if (subjectType->is()) { subjectType = resolveDependentMemberTypes(*this, subjectType); + } else { + subjectType = ErrorType::get(subjectType); } auto invalidConstraint = Constraint( diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 2a75f47fd89a1..8cbdd8095e06d 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1847,7 +1847,7 @@ void IRGenDebugInfoImpl::setCurrentLoc(IRBuilder &Builder, auto DL = llvm::DebugLoc::get(L.Line, L.Column, Scope, InlinedAt); Builder.SetCurrentDebugLocation(DL); } - + void IRGenDebugInfoImpl::addFailureMessageToCurrentLoc(IRBuilder &Builder, StringRef failureMsg) { auto TrapLoc = Builder.getCurrentDebugLocation(); @@ -1864,7 +1864,7 @@ void IRGenDebugInfoImpl::addFailureMessageToCurrentLoc(IRBuilder &Builder, FuncName += failureMsg; llvm::DISubprogram *TrapSP = DBuilder.createFunction( - MainModule, StringRef(), FuncName, TrapLoc->getFile(), 0, DIFnTy, 0, + MainModule, FuncName, StringRef(), TrapLoc->getFile(), 0, DIFnTy, 0, llvm::DINode::FlagArtificial, llvm::DISubprogram::SPFlagDefinition, nullptr, nullptr, nullptr); diff --git a/lib/SILGen/SILGenEpilog.cpp b/lib/SILGen/SILGenEpilog.cpp index 414bfc6a27bd4..66f3302207a9a 100644 --- a/lib/SILGen/SILGenEpilog.cpp +++ b/lib/SILGen/SILGenEpilog.cpp @@ -30,8 +30,8 @@ void SILGenFunction::prepareEpilog(Type resultType, bool isThrowing, // emits unreachable if there is no source level return. NeedsReturn = (fnConv.funcTy->getNumResults() != 0); for (auto directResult : fnConv.getDirectSILResults()) { - SILType resultType = - F.mapTypeIntoContext(fnConv.getSILType(directResult)); + SILType resultType = F.getLoweredType( + F.mapTypeIntoContext(fnConv.getSILType(directResult))); epilogBB->createPhiArgument(resultType, ValueOwnershipKind::Owned); } } diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp index 8efe5fc27b65e..402c2aadf27c0 100644 --- a/lib/SILOptimizer/Utils/ConstExpr.cpp +++ b/lib/SILOptimizer/Utils/ConstExpr.cpp @@ -56,6 +56,8 @@ enum class WellKnownFunction { StringEquals, // String.percentEscapedString.getter StringEscapePercent, + // BinaryInteger.description.getter + BinaryIntegerDescription, // _assertionFailure(_: StaticString, _: StaticString, file: StaticString,...) AssertionFailure, // A function taking one argument that prints the symbolic value of the @@ -83,6 +85,8 @@ static llvm::Optional classifyFunction(SILFunction *fn) { return WellKnownFunction::StringEquals; if (fn->hasSemanticsAttr(semantics::STRING_ESCAPE_PERCENT_GET)) return WellKnownFunction::StringEscapePercent; + if (fn->hasSemanticsAttr(semantics::BINARY_INTEGER_DESCRIPTION)) + return WellKnownFunction::BinaryIntegerDescription; if (fn->hasSemanticsAttrThatStartsWith("programtermination_point")) return WellKnownFunction::AssertionFailure; // A call to a function with the following semantics annotation will be @@ -780,6 +784,13 @@ extractStaticStringValue(SymbolicValue staticString) { return staticStringProps[0].getStringValue(); } +static Optional +extractStringOrStaticStringValue(SymbolicValue stringValue) { + if (stringValue.getKind() == SymbolicValue::String) + return stringValue.getStringValue(); + return extractStaticStringValue(stringValue); +} + /// If the specified type is a Swift.Array of some element type, then return the /// element type. Otherwise, return a null Type. static Type getArrayElementType(Type ty) { @@ -789,6 +800,28 @@ static Type getArrayElementType(Type ty) { return Type(); } +/// Check if the given type \p ty is a stdlib integer type and if so return +/// whether the type is signed. Returns \c None if \p ty is not a stdlib integer +/// type, \c true if it is a signed integer type and \c false if it is an +/// unsigned integer type. +static Optional getSignIfStdlibIntegerType(Type ty) { + StructDecl *decl = ty->getStructOrBoundGenericStruct(); + if (!decl) + return None; + ASTContext &astCtx = ty->getASTContext(); + if (decl == astCtx.getIntDecl() || decl == astCtx.getInt8Decl() || + decl == astCtx.getInt16Decl() || decl == astCtx.getInt32Decl() || + decl == astCtx.getInt64Decl()) { + return true; + } + if (decl == astCtx.getUIntDecl() || decl == astCtx.getUInt8Decl() || + decl == astCtx.getUInt16Decl() || decl == astCtx.getUInt32Decl() || + decl == astCtx.getUInt64Decl()) { + return false; + } + return None; +} + /// Given a call to a well known function, collect its arguments as constants, /// fold it, and return None. If any of the arguments are not constants, marks /// the call's results as Unknown, and return an Unknown with information about @@ -803,8 +836,8 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, for (unsigned i = 0; i < apply->getNumArguments(); i++) { SILValue argument = apply->getArgument(i); SymbolicValue argValue = getConstantValue(argument); - Optional stringOpt = extractStaticStringValue(argValue); - + Optional stringOpt = + extractStringOrStaticStringValue(argValue); // The first argument is a prefix that specifies the kind of failure // this is. if (i == 0) { @@ -816,7 +849,6 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, } continue; } - if (stringOpt) { message += ": "; message += stringOpt.getValue(); @@ -1064,6 +1096,42 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, setValue(apply, resultVal); return None; } + case WellKnownFunction::BinaryIntegerDescription: { + // BinaryInteger.description.getter + assert(conventions.getNumDirectSILResults() == 1 && + conventions.getNumIndirectSILResults() == 0 && + conventions.getNumParameters() == 1 && apply->hasSubstitutions() && + "unexpected BinaryInteger.description.getter signature"); + // Get the type of the argument and check if it is a signed or + // unsigned integer. + SILValue integerArgument = apply->getOperand(1); + CanType argumentType = substituteGenericParamsAndSimpify( + integerArgument->getType().getASTType()); + Optional isSignedIntegerType = + getSignIfStdlibIntegerType(argumentType); + if (!isSignedIntegerType.hasValue()) { + return getUnknown(evaluator, (SILInstruction *)apply, + UnknownReason::InvalidOperandValue); + } + // Load the stdlib integer's value and convert it to a string. + SymbolicValue stdlibIntegerValue = + getConstAddrAndLoadResult(integerArgument); + if (!stdlibIntegerValue.isConstant()) { + return stdlibIntegerValue; + } + SymbolicValue builtinIntegerValue = + stdlibIntegerValue.lookThroughSingleElementAggregates(); + assert(builtinIntegerValue.getKind() == SymbolicValue::Integer && + "stdlib integer type must store only a builtin integer"); + APInt integer = builtinIntegerValue.getIntegerValue(); + SmallString<8> integerString; + isSignedIntegerType.getValue() ? integer.toStringSigned(integerString) + : integer.toStringUnsigned(integerString); + SymbolicValue resultVal = + SymbolicValue::getString(integerString.str(), evaluator.getAllocator()); + setValue(apply, resultVal); + return None; + } case WellKnownFunction::DebugPrint: { assert(apply->getNumArguments() == 1 && "debug_print function must take exactly one argument"); diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp index 6860d71f77ef7..1910e242ce091 100644 --- a/lib/Sema/CSDiag.cpp +++ b/lib/Sema/CSDiag.cpp @@ -1202,32 +1202,6 @@ static Expr *getFailedArgumentExpr(CalleeCandidateInfo CCI, Expr *argExpr) { bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI, Expr *fnExpr, Expr *argExpr, ArrayRef argLabels) { - if (auto *MTT = CS.getType(fnExpr)->getAs()) { - auto instTy = MTT->getInstanceType(); - auto &DE = CS.getASTContext().Diags; - if (instTy->getAnyNominal()) { - // If we are invoking a constructor on a nominal type and there are - // absolutely no candidates, then they must all be private. - if (CCI.empty() || (CCI.size() == 1 && CCI.candidates[0].getDecl() && - isa(CCI.candidates[0].getDecl()))) { - DE.diagnose(fnExpr->getLoc(), diag::no_accessible_initializers, - instTy); - return true; - } - // continue below - } else if (!instTy->is()) { - // If we are invoking a constructor on a non-nominal type, the expression - // is malformed. - SourceRange initExprRange(fnExpr->getSourceRange().Start, - argExpr->getSourceRange().End); - DE.diagnose(fnExpr->getLoc(), instTy->isExistentialType() ? - diag::construct_protocol_by_name : - diag::non_nominal_no_initializers, instTy) - .highlight(initExprRange); - return true; - } - } - // Try to diagnose errors related to the use of implicit self reference. if (diagnoseImplicitSelfErrors(fnExpr, argExpr, CCI, argLabels)) return true; @@ -1268,59 +1242,9 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI, return false; } -// Check if there is a structural problem in the function expression -// by performing type checking with the option to allow unresolved -// type variables. If that is going to produce a function type with -// unresolved result let's not re-typecheck the function expression, -// because it might produce unrelated diagnostics due to lack of -// contextual information. -static bool shouldTypeCheckFunctionExpr(FailureDiagnosis &FD, DeclContext *DC, - Expr *fnExpr) { - if (!isa(fnExpr)) - return true; - - SmallPtrSet fnTypes; - FD.getPossibleTypesOfExpressionWithoutApplying( - fnExpr, DC, fnTypes, FreeTypeVariableBinding::UnresolvedType); - - if (fnTypes.size() == 1) { - // Some member types depend on the arguments to produce a result type, - // type-checking such expressions without associated arguments is - // going to produce unrelated diagnostics. - if (auto fn = (*fnTypes.begin())->getAs()) { - auto resultType = fn->getResult(); - if (resultType->hasUnresolvedType() || resultType->hasTypeVariable()) - return false; - } - } - - // Might be a structural problem related to the member itself. - return true; -} - bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { auto *fnExpr = callExpr->getFn(); - - if (shouldTypeCheckFunctionExpr(*this, CS.DC, fnExpr)) { - // Type check the function subexpression to resolve a type for it if - // possible. - fnExpr = typeCheckChildIndependently(callExpr->getFn()); - if (!fnExpr) { - return CS.getASTContext().Diags.hadAnyError(); - } - } - - SWIFT_DEFER { - if (!fnExpr) return; - - // If it's a member operator reference, put the operator back. - if (auto operatorRef = fnExpr->getMemberOperatorRef()) - callExpr->setFn(operatorRef); - }; - - auto getFuncType = [](Type type) -> Type { return type->getRValueType(); }; - - auto fnType = getFuncType(CS.getType(fnExpr)); + auto fnType = CS.getType(fnExpr)->getRValueType(); bool hasTrailingClosure = callArgHasTrailingClosure(callExpr->getArg()); @@ -1372,21 +1296,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { } } - // Let's check whether this is a situation when callee expects - // no arguments but N are given. Otherwise, just below - // `typeCheckArgumentChild*` is going to use `()` is a contextual type which - // is incorrect. - if (argType && argType->isVoid()) { - auto *argExpr = callExpr->getArg(); - if (isa(argExpr) || - (isa(argExpr) && - cast(argExpr)->getNumElements() > 0)) { - diagnose(callExpr->getLoc(), diag::extra_argument_to_nullary_call) - .highlight(argExpr->getSourceRange()); - return true; - } - } - // Get the expression result of type checking the arguments to the call // independently, so we have some idea of what we're working with. // @@ -1489,17 +1398,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { if (CS.getType(argExpr)->hasUnresolvedType()) return false; - SmallVector params; - AnyFunctionType::decomposeInput(CS.getType(argExpr), params); - auto argString = AnyFunctionType::getParamListAsString(params); - - if (auto MTT = fnType->getAs()) { - if (MTT->getInstanceType()->isExistentialType()) { - diagnose(fnExpr->getLoc(), diag::construct_protocol_value, fnType); - return true; - } - } - bool isInitializer = isa(fnExpr); if (isa(argExpr) && cast(argExpr)->getNumElements() == 0) { @@ -1507,6 +1405,10 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { diagnose(fnExpr->getLoc(), diag::cannot_call_with_no_params, overloadName, isInitializer); } else { + SmallVector params; + AnyFunctionType::decomposeInput(CS.getType(argExpr), params); + auto argString = AnyFunctionType::getParamListAsString(params); + diagnose(fnExpr->getLoc(), diag::cannot_call_with_params, overloadName, argString, isInitializer); } diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index df3bd12ac70d2..b8cf4a95a75bb 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -4561,7 +4561,21 @@ bool ExtraneousArgumentsFailure::diagnoseAsNote() { } bool ExtraneousArgumentsFailure::diagnoseSingleExtraArgument() const { - auto *arguments = getArgumentListExprFor(getLocator()); + auto *locator = getLocator(); + + // This specifically handles a case of `Void(...)` which generates + // constraints differently from other constructor invocations and + // wouldn't have `ApplyArgument` as a last element in the locator. + if (auto *call = dyn_cast(getRawAnchor())) { + auto *TE = dyn_cast(call->getFn()); + if (TE && getType(TE)->getMetatypeInstanceType()->isVoid()) { + emitDiagnostic(call->getLoc(), diag::extra_argument_to_nullary_call) + .highlight(call->getArg()->getSourceRange()); + return true; + } + } + + auto *arguments = getArgumentListExprFor(locator); if (!arguments) return false; diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 0b3346c403819..3d00cf3de5a07 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -2249,8 +2249,17 @@ ConstraintSystem::matchTypesBindTypeVar( // Simplify the right-hand type and perform the "occurs" check. typeVar = getRepresentative(typeVar); type = simplifyType(type, flags); - if (!isBindable(typeVar, type)) + if (!isBindable(typeVar, type)) { + if (shouldAttemptFixes()) { + // If type variable is allowed to be a hole and it can't be bound to + // a particular (full resolved) type, just ignore this binding + // instead of re-trying it and failing later. + if (typeVar->getImpl().canBindToHole() && !type->hasTypeVariable()) + return getTypeMatchSuccess(); + } + return formUnsolvedResult(); + } // Since member lookup doesn't check requirements // it might sometimes return types which are not @@ -3322,10 +3331,13 @@ bool ConstraintSystem::repairFailures( if (lhs->hasHole() || rhs->hasHole()) return true; - // If dependent members are present here it's because - // base doesn't conform to associated type's protocol. - if (lhs->hasDependentMember() || rhs->hasDependentMember()) - break; + // If dependent members are present here it's because the base doesn't + // conform to the associated type's protocol. We can only get here if we + // already applied a fix for the conformance failure. + if (lhs->hasDependentMember() || rhs->hasDependentMember()) { + increaseScore(SK_Fix); + return true; + } // If requirement is something like `T == [Int]` let's let // type matcher a chance to match generic parameters before @@ -3940,12 +3952,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, llvm_unreachable("type variables should have already been handled by now"); case TypeKind::DependentMember: { - // If one of the dependent member types has no type variables, - // this comparison is effectively illformed, because dependent - // member couldn't be simplified down to the actual type, and - // we wouldn't be able to solve this constraint, so let's just fail. - if (!desugar1->hasTypeVariable() || !desugar2->hasTypeVariable()) - return getTypeMatchFailure(locator); + // If one of the dependent member types has no type variables, the + // dependent member can't be simplified because the base doesn't conform + // to the associated type's protocol. We can only get here if we already + // applied a fix for the conformance failure. + if (!desugar1->hasTypeVariable() || !desugar2->hasTypeVariable()) { + increaseScore(SK_Fix); + return getTypeMatchSuccess(); + } // Nothing we can solve yet, since we need to wait until // type variables will get resolved. @@ -7509,6 +7523,18 @@ ConstraintSystem::simplifyApplicableFnConstraint( // following: $T1 -> $T2. auto func1 = type1->castTo(); + // If a type variable representing "function type" is a hole + // or it could be bound to some concrete type with a help of + // a fix, let's propagate holes to the "input" type. Doing so + // provides more information to upcoming argument and result matching. + if (shouldAttemptFixes()) { + if (auto *typeVar = type2->getAs()) { + auto *locator = typeVar->getImpl().getLocator(); + if (typeVar->isHole() || hasFixFor(locator)) + recordPotentialHole(func1); + } + } + // Before stripping lvalue-ness and optional types, save the original second // type for handling `func callAsFunction` and `@dynamicCallable` // applications. This supports the following cases: @@ -7721,10 +7747,7 @@ ConstraintSystem::simplifyApplicableFnConstraint( // If there are any type variables associated with arguments/result // they have to be marked as "holes". - type1.visit([&](Type subType) { - if (auto *typeVar = subType->getAs()) - recordPotentialHole(typeVar); - }); + recordPotentialHole(func1); if (desugar2->isHole()) return SolutionKind::Solved; @@ -7998,11 +8021,7 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint( return SolutionKind::Error; recordPotentialHole(tv); - - Type(func1).visit([&](Type type) { - if (auto *typeVar = type->getAs()) - recordPotentialHole(typeVar); - }); + recordPotentialHole(func1); return SolutionKind::Solved; } @@ -8563,6 +8582,14 @@ void ConstraintSystem::recordPotentialHole(TypeVariableType *typeVar) { typeVar->getImpl().enableCanBindToHole(getSavedBindings()); } +void ConstraintSystem::recordPotentialHole(FunctionType *fnType) { + assert(fnType); + Type(fnType).visit([&](Type type) { + if (auto *typeVar = type->getAs()) + recordPotentialHole(typeVar); + }); +} + ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint( ConstraintFix *fix, Type type1, Type type2, ConstraintKind matchKind, TypeMatchOptions flags, ConstraintLocatorBuilder locator) { diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index a639bd9d1e72b..472174e6de469 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -2359,6 +2359,7 @@ class ConstraintSystem { bool recordFix(ConstraintFix *fix, unsigned impact = 1); void recordPotentialHole(TypeVariableType *typeVar); + void recordPotentialHole(FunctionType *fnType); /// Determine whether constraint system already has a fix recorded /// for a particular location. diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h index 5725f294885f9..1c60a7561c5b8 100644 --- a/stdlib/public/SwiftShims/LibcShims.h +++ b/stdlib/public/SwiftShims/LibcShims.h @@ -43,6 +43,8 @@ typedef __swift_uint32_t __swift_mode_t; typedef __swift_uint16_t __swift_mode_t; #elif defined(_WIN32) typedef __swift_int32_t __swift_mode_t; +#elif defined(__wasi__) +typedef __swift_uint32_t __swift_mode_t; #else // just guessing typedef __swift_uint16_t __swift_mode_t; #endif @@ -105,7 +107,7 @@ static inline __swift_size_t _swift_stdlib_malloc_size(const void *ptr) { return malloc_size(ptr); } #elif defined(__linux__) || defined(__CYGWIN__) || defined(__ANDROID__) \ - || defined(__HAIKU__) || defined(__FreeBSD__) + || defined(__HAIKU__) || defined(__FreeBSD__) || defined(__wasi__) static inline __swift_size_t _swift_stdlib_malloc_size(const void *ptr) { #if defined(__ANDROID__) #if !defined(__ANDROID_API__) || __ANDROID_API__ >= 17 diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift index 7a9ac0035e10e..56e85f0dfc57d 100644 --- a/stdlib/public/core/Integers.swift +++ b/stdlib/public/core/Integers.swift @@ -1557,6 +1557,7 @@ extension BinaryInteger { } /// A textual representation of this value. + @_semantics("binaryInteger.description") public var description: String { return _description(radix: 10, uppercase: false) } diff --git a/stdlib/public/stubs/CommandLine.cpp b/stdlib/public/stubs/CommandLine.cpp index 0b4506391beeb..cf371e5ababe4 100644 --- a/stdlib/public/stubs/CommandLine.cpp +++ b/stdlib/public/stubs/CommandLine.cpp @@ -206,6 +206,42 @@ char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { return outBuf; } +#elif defined(__wasi__) +#include +#include +#include + +SWIFT_RUNTIME_STDLIB_API +char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { + assert(outArgLen != nullptr); + + if (_swift_stdlib_ProcessOverrideUnsafeArgv) { + *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; + return _swift_stdlib_ProcessOverrideUnsafeArgv; + } + + __wasi_errno_t err; + + size_t argv_buf_size; + size_t argc; + err = __wasi_args_sizes_get(&argc, &argv_buf_size); + if (err != __WASI_ERRNO_SUCCESS) return nullptr; + + size_t num_ptrs = argc + 1; + char *argv_buf = (char *)malloc(argv_buf_size); + char **argv = (char **)calloc(num_ptrs, sizeof(char *)); + + err = __wasi_args_get((uint8_t **)argv, (uint8_t *)argv_buf); + if (err != __WASI_ERRNO_SUCCESS) { + free(argv_buf); + free(argv); + return nullptr; + } + + *outArgLen = static_cast(argc); + + return argv; +} #else // Add your favorite OS's command line arg grabber here. SWIFT_RUNTIME_STDLIB_API char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp index 083deaa4747a1..b54ede8c61f66 100644 --- a/stdlib/public/stubs/LibcShims.cpp +++ b/stdlib/public/stubs/LibcShims.cpp @@ -23,7 +23,7 @@ #include #include -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__wasi__) #include #endif diff --git a/stdlib/public/stubs/Random.cpp b/stdlib/public/stubs/Random.cpp index bb69f7e7793d1..bc130b145015b 100644 --- a/stdlib/public/stubs/Random.cpp +++ b/stdlib/public/stubs/Random.cpp @@ -42,6 +42,8 @@ #include "swift/Runtime/Mutex.h" #include "../SwiftShims/Random.h" +#include // required for std::min + #if defined(__APPLE__) SWIFT_RUNTIME_STDLIB_API @@ -88,7 +90,7 @@ void swift::swift_stdlib_random(void *buf, __swift_size_t nbytes) { if (getrandom_available) { actual_nbytes = WHILE_EINTR(syscall(__NR_getrandom, buf, nbytes, 0)); } -#elif __has_include() && (defined(__CYGWIN__) || defined(__Fuchsia__)) +#elif __has_include() && (defined(__CYGWIN__) || defined(__Fuchsia__) || defined(__wasi__)) __swift_size_t getentropy_nbytes = std::min(nbytes, __swift_size_t{256}); if (0 == getentropy(buf, getentropy_nbytes)) { diff --git a/stdlib/public/stubs/Stubs.cpp b/stdlib/public/stubs/Stubs.cpp index 55bada6a1db92..d5548c388df57 100644 --- a/stdlib/public/stubs/Stubs.cpp +++ b/stdlib/public/stubs/Stubs.cpp @@ -26,7 +26,7 @@ #define NOMINMAX #include #else -#if !defined(__HAIKU__) +#if !defined(__HAIKU__) && !defined(__wasi__) #include #else #include @@ -67,7 +67,7 @@ static float swift_strtof_l(const char *nptr, char **endptr, locale_t loc) { #define strtod_l swift_strtod_l #define strtof_l swift_strtof_l #endif -#elif defined(__linux__) +#elif defined(__linux__) || defined(__wasi__) #include #else #include @@ -503,6 +503,8 @@ const char *swift::_swift_stdlib_strtof_clocale( void swift::_swift_stdlib_flockfile_stdout() { #if defined(_WIN32) _lock_file(stdout); +#elif defined(__wasi__) + // WebAssembly/WASI doesn't support file locking yet https://bugs.swift.org/browse/SR-12097 #else flockfile(stdout); #endif @@ -511,6 +513,8 @@ void swift::_swift_stdlib_flockfile_stdout() { void swift::_swift_stdlib_funlockfile_stdout() { #if defined(_WIN32) _unlock_file(stdout); +#elif defined(__wasi__) + // WebAssembly/WASI doesn't support file locking yet https://bugs.swift.org/browse/SR-12097 #else funlockfile(stdout); #endif diff --git a/test/Constraints/bridging.swift b/test/Constraints/bridging.swift index bafa1dab76723..4cdc52e3e2626 100644 --- a/test/Constraints/bridging.swift +++ b/test/Constraints/bridging.swift @@ -265,7 +265,7 @@ func rdar19831698() { var v71 = true + 1.0 // expected-error{{binary operator '+' cannot be applied to operands of type 'Bool' and 'Double'}} // expected-note@-1{{overloads for '+'}} var v72 = true + true // expected-error{{binary operator '+' cannot be applied to two 'Bool' operands}} - var v73 = true + [] // expected-error@:13 {{cannot convert value of type 'Bool' to expected argument type 'Array'}} + var v73 = true + [] // expected-error@:18 {{binary operator '+' cannot be applied to operands of type 'Bool' and '[Any]'}} var v75 = true + "str" // expected-error@:13 {{cannot convert value of type 'Bool' to expected argument type 'String'}} } diff --git a/test/Constraints/members.swift b/test/Constraints/members.swift index 7a39dd010c393..c2de930b8b443 100644 --- a/test/Constraints/members.swift +++ b/test/Constraints/members.swift @@ -405,17 +405,17 @@ func bar_32854314() -> Int { extension Array where Element == Int { func foo() { let _ = min(foo_32854314(), bar_32854314()) // expected-note {{use 'Swift.' to reference the global function in module 'Swift'}} {{13-13=Swift.}} - // expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min()'}} + // expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min(by:)'}} } func foo(_ x: Int, _ y: Double) { let _ = min(x, y) // expected-note {{use 'Swift.' to reference the global function in module 'Swift'}} {{13-13=Swift.}} - // expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min()'}} + // expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min(by:)'}} } func bar() { let _ = min(1.0, 2) // expected-note {{use 'Swift.' to reference the global function in module 'Swift'}} {{13-13=Swift.}} - // expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min()'}} + // expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min(by:)'}} } } diff --git a/test/Constraints/same_types.swift b/test/Constraints/same_types.swift index 2eda295170a75..6129d8046338b 100644 --- a/test/Constraints/same_types.swift +++ b/test/Constraints/same_types.swift @@ -333,3 +333,25 @@ class R: P7 where T: P7, T.A == T.Type { // expected-note {{'T' declared as p R.fn(args: R.self) // expected-error {{generic parameter 'T' could not be inferred}} // expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} + +// rdar://problem/58607155 +protocol AssocType1 { associatedtype A } +protocol AssocType2 { associatedtype A } + +func rdar58607155() { + func f(t1: T1, t2: T2) where T1.A == T2.A {} + // expected-note@-1 2 {{where 'T2' = 'MissingConformance'}} + // expected-note@-2 2 {{where 'T1' = 'MissingConformance'}} + + class Conformance: AssocType1, AssocType2 { typealias A = Int } + class MissingConformance {} + + // One generic argument has a conformance failure + f(t1: MissingConformance(), t2: Conformance()) // expected-error {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType1'}} + f(t1: Conformance(), t2: MissingConformance()) // expected-error {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType2'}} + + // Both generic arguments have a conformance failure + f(t1: MissingConformance(), t2: MissingConformance()) + // expected-error@-1 {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType1'}} + // expected-error@-2 {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType2'}} +} diff --git a/test/DebugInfo/linetable-codeview.swift b/test/DebugInfo/linetable-codeview.swift index 524d49c8561b9..77c7141e7a1ad 100644 --- a/test/DebugInfo/linetable-codeview.swift +++ b/test/DebugInfo/linetable-codeview.swift @@ -81,7 +81,7 @@ func foo() { // FIXME: The location of ``@llvm.trap`` should be in Integers.swift.gyb // instead of being artificial. // CHECK: ![[INLINEDADD]] = !DILocation(line: 0, scope: ![[FAILURE_FUNC:[0-9]+]], inlinedAt: ![[INLINELOC:[0-9]+]] -// CHECK-DAG: !{{.*}} = distinct !DISubprogram(linkageName: "Swift runtime failure: arithmetic overflow", scope: {{.*}}, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, {{.*}}) +// CHECK-DAG: !{{.*}} = distinct !DISubprogram(name: "Swift runtime failure: arithmetic overflow", scope: {{.*}}, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, {{.*}}) // CHECK-DAG: ![[INLINELOC]] = !DILocation(line: 0, scope: !{{[0-9]+}}, inlinedAt: ![[ADD]] // NOTE: These prologue instructions are given artificial line locations for diff --git a/test/IRGen/condfail_message.swift b/test/IRGen/condfail_message.swift index 8c3eabb2da652..5a5fc702cf465 100644 --- a/test/IRGen/condfail_message.swift +++ b/test/IRGen/condfail_message.swift @@ -11,6 +11,6 @@ func testit(_ a: Int8) -> Int8 { // CHECK: [[CALLER_LOC:![0-9]+]] = !DILocation(line: 9, column: 12, scope: !{{.*}}) // CHECK: [[LOC]] = !DILocation(line: 0, scope: [[FAILURE_FUNC:![0-9]+]], inlinedAt: [[CALLER_LOC]]) -// CHECK: [[FAILURE_FUNC]] = distinct !DISubprogram(linkageName: "Swift runtime failure: arithmetic overflow", scope: {{.*}}, file: {{.*}}, type: [[FUNC_TYPE:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, {{.*}}) +// CHECK: [[FAILURE_FUNC]] = distinct !DISubprogram(name: "Swift runtime failure: arithmetic overflow", scope: {{.*}}, file: {{.*}}, type: [[FUNC_TYPE:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, {{.*}}) // CHECK: [[FUNC_TYPE]] = !DISubroutineType(types: null) diff --git a/test/SILGen/opaque_result_type.swift b/test/SILGen/opaque_result_type.swift index eacbd6204ab5f..6980e773fc4c3 100644 --- a/test/SILGen/opaque_result_type.swift +++ b/test/SILGen/opaque_result_type.swift @@ -149,3 +149,19 @@ struct S2 : X { return foo } } + +class Base {} +class Sub1 : Base {} +class Sub2 : Base {} + +public class D { + var cond = true + // CHECK-LABEL: sil private [ossa] @$s18opaque_result_type1DC1c33_C2C55A4BAF30C3244D4A165D48A91142LLQrvg + // CHECK: bb3([[RET:%[0-9]+]] : @owned $Base): + // CHECH: return [[RET]] + // CHECK: } // end sil function '$s18opaque_result_type1DC1c33_C2C55A4BAF30C3244D4A165D48A91142LLQrvg' + private lazy var c: some Base = { + let d = cond ? Sub1() : Sub2() + return d + }() +} diff --git a/test/SILOptimizer/constant_evaluable_subset_test.swift b/test/SILOptimizer/constant_evaluable_subset_test.swift index b1603de445de7..49174d0db7c16 100644 --- a/test/SILOptimizer/constant_evaluable_subset_test.swift +++ b/test/SILOptimizer/constant_evaluable_subset_test.swift @@ -911,3 +911,49 @@ func interpretMetaTypeCast() -> Bool { func interpretMetaTypeCast2() -> Bool { return testMetaTypeCast(((Int) -> Int).self) } + +// CHECK-LABEL: @testBinaryIntegerDescription +// CHECK-NOT: error: +@_semantics("constant_evaluable") +func testBinaryIntegerDescription(_ x: T) -> String { + return x.description +} + +@_semantics("test_driver") +func interpretBinaryIntegerDescription() -> String { + var str = testBinaryIntegerDescription(-10) + str += testBinaryIntegerDescription(UInt(20)) + return str +} + +// CHECK-LABEL: @testPreconditionFailure +// CHECK: error: not constant evaluable +@_semantics("constant_evaluable") +func testPreconditionFailure(_ x: Int) -> Int { + precondition(x > 0, "argument must be positive") + return x + 1 + // CHECK: note: operation traps + // Note that the message displayed depends on the assert configuration, + // therefore it is not checked here. For debug stdlib, the full message + // must be displayed. +} + +@_semantics("test_driver") +func interpretPreconditionFailure() -> Int { + return testPreconditionFailure(-10) +} + +// CHECK-LABEL: @testFatalError +// CHECK: error: not constant evaluable +@_semantics("constant_evaluable") +func testFatalError() -> Int { + fatalError("invoked an uncallable function") + return 0 + // CHECK: note: Fatal error: invoked an uncallable function + // CHECK: note: operation traps +} + +@_semantics("test_driver") +func interpretFatalError() -> Int { + return testFatalError() +} diff --git a/test/SILOptimizer/constant_evaluator_test.sil b/test/SILOptimizer/constant_evaluator_test.sil index b1a3a9a1123e2..fb555685f89a1 100644 --- a/test/SILOptimizer/constant_evaluator_test.sil +++ b/test/SILOptimizer/constant_evaluator_test.sil @@ -1503,3 +1503,31 @@ bb0: %3 = apply %2(%1) : $@convention(thin) <τ_0_0> (@thick τ_0_0.Type) -> Builtin.Int1 return %3 : $Builtin.Int1 } // CHECK: Returns int: -1 + +// CHECK-LABEL: @interpretBinaryIntegerDescription +sil [ossa] @interpretBinaryIntegerDescription : $@convention(thin) () -> @owned String { +bb0: + %0 = integer_literal $Builtin.Int64, -10 + %1 = struct $Int64 (%0 : $Builtin.Int64) + %2 = alloc_stack $Int64 + store %1 to [trivial] %2 : $*Int64 + %4 = function_ref @binaryIntegerDescription : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String + %5 = apply %4(%2) : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String + dealloc_stack %2 : $*Int64 + return %5 : $String +} // CHECK: Returns string: "-10" + +sil [_semantics "binaryInteger.description"] @binaryIntegerDescription : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String + +// CHECK-LABEL: @interpretUnsignedBinaryIntegerDescription +sil [ossa] @interpretUnsignedBinaryIntegerDescription : $@convention(thin) () -> @owned String { +bb0: + %0 = integer_literal $Builtin.Int64, 0xffffffffffffffff + %1 = struct $UInt64 (%0 : $Builtin.Int64) + %2 = alloc_stack $UInt64 + store %1 to [trivial] %2 : $*UInt64 + %4 = function_ref @binaryIntegerDescription : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String + %5 = apply %4(%2) : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String + dealloc_stack %2 : $*UInt64 + return %5 : $String +} // CHECK: Returns string: "18446744073709551615" diff --git a/test/Serialization/Inputs/nested-type-with-overlay/overlay.swift b/test/Serialization/Inputs/nested-type-with-overlay/overlay.swift index 72f831e10f774..754423baa4235 100644 --- a/test/Serialization/Inputs/nested-type-with-overlay/overlay.swift +++ b/test/Serialization/Inputs/nested-type-with-overlay/overlay.swift @@ -8,3 +8,13 @@ extension Base { } public var shadowedFromSwift = Base.NestedAndShadowed(dummy: ()) + +public struct CustomError { + public struct Code : RawRepresentable { + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + } +} diff --git a/test/Serialization/nested-type-with-overlay.swift b/test/Serialization/nested-type-with-overlay.swift index e2c2f36cb0423..4b83de9c05b7b 100644 --- a/test/Serialization/nested-type-with-overlay.swift +++ b/test/Serialization/nested-type-with-overlay.swift @@ -8,8 +8,8 @@ // REQUIRES: asserts -// CHECK: 3 Serialization - # of nested types resolved without full lookup -// Unfortunately this isn't 4 because of the shadowed nested type from Clang. +// CHECK: 4 Serialization - # of nested types resolved without full lookup +// Unfortunately this isn't 5 because of the shadowed nested type from Clang. import HasOverlay @@ -20,3 +20,9 @@ public func resolveNestedTypes( public var shadowedFromClang = getShadowedFromClang() public var shadowedFromSwift = HasOverlay.shadowedFromSwift + +extension CustomError.Code { + public static var failedSuccessfully: CustomError.Code { + return CustomError.Code(rawValue: -9999) + } +} diff --git a/test/TBD/linker-directives-ld-previous-macos.swift b/test/TBD/linker-directives-ld-previous-macos.swift index 86ab5883ddb76..f678721facd96 100644 --- a/test/TBD/linker-directives-ld-previous-macos.swift +++ b/test/TBD/linker-directives-ld-previous-macos.swift @@ -7,8 +7,14 @@ // RUN: %target-swift-frontend -typecheck %S/Inputs/linker-directive.swift -emit-tbd -emit-tbd-path %t/linker_directives.tbd -previous-module-installname-map-file %S/Inputs/install-name-map-toasterkit.json // RUN: %FileCheck %s < %t/linker_directives.tbd +// RUN: %target-swift-frontend -target-variant x86_64-apple-ios13.0-macabi -typecheck %S/Inputs/linker-directive.swift -emit-tbd -emit-tbd-path %t/linker_directives.tbd -previous-module-installname-map-file %S/Inputs/install-name-map-toasterkit.json +// RUN: %FileCheck -check-prefix=CHECK-ZIPPERED %s < %t/linker_directives.tbd + // CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit5toastyyF$ // CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleV4moveyyF$ // CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVMa$ // CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVMn$ -// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVN$ \ No newline at end of file +// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVN$ + +// CHECK-ZIPPERED: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit5toastyyF$ +// CHECK-ZIPPERED: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit5toastyyF$ diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift index 43af91bfcfebb..e63fe024f7fa4 100644 --- a/test/expr/expressions.swift +++ b/test/expr/expressions.swift @@ -748,10 +748,8 @@ func invalidDictionaryLiteral() { } -[4].joined(separator: [1]) // expected-error {{cannot convert value of type 'Int' to expected element type 'String'}} -// expected-error@-1 {{cannot convert value of type '[Int]' to expected argument type 'String'}} -[4].joined(separator: [[[1]]]) // expected-error {{cannot convert value of type 'Int' to expected element type 'String'}} -// expected-error@-1 {{cannot convert value of type '[[[Int]]]' to expected argument type 'String'}} +[4].joined(separator: [1]) // expected-error {{referencing instance method 'joined(separator:)' on 'Sequence' requires that 'Int' conform to 'Sequence'}} +[4].joined(separator: [[[1]]]) // expected-error {{referencing instance method 'joined(separator:)' on 'Sequence' requires that 'Int' conform to 'Sequence'}} //===----------------------------------------------------------------------===// // nil/metatype comparisons diff --git a/test/type/protocol_composition.swift b/test/type/protocol_composition.swift index b78a9af3a5fd0..a75b0414b5aa5 100644 --- a/test/type/protocol_composition.swift +++ b/test/type/protocol_composition.swift @@ -173,7 +173,9 @@ takesP1AndP2([Swift.AnyObject & P1 & P2]()) takesP1AndP2([AnyObject & protocol_composition.P1 & P2]()) takesP1AndP2([AnyObject & P1 & protocol_composition.P2]()) takesP1AndP2([DoesNotExist & P1 & P2]()) // expected-error {{use of unresolved identifier 'DoesNotExist'}} -takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{module 'Swift' has no member named 'DoesNotExist'}} +// TODO(diagnostics): The problem here is that `&` is interpreted as a binary operator, we need to re-think +// how "missing member" fix is implemented because currently it finds N solutions with multiple fixes. +takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{cannot invoke '' with no arguments}} typealias T08 = P1 & inout P2 // expected-error {{'inout' may only be used on parameters}} typealias T09 = P1 & __shared P2 // expected-error {{'__shared' may only be used on parameters}} diff --git a/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake b/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake index 4f88629516aa4..83b70845e0886 100644 --- a/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake +++ b/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake @@ -71,6 +71,12 @@ function(add_sourcekit_default_compiler_flags target) LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories) # Set compilation and link flags. + if(${SWIFT_HOST_VARIANT_SDK} STREQUAL WINDOWS) + swift_windows_include_for_arch(${SWIFT_HOST_VARIANT_ARCH} + ${SWIFT_HOST_VARIANT_ARCH}_INCLUDE) + target_include_directories(${target} SYSTEM PRIVATE + ${${SWIFT_HOST_VARIANT_ARCH}_INCLUDE}) + endif() target_compile_options(${target} PRIVATE -fblocks) target_link_options(${target} PRIVATE diff --git a/utils/build-script b/utils/build-script index ec82542135207..e5811049a68c0 100755 --- a/utils/build-script +++ b/utils/build-script @@ -510,9 +510,7 @@ class BuildScriptInvocation(object): ] if args.skip_build: - impl_args += ["--skip-build-cmark", - "--skip-build-llvm", - "--skip-build-swift"] + impl_args += ["--skip-build"] if not args.build_benchmarks: impl_args += ["--skip-build-benchmarks"] # Currently we do not build external benchmarks by default. diff --git a/utils/build-script-impl b/utils/build-script-impl index 49239434d12e0..b5b3264410f36 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -30,12 +30,13 @@ umask 0022 # A default value of "" indicates that the corresponding variable # will remain unset unless set explicitly. # -# skip-* parameters do not affect the configuration (CMake parameters). -# You can turn them on and off in different invocations of the script for the -# same build directory. +# The --skip-build parameter, with no product name, does not affect the +# configuration (CMake parameters). You can turn this option on and +# off in different invocations of the script for the same build +# directory without affecting configutation. # -# build-* parameters affect the CMake configuration (enable/disable those -# components). +# skip-build-* and build-* parameters affect the CMake configuration +# (enable/disable those components). # # Each variable name is re-exported into this script in uppercase, where dashes # are substituted by underscores. For example, `swift-install-components` is @@ -118,6 +119,7 @@ KNOWN_SETTINGS=( swift-stdlib-build-type "Debug" "the CMake build variant for Swift" ## Skip Build ... + skip-build "" "set to configure as usual while skipping the build step" skip-build-android "" "set to skip building Swift stdlibs for Android" skip-build-benchmarks "" "set to skip building Swift Benchmark Suite" skip-build-clang-tools-extra "" "set to skip building clang-tools-extra as part of llvm" @@ -1041,13 +1043,10 @@ if [[ ! "${SKIP_BUILD_PLAYGROUNDSUPPORT}" && ! -d ${PLAYGROUNDSUPPORT_SOURCE_DIR exit 1 fi -# We cannot currently apply the normal rules of skipping here for LLVM. Even if -# we are skipping building LLVM, we still need to at least build several tools -# that swift relies on for building and testing. See the LLVM configure rules. -PRODUCTS=(llvm) [[ "${SKIP_BUILD_CMARK}" ]] || PRODUCTS+=(cmark) [[ "${SKIP_BUILD_LIBCXX}" ]] || PRODUCTS+=(libcxx) [[ "${SKIP_BUILD_LIBICU}" ]] || PRODUCTS+=(libicu) +[[ "${SKIP_BUILD_LLVM}" ]] || PRODUCTS+=(llvm) [[ "${SKIP_BUILD_SWIFT}" ]] || PRODUCTS+=(swift) [[ "${SKIP_BUILD_LLDB}" ]] || PRODUCTS+=(lldb) [[ "${SKIP_BUILD_LIBDISPATCH}" ]] || PRODUCTS+=(libdispatch) @@ -1406,7 +1405,6 @@ for host in "${ALL_HOSTS[@]}"; do for product in "${PRODUCTS[@]}"; do [[ $(should_execute_action "${host}-${product/_static}-build") ]] || continue - unset skip_build source_dir_var="$(toupper ${product})_SOURCE_DIR" source_dir=${!source_dir_var} build_dir=$(build_directory ${host} ${product}) @@ -1436,7 +1434,7 @@ for host in "${ALL_HOSTS[@]}"; do if [ "${BUILD_LLVM}" == "0" ] ; then build_targets=(clean) fi - if [ "${SKIP_BUILD_LLVM}" ] ; then + if [ "${SKIP_BUILD}" ] ; then # We can't skip the build completely because the standalone # build of Swift depend on these for building and testing. build_targets=(llvm-tblgen clang-resource-headers intrinsics_gen clang-tablegen-targets) @@ -2207,18 +2205,25 @@ for host in "${ALL_HOSTS[@]}"; do fi # Build. - if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then - # Xcode generator uses "ALL_BUILD" instead of "all". - # Also, xcodebuild uses -target instead of bare names. - build_targets=("${build_targets[@]/all/ALL_BUILD}") - build_targets=("${build_targets[@]/#/${BUILD_TARGET_FLAG} }") - - # Xcode can't restart itself if it turns out we need to reconfigure. - # Do an advance build to handle that. - call "${CMAKE_BUILD[@]}" "${build_dir}" $(cmake_config_opt ${product}) - fi + # + # Even if builds are skipped, Swift configuration relies on + # some LLVM tools like TableGen. In the LLVM configure rules + # above, a small subset of LLVM build_targets are selected + # when SKIP_BUILD is set. + if [[ $(not ${SKIP_BUILD}) || "${product}" == "llvm" ]]; then + if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then + # Xcode generator uses "ALL_BUILD" instead of "all". + # Also, xcodebuild uses -target instead of bare names. + build_targets=("${build_targets[@]/all/ALL_BUILD}") + build_targets=("${build_targets[@]/#/${BUILD_TARGET_FLAG} }") + + # Xcode can't restart itself if it turns out we need to reconfigure. + # Do an advance build to handle that. + call "${CMAKE_BUILD[@]}" "${build_dir}" $(cmake_config_opt ${product}) + fi - call "${CMAKE_BUILD[@]}" "${build_dir}" $(cmake_config_opt ${product}) -- "${BUILD_ARGS[@]}" ${build_targets[@]} + call "${CMAKE_BUILD[@]}" "${build_dir}" $(cmake_config_opt ${product}) -- "${BUILD_ARGS[@]}" ${build_targets[@]} + fi # When we are building LLVM copy over the compiler-rt # builtins for iOS/tvOS/watchOS to ensure that Swift's diff --git a/utils/build_swift/build_swift/driver_arguments.py b/utils/build_swift/build_swift/driver_arguments.py index 3c607ee18efbb..ed569ad8a8473 100644 --- a/utils/build_swift/build_swift/driver_arguments.py +++ b/utils/build_swift/build_swift/driver_arguments.py @@ -131,29 +131,6 @@ def _apply_default_arguments(args): raise ValueError('error: --watchos-all is unavailable in open-source ' 'Swift.\nUse --watchos to skip watchOS device tests.') - # Propagate global --skip-build - if args.skip_build: - args.build_linux = False - args.build_freebsd = False - args.build_cygwin = False - args.build_osx = False - args.build_ios = False - args.build_tvos = False - args.build_watchos = False - args.build_android = False - args.build_benchmarks = False - args.build_external_benchmarks = False - args.build_lldb = False - args.build_llbuild = False - args.build_libcxx = False - args.build_swiftpm = False - args.build_xctest = False - args.build_foundation = False - args.build_libdispatch = False - args.build_libicu = False - args.build_playgroundsupport = False - args.build_pythonkit = False - # --skip-{ios,tvos,watchos} or --skip-build-{ios,tvos,watchos} are # merely shorthands for --skip-build-{**os}-{device,simulator} if not args.ios or not args.build_ios: diff --git a/utils/build_swift/tests/build_swift/test_driver_arguments.py b/utils/build_swift/tests/build_swift/test_driver_arguments.py index efbc469a28a3c..7811b6dd6d61e 100644 --- a/utils/build_swift/tests/build_swift/test_driver_arguments.py +++ b/utils/build_swift/tests/build_swift/test_driver_arguments.py @@ -540,30 +540,6 @@ def test_implied_defaults_build_variant(self): self.assertEqual(namespace.swift_build_variant, 'Debug') self.assertEqual(namespace.swift_stdlib_build_variant, 'Debug') - def test_implied_defaults_skip_build(self): - namespace = self.parse_default_args(['--skip-build']) - - self.assertFalse(namespace.build_benchmarks) - - self.assertFalse(namespace.build_linux) - self.assertFalse(namespace.build_android) - self.assertFalse(namespace.build_freebsd) - self.assertFalse(namespace.build_cygwin) - self.assertFalse(namespace.build_osx) - self.assertFalse(namespace.build_ios) - self.assertFalse(namespace.build_tvos) - self.assertFalse(namespace.build_watchos) - - self.assertFalse(namespace.build_foundation) - self.assertFalse(namespace.build_libdispatch) - self.assertFalse(namespace.build_libicu) - self.assertFalse(namespace.build_lldb) - self.assertFalse(namespace.build_llbuild) - self.assertFalse(namespace.build_libcxx) - self.assertFalse(namespace.build_playgroundsupport) - self.assertFalse(namespace.build_swiftpm) - self.assertFalse(namespace.build_xctest) - def test_implied_defaults_skip_build_ios(self): namespace = self.parse_default_args(['--skip-build-ios']) self.assertFalse(namespace.build_ios_device) diff --git a/validation-test/compiler_crashers_2_fixed/rdar58941114.swift b/validation-test/compiler_crashers_2_fixed/rdar58941114.swift new file mode 100644 index 0000000000000..50db463dda4dd --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/rdar58941114.swift @@ -0,0 +1,6 @@ +// RUN: not %target-swift-frontend %s -typecheck + +class C {} +protocol Foo { + associatedtype X where C: X +}