From eaa38f36d68be8dff7131ce3f37c59393f244646 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 20 Oct 2025 16:59:49 -0400 Subject: [PATCH 1/4] Sema: Fix a fuzzer crash This test case crashes when prepared overloads are disabled, but passes when enabled. To avoid messing up tests if we have to turn the flag on and off, fix the crash. --- lib/Sema/ConstraintSystem.cpp | 6 ++++-- .../Solution-getFixedType-98b9c4.swift | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/Solution-getFixedType-98b9c4.swift (82%) diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 0cc585646950d..1478599dce3d2 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -2924,8 +2924,10 @@ static bool diagnoseContextualFunctionCallGenericAmbiguity( // from all the closure contextual fix/solutions and if there are more than // one fixed type diagnose it. swift::SmallSetVector genericParamInferredTypes; - for (auto &fix : contextualFixes) - genericParamInferredTypes.insert(fix.first->getFixedType(resultTypeVar)); + for (auto &fix : contextualFixes) { + if (fix.first->hasFixedType(resultTypeVar)) + genericParamInferredTypes.insert(fix.first->getFixedType(resultTypeVar)); + } if (llvm::all_of(allFixes, [&](FixInContext fix) { auto fixLocator = fix.second->getLocator(); diff --git a/validation-test/compiler_crashers/Solution-getFixedType-98b9c4.swift b/validation-test/compiler_crashers_fixed/Solution-getFixedType-98b9c4.swift similarity index 82% rename from validation-test/compiler_crashers/Solution-getFixedType-98b9c4.swift rename to validation-test/compiler_crashers_fixed/Solution-getFixedType-98b9c4.swift index 41087feedf886..48eb1e317be4c 100644 --- a/validation-test/compiler_crashers/Solution-getFixedType-98b9c4.swift +++ b/validation-test/compiler_crashers_fixed/Solution-getFixedType-98b9c4.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::constraints::Solution::getFixedType(swift::TypeVariableType*) const","signatureAssert":"Assertion failed: (knownBinding != typeBindings.end()), function getFixedType"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s class a { static b { From 3698d16ee10bfff2832ab8c760a8b0d2f2ea7272 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 20 Oct 2025 15:08:11 -0400 Subject: [PATCH 2/4] Sema: Add a couple of passing diagnostic tests to static_members_on_protocol_in_generic_context.swift It looks like we didn't test leading dot with instance members. --- ...c_members_on_protocol_in_generic_context.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/Constraints/static_members_on_protocol_in_generic_context.swift b/test/Constraints/static_members_on_protocol_in_generic_context.swift index 7ef8a01ec0a7d..4c9f28ef4d81b 100644 --- a/test/Constraints/static_members_on_protocol_in_generic_context.swift +++ b/test/Constraints/static_members_on_protocol_in_generic_context.swift @@ -363,3 +363,18 @@ do { func testSomeMarkerProto(_: T) {} testSomeMarkerProto(.answer()) } + +// Make sure we diagnose something for instance properties as well +extension P { + var instanceProp: S { S() } +} + +extension P where Self == S { + var instanceProp2: S { S() } +} + +test(.instanceProp) +// expected-error@-1 {{instance member 'instanceProp' cannot be used on type 'P'}} +test(.instanceProp2) +// expected-error@-1 {{instance member 'instanceProp2' cannot be used on type 'P'}} +// expected-error@-2 {{property 'instanceProp2' requires the types 'Self' and 'S' be equivalent}} \ No newline at end of file From a1bbf83eeed8281f6fb80e6d53ccb7b695b41285 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 20 Oct 2025 15:09:06 -0400 Subject: [PATCH 3/4] Sema: Clean up leading dot fix logic in simplifyConformsToConstraint() Tests still pass without this code, including the tests I just added in the previous commit. --- lib/Sema/CSSimplify.cpp | 48 +++------------------------------ test/Constraints/operator.swift | 4 +-- 2 files changed, 6 insertions(+), 46 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 4cf84fecad1e8..1d2e15ad905eb 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -8859,7 +8859,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint( return SolutionKind::Solved; } - auto formUnsolved = [&](bool activate = false) { + auto formUnsolved = [&]() { // If we're supposed to generate constraints, do so. if (flags.contains(TMF_GenerateConstraints)) { auto *conformance = Constraint::create( @@ -8867,9 +8867,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint( getConstraintLocator(locator)); addUnsolvedConstraint(conformance); - if (activate) - activateConstraint(conformance); - return SolutionKind::Solved; } @@ -9243,47 +9240,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint( if (isExpr(anchor) && req->is()) { - auto signature = path[path.size() - 2] - .castTo() - .getSignature(); - auto requirement = signature.getRequirements()[req->getIndex()]; - auto *memberLoc = getConstraintLocator(anchor, path.front()); - auto overload = findSelectedOverloadFor(memberLoc); - - // To figure out what is going on here we need to wait until - // member overload is set in the constraint system. - if (!overload) { - // If it's not allowed to generate new constraints - // there is no way to control re-activation, so this - // check has to fail. - if (!flags.contains(TMF_GenerateConstraints)) - return SolutionKind::Error; - - return formUnsolved(/*activate=*/true); - } - - auto *memberRef = overload->choice.getDeclOrNull(); - if (!memberRef) - return SolutionKind::Error; - - // If this is a `Self` conformance requirement from a static member - // reference on a protocol metatype, let's produce a tailored diagnostic. - if (memberRef->isStatic()) { - if (hasFixFor(memberLoc, - FixKind::AllowInvalidStaticMemberRefOnProtocolMetatype)) - return SolutionKind::Solved; - - if (auto *protocolDecl = - memberRef->getDeclContext()->getSelfProtocolDecl()) { - auto selfTy = protocolDecl->getSelfInterfaceType(); - if (selfTy->isEqual(requirement.getFirstType())) { - auto *fix = AllowInvalidStaticMemberRefOnProtocolMetatype::create( - *this, memberLoc); - return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved; - } - } - } + auto *fix = AllowInvalidStaticMemberRefOnProtocolMetatype::create( + *this, memberLoc); + return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved; } if (auto *fix = diff --git a/test/Constraints/operator.swift b/test/Constraints/operator.swift index 5756db1978ee1..39608a4bc00d2 100644 --- a/test/Constraints/operator.swift +++ b/test/Constraints/operator.swift @@ -323,12 +323,12 @@ enum I60954 { // expected-error@+1{{operator implementation without matching operator declaration}} func ?= (pattern: I60954?, version: Self) { // expected-error{{operator '?=' declared in type 'I60954' must be 'static'}} // expected-error@+2{{operator is not a known binary operator}} - // expected-error@+1{{initializer 'init(_:)' requires that 'I60954' conform to 'StringProtocol'}} + // expected-error@+1{{contextual member reference to initializer 'init(_:)' requires 'Self' constraint in the protocol extension}} pattern ?= .init(version) // expected-error{{value of optional type 'I60954?' must be unwrapped to a value of type 'I60954'}} // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}} // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} } - init?(_ string: S) where S: StringProtocol {} // expected-note{{where 'S' = 'I60954'}} + init?(_ string: S) where S: StringProtocol {} } infix operator <<<>>> : DefaultPrecedence From b2adbc46b01c2f357e54779ac83581dc9b53facd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 17 Sep 2025 14:50:39 -0400 Subject: [PATCH 4/4] Sema: Enable prepared overloads by default This can be turned off with -solver-disable-prepared-overloads. --- include/swift/Basic/LangOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 3e89fc1062711..b84a3b4950b4d 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -1018,7 +1018,7 @@ namespace swift { bool SolverDisableSplitter = false; /// Enable the experimental "prepared overloads" optimization. - bool SolverEnablePreparedOverloads = false; + bool SolverEnablePreparedOverloads = true; }; /// Options for controlling the behavior of the Clang importer.