Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
48 changes: 4 additions & 44 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8859,17 +8859,14 @@ 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(
*this, kind, type, protocol->getDeclaredInterfaceType(),
getConstraintLocator(locator));

addUnsolvedConstraint(conformance);
if (activate)
activateConstraint(conformance);

return SolutionKind::Solved;
}

Expand Down Expand Up @@ -9243,47 +9240,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(

if (isExpr<UnresolvedMemberExpr>(anchor) &&
req->is<LocatorPathElt::TypeParameterRequirement>()) {
auto signature = path[path.size() - 2]
.castTo<LocatorPathElt::OpenedGeneric>()
.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 =
Expand Down
6 changes: 4 additions & 2 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Type, 4> 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();
Expand Down
4 changes: 2 additions & 2 deletions test/Constraints/operator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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?<S>(_ string: S) where S: StringProtocol {} // expected-note{{where 'S' = 'I60954'}}
init?<S>(_ string: S) where S: StringProtocol {}
}

infix operator <<<>>> : DefaultPrecedence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,18 @@ do {
func testSomeMarkerProto<T: SomeMarkerProto>(_: 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}}
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down