diff --git a/CMakeLists.txt b/CMakeLists.txt index 309a32524b6d0..8fb1b429b98fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1048,6 +1048,14 @@ elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "ANDROID") set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}") set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}") +elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "WASI") + set(SWIFT_HOST_VARIANT "wasi" CACHE STRING + "Deployment OS for Swift host tools (the compiler) [wasi]") + + configure_sdk_unix("WASI" "wasm32") + set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}") + elseif("${SWIFT_HOST_VARIANT_SDK}" MATCHES "(OSX|IOS*|TVOS*|WATCHOS*)") set(SWIFT_HOST_VARIANT "macosx" CACHE STRING diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 67ce1590cbc82..ea81d878c0ced 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -25,6 +25,7 @@ #include "swift/Basic/OptimizationMode.h" #include "swift/Config.h" #include "clang/Basic/PointerAuthOptions.h" +#include "llvm/IR/CallingConv.h" // FIXME: This include is just for llvm::SanitizerCoverageOptions. We should // split the header upstream so we don't include so much. #include "llvm/Transforms/Instrumentation.h" @@ -477,6 +478,9 @@ class IRGenOptions { /// function instead of to trap instructions. std::string TrapFuncName = ""; + /// The calling convention used to perform non-swift calls. + llvm::CallingConv::ID PlatformCCallingConvention; + IRGenOptions() : DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssemblyAfterOptimization), @@ -517,7 +521,8 @@ class IRGenOptions { ColocateTypeDescriptors(true), UseRelativeProtocolWitnessTables(false), CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()), - TypeInfoFilter(TypeInfoDumpFilter::All) { + TypeInfoFilter(TypeInfoDumpFilter::All), + PlatformCCallingConvention(llvm::CallingConv::C) { #ifndef NDEBUG DisableRoundTripDebugTypes = false; #else diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 8e8ed8d5b46bb..b88be4acad09a 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -1224,4 +1224,12 @@ def experimental_spi_only_imports : def enable_ossa_complete_lifetimes : Flag<["-"], "enable-ossa-complete-lifetimes">, HelpText<"Require linear OSSA lifetimes after SILGen">; + +def platform_c_calling_convention : + Separate<["-"], "experimental-platform-c-calling-convention">, + HelpText<"Which calling convention is used to perform non-swift calls. " + "Defaults to llvm's standard C calling convention.">; +def platform_c_calling_convention_EQ : + Joined<["-"], "experimental-platform-c-calling-convention=">, + Alias; } // end let Flags = [FrontendOption, NoDriverOption, HelpHidden] diff --git a/include/swift/Sema/Constraint.h b/include/swift/Sema/Constraint.h index 54e780d2c7a0f..5e7b688d38662 100644 --- a/include/swift/Sema/Constraint.h +++ b/include/swift/Sema/Constraint.h @@ -186,14 +186,12 @@ enum class ConstraintKind : char { /// constraint. OneWayBindParam, /// If there is no contextual info e.g. `_ = { 42 }` default first type - /// to a second type (inferred closure type). This is effectively a - /// `Defaultable` constraint which a couple of differences: + /// to a second type. This is effectively a `Defaultable` constraint + /// which one significant difference: /// - /// - References inferred closure type and all of the outer parameters - /// referenced by closure body. /// - Handled specially by binding inference, specifically contributes /// to the bindings only if there are no contextual types available. - DefaultClosureType, + FallbackType, /// The first type represents a result of an unresolved member chain, /// and the second type is its base type. This constraint acts almost /// like `Equal` but also enforces following semantics: @@ -701,7 +699,7 @@ class Constraint final : public llvm::ilist_node, case ConstraintKind::OptionalObject: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PackElementOf: case ConstraintKind::SameShape: diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index ecb534937af80..2b83ee8eee5a5 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -4852,11 +4852,12 @@ class ConstraintSystem { TypeMatchOptions flags, ConstraintLocatorBuilder locator); - /// Attempt to simplify the given defaultable closure type constraint. - SolutionKind simplifyDefaultClosureTypeConstraint( - Type closureType, Type inferredType, - ArrayRef referencedOuterParameters, - TypeMatchOptions flags, ConstraintLocatorBuilder locator); + /// Attempt to simplify the given fallback type constraint. + SolutionKind + simplifyFallbackTypeConstraint(Type defaultableType, Type fallbackType, + ArrayRef referencedVars, + TypeMatchOptions flags, + ConstraintLocatorBuilder locator); /// Attempt to simplify a property wrapper constraint. SolutionKind simplifyPropertyWrapperConstraint(Type wrapperType, Type wrappedValueType, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 7e4aa57a3c54b..c3182dffc347a 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2807,6 +2807,16 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, return true; } + if (const Arg *A = Args.getLastArg(options::OPT_platform_c_calling_convention)) { + Opts.PlatformCCallingConvention = + llvm::StringSwitch(A->getValue()) + .Case("c", llvm::CallingConv::C) + .Case("arm_apcs", llvm::CallingConv::ARM_APCS) + .Case("arm_aapcs", llvm::CallingConv::ARM_AAPCS) + .Case("arm_aapcs_vfp", llvm::CallingConv::ARM_AAPCS_VFP) + .Default(llvm::CallingConv::C); + } + return false; } diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 16fa1bc9e3a39..508fd5f0d1b4e 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -322,7 +322,7 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM, case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::Block: - return llvm::CallingConv::C; + return IGM.getOptions().PlatformCCallingConvention; case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 12c162da37288..cda017bc94115 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -3297,7 +3297,7 @@ llvm::Constant *swift::irgen::emitCXXConstructorThunkIfNeeded( llvm::Function *thunk = llvm::Function::Create( assumedFnType, llvm::Function::PrivateLinkage, name, &IGM.Module); - thunk->setCallingConv(llvm::CallingConv::C); + thunk->setCallingConv(IGM.getOptions().PlatformCCallingConvention); llvm::AttrBuilder attrBuilder(IGM.getLLVMContext()); IGM.constructInitialFnAttributes(attrBuilder); diff --git a/lib/IRGen/GenHeap.cpp b/lib/IRGen/GenHeap.cpp index fd6b761dd9e2c..b9657b1955eab 100644 --- a/lib/IRGen/GenHeap.cpp +++ b/lib/IRGen/GenHeap.cpp @@ -1978,7 +1978,7 @@ emitHeapMetadataRefForUnknownHeapObject(IRGenFunction &IGF, auto metadata = IGF.Builder.CreateCall( IGF.IGM.getGetObjectClassFunctionPointer(), object); metadata->setName(object->getName() + ".Type"); - metadata->setCallingConv(llvm::CallingConv::C); + metadata->setCallingConv(IGF.IGM.getOptions().PlatformCCallingConvention); metadata->setDoesNotThrow(); metadata->addFnAttr(llvm::Attribute::ReadOnly); return metadata; diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 970a555997210..1e01dfdcbb021 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -570,7 +570,7 @@ IRGenModule::IRGenModule(IRGenerator &irgen, InvariantNode = llvm::MDNode::get(getLLVMContext(), {}); DereferenceableID = getLLVMContext().getMDKindID("dereferenceable"); - C_CC = llvm::CallingConv::C; + C_CC = getOptions().PlatformCCallingConvention; // TODO: use "tinycc" on platforms that support it DefaultCC = SWIFT_DEFAULT_LLVM_CC; SwiftCC = llvm::CallingConv::Swift; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index ce8131c75c479..cd9f82adf4ccc 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1664,19 +1664,35 @@ ParserResult Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { } case tok::identifier: // foo - case tok::kw_self: // self - + case tok::kw_self: { // self + auto canParseBindingInPattern = [&]() { + if (InBindingPattern != PatternBindingState::ImplicitlyImmutable && + !InBindingPattern.getIntroducer().hasValue()) { + return false; + } + // If we have "case let x.", "case let x(", or "case let x[", we parse 'x' + // as a normal name, not a binding, because it is the start of an enum + // pattern, call, or subscript. + if (peekToken().isAny(tok::period, tok::period_prefix, tok::l_paren, + tok::l_square)) { + return false; + } + // If we have a generic argument list, this is something like + // "case let E.e(y)", and 'E' should be parsed as a normal name, not + // a binding. + if (peekToken().isAnyOperator() && peekToken().getText().equals("<")) { + BacktrackingScope S(*this); + consumeToken(); + return !canParseAsGenericArgumentList(); + } + return true; + }(); // If we are parsing a refutable pattern and are inside a let/var pattern, // the identifiers change to be value bindings instead of decl references. // Parse and return this as an UnresolvedPatternExpr around a binding. This // will be resolved (or rejected) by sema when the overall refutable pattern // it transformed from an expression into a pattern. - if ((InBindingPattern == PatternBindingState::ImplicitlyImmutable || - InBindingPattern.getIntroducer().hasValue()) && - // If we have "case let x." or "case let x(", we parse x as a normal - // name, not a binding, because it is the start of an enum pattern or - // call pattern. - peekToken().isNot(tok::period, tok::period_prefix, tok::l_paren)) { + if (canParseBindingInPattern) { Identifier name; SourceLoc loc = consumeIdentifier(name, /*diagnoseDollarPrefix=*/false); // If we have an inout/let/var, set that as our introducer. otherwise @@ -1710,6 +1726,7 @@ ParserResult Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { } LLVM_FALLTHROUGH; + } case tok::kw_Self: // Self return parseExprIdentifier(); diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index 2b628a59a27f0..f28dc7bbe85ce 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -452,7 +452,7 @@ void BindingSet::inferTransitiveBindings( // Infer transitive defaults. for (const auto &def : bindings.Defaults) { - if (def.getSecond()->getKind() == ConstraintKind::DefaultClosureType) + if (def.getSecond()->getKind() == ConstraintKind::FallbackType) continue; addDefault(def.second); @@ -1510,7 +1510,7 @@ void PotentialBindings::infer(Constraint *constraint) { } case ConstraintKind::Defaultable: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: // Do these in a separate pass. if (CS.getFixedTypeRecursive(constraint->getFirstType(), true) ->getAs() == TypeVar) { @@ -1634,7 +1634,7 @@ void PotentialBindings::retract(Constraint *constraint) { break; case ConstraintKind::Defaultable: - case ConstraintKind::DefaultClosureType: { + case ConstraintKind::FallbackType: { Defaults.erase(constraint); break; } @@ -2075,11 +2075,10 @@ bool TypeVarBindingProducer::computeNext() { if (NumTries == 0) { // Add defaultable constraints (if any). for (auto *constraint : DelayedDefaults) { - if (constraint->getKind() == ConstraintKind::DefaultClosureType) { - // If there are no other possible bindings for this closure - // let's default it to the type inferred from its parameters/body, - // otherwise we should only attempt contextual types as a - // top-level closure type. + if (constraint->getKind() == ConstraintKind::FallbackType) { + // If there are no other possible bindings for this variable + // let's default it to the fallback type, otherwise we should + // only attempt contextual types. if (!ExploredTypes.empty()) continue; } diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index e950a7bdf899c..26ba896bef55e 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -2921,9 +2921,9 @@ namespace { SmallVector referencedVars{ collectVarRefs.varRefs.begin(), collectVarRefs.varRefs.end()}; - CS.addUnsolvedConstraint(Constraint::create( - CS, ConstraintKind::DefaultClosureType, closureType, inferredType, - locator, referencedVars)); + CS.addUnsolvedConstraint( + Constraint::create(CS, ConstraintKind::FallbackType, closureType, + inferredType, locator, referencedVars)); CS.setClosureType(closure, inferredType); return closureType; diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 58e2aa5d49b6c..abcd92f351384 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -2284,7 +2284,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2, case ConstraintKind::BridgingConversion: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::SyntacticElement: @@ -2643,7 +2643,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1, case ConstraintKind::ValueWitness: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::SyntacticElement: @@ -3161,7 +3161,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2, case ConstraintKind::BridgingConversion: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::SyntacticElement: @@ -6811,7 +6811,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, case ConstraintKind::ValueWitness: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::SyntacticElement: @@ -10989,18 +10989,18 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyDefaultableConstraint( return SolutionKind::Solved; } -ConstraintSystem::SolutionKind -ConstraintSystem::simplifyDefaultClosureTypeConstraint( - Type closureType, Type inferredType, - ArrayRef referencedOuterParameters, - TypeMatchOptions flags, ConstraintLocatorBuilder locator) { - closureType = getFixedTypeRecursive(closureType, flags, /*wantRValue=*/true); +ConstraintSystem::SolutionKind ConstraintSystem::simplifyFallbackTypeConstraint( + Type defaultableType, Type fallbackType, + ArrayRef referencedVars, TypeMatchOptions flags, + ConstraintLocatorBuilder locator) { + defaultableType = + getFixedTypeRecursive(defaultableType, flags, /*wantRValue=*/true); - if (closureType->isTypeVariableOrMember()) { + if (defaultableType->isTypeVariableOrMember()) { if (flags.contains(TMF_GenerateConstraints)) { addUnsolvedConstraint(Constraint::create( - *this, ConstraintKind::DefaultClosureType, closureType, inferredType, - getConstraintLocator(locator), referencedOuterParameters)); + *this, ConstraintKind::FallbackType, defaultableType, fallbackType, + getConstraintLocator(locator), referencedVars)); return SolutionKind::Solved; } @@ -15065,7 +15065,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first, case ConstraintKind::Conjunction: case ConstraintKind::KeyPath: case ConstraintKind::KeyPathApplication: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::SyntacticElement: llvm_unreachable("Use the correct addConstraint()"); } @@ -15597,12 +15597,12 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) { /*flags*/ None, constraint.getLocator()); - case ConstraintKind::DefaultClosureType: - return simplifyDefaultClosureTypeConstraint(constraint.getFirstType(), - constraint.getSecondType(), - constraint.getTypeVariables(), - /*flags*/ None, - constraint.getLocator()); + case ConstraintKind::FallbackType: + return simplifyFallbackTypeConstraint(constraint.getFirstType(), + constraint.getSecondType(), + constraint.getTypeVariables(), + /*flags*/ None, + constraint.getLocator()); case ConstraintKind::PropertyWrapper: return simplifyPropertyWrapperConstraint(constraint.getFirstType(), diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index bd8991909634c..8630e128df625 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -99,7 +99,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, llvm_unreachable("Wrong constructor for member constraint"); case ConstraintKind::Defaultable: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: assert(!First.isNull()); assert(!Second.isNull()); break; @@ -164,7 +164,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third, case ConstraintKind::Conjunction: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::SyntacticElement: @@ -314,7 +314,7 @@ Constraint *Constraint::clone(ConstraintSystem &cs) const { case ConstraintKind::Defaultable: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::BindTupleOfFunctionParams: @@ -469,8 +469,8 @@ void Constraint::print(llvm::raw_ostream &Out, SourceManager *sm, case ConstraintKind::OpenedExistentialOf: Out << " opened archetype of "; break; case ConstraintKind::OneWayEqual: Out << " one-way bind to "; break; case ConstraintKind::OneWayBindParam: Out << " one-way bind param to "; break; - case ConstraintKind::DefaultClosureType: - Out << " closure can default to "; + case ConstraintKind::FallbackType: + Out << " can fallback to "; break; case ConstraintKind::UnresolvedMemberChainBase: Out << " unresolved member chain base "; @@ -740,7 +740,7 @@ gatherReferencedTypeVars(Constraint *constraint, case ConstraintKind::SelfObjectOfProtocol: case ConstraintKind::OneWayEqual: case ConstraintKind::OneWayBindParam: - case ConstraintKind::DefaultClosureType: + case ConstraintKind::FallbackType: case ConstraintKind::UnresolvedMemberChainBase: case ConstraintKind::PropertyWrapper: case ConstraintKind::BindTupleOfFunctionParams: diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 0108b70e08f5e..792eb7adb08d4 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -1031,7 +1031,7 @@ Type ConstraintSystem::openPackExpansionType(PackExpansionType *expansion, // This constraint is important to make sure that pack expansion always // has a binding and connect pack expansion var to any type variables // that appear in pattern and shape types. - addUnsolvedConstraint(Constraint::create(*this, ConstraintKind::Defaultable, + addUnsolvedConstraint(Constraint::create(*this, ConstraintKind::FallbackType, expansionVar, openedPackExpansion, expansionLoc)); @@ -7419,7 +7419,7 @@ bool TypeVarBindingProducer::requiresOptionalAdjustment( PotentialBinding TypeVarBindingProducer::getDefaultBinding(Constraint *constraint) const { assert(constraint->getKind() == ConstraintKind::Defaultable || - constraint->getKind() == ConstraintKind::DefaultClosureType); + constraint->getKind() == ConstraintKind::FallbackType); auto type = constraint->getSecondType(); Binding binding{type, BindingKind::Exact, constraint}; diff --git a/test/Constraints/pack-expansion-expressions.swift b/test/Constraints/pack-expansion-expressions.swift index 1247a21702394..cfd58eb9d547e 100644 --- a/test/Constraints/pack-expansion-expressions.swift +++ b/test/Constraints/pack-expansion-expressions.swift @@ -562,3 +562,45 @@ func configure( repeat item[keyPath: (each configuration).0] = (each configuration).1 return item } + +// rdar://110819621 - generic parameter is bound before pack expansion type which result in inference failures +func test_that_expansions_are_bound_early() { + struct Data { + let prop: Int? + } + + struct Value { + init(_ body: (repeat each T) -> Bool) {} + } + + func compute( + root: Root, + keyPath: KeyPath, + other: Value) -> Bool { true } + + func test_keypath(v: Int) { + let _: Value = Value({ + compute( + root: $0, + keyPath: \.prop, + other: v + ) + }) // Ok + + let _: Value = Value({ + compute( + root: $0, + keyPath: \.prop, + other: v + ) + }) // Ok + } + + func equal(_: Value, _: Value) -> Bool {} + + func test_equality(i: Int) { + let _: Value = Value({ + equal($0.prop, i) // Ok + }) + } +} diff --git a/test/Constraints/rdar108738034.swift b/test/Constraints/rdar108738034.swift new file mode 100644 index 0000000000000..368eb480884b3 --- /dev/null +++ b/test/Constraints/rdar108738034.swift @@ -0,0 +1,21 @@ +// RUN: %target-typecheck-verify-swift + +// rdar://108738034: Make sure we can type-check this. +enum E: Error { + case e(T) +} + +struct S { + func bar(_: (Error?) -> Void) {} +} + +func foo(_ s: S) { + s.bar { error in + guard let error = error else { + return + } + if case let E.e(y) = error { + print(y) + } + } +} diff --git a/test/Parse/matching_patterns.swift b/test/Parse/matching_patterns.swift index 050916fac0574..2a78444f7719e 100644 --- a/test/Parse/matching_patterns.swift +++ b/test/Parse/matching_patterns.swift @@ -364,3 +364,51 @@ let (responseObject: Int?) = op1 // expected-error @-1 {{expected ',' separator}} {{25-25=,}} // expected-error @-2 {{expected pattern}} // expected-error @-3 {{cannot convert value of type 'Int?' to specified type '(responseObject: _)'}} + +enum E { + case e(T) +} + +// rdar://108738034 - Make sure we don't treat 'E' as a binding, but can treat +// 'y' as a binding +func testNonBinding1(_ x: E) -> Int { + if case let E.e(y) = x { y } else { 0 } +} + +func testNonBinding2(_ e: E) -> Int { + switch e { + case let E.e(y): + y + } +} + +// In this case, 'y' should be an identifier, but 'z' is a binding. +func testNonBinding3(_ x: (Int, Int), y: [Int]) -> Int { + if case let (y[0], z) = x { z } else { 0 } +} + +func testNonBinding4(_ x: (Int, Int), y: [Int]) -> Int { + switch x { + case let (y[0], z): + z + default: + 0 + } +} + +func testNonBinding5(_ x: Int, y: [Int]) { + // We treat 'z' here as a binding, which is invalid. + if case let y[z] = x {} // expected-error {{pattern variable binding cannot appear in an expression}} +} + +func testNonBinding6(y: [Int], z: Int) -> Int { + switch 0 { + // We treat 'z' here as a binding, which is invalid. + case let y[z]: // expected-error {{pattern variable binding cannot appear in an expression}} + z + case y[z]: // This is fine + 0 + default: + 0 + } +} diff --git a/unittests/Sema/ConstraintSimplificationTests.cpp b/unittests/Sema/ConstraintSimplificationTests.cpp index c8c3271cc815b..d596e5317fe1e 100644 --- a/unittests/Sema/ConstraintSimplificationTests.cpp +++ b/unittests/Sema/ConstraintSimplificationTests.cpp @@ -111,7 +111,7 @@ TEST_F(SemaTest, TestClosureInferenceFromOptionalContext) { auto *closureTy = cs.createTypeVariable(closureLoc, /*options=*/0); cs.addUnsolvedConstraint(Constraint::create( - cs, ConstraintKind::DefaultClosureType, closureTy, defaultTy, + cs, ConstraintKind::FallbackType, closureTy, defaultTy, cs.getConstraintLocator(closure), /*referencedVars=*/{})); auto contextualTy = diff --git a/utils/build-script-impl b/utils/build-script-impl index a8d6d44bf3c07..2d2b0671f8765 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -487,6 +487,7 @@ function verify_host_is_supported() { | watchsimulator-arm64 \ | watchos-armv7k \ | watchos-arm64_32 \ + | wasi-wasm32 \ | android-armv7 \ | android-aarch64 \ | android-x86_64 \