Skip to content

Commit b9405bb

Browse files
committed
Update disjunction constraints
This sets up the type constraints as equalities with a type variable. This is apparently more performant in the solver, so that should be good. It doesn't have additional effect on the resulting behavior.
1 parent 1ed8556 commit b9405bb

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,10 +2148,11 @@ SynthesizeMainFunctionRequest::evaluate(Evaluator &evaluator,
21482148
// usual type-checking. The alternative would be to directly call
21492149
// mainType.main() from the entry point, and that would require fully
21502150
// type-checking the call to mainType.main().
2151-
2152-
constraints::ConstraintSystem CS(
2153-
declContext, constraints::ConstraintSystemFlags::IgnoreAsyncSyncMismatch);
2154-
constraints::ConstraintLocator *locator = CS.getConstraintLocator({});
2151+
using namespace constraints;
2152+
ConstraintSystem CS(declContext,
2153+
ConstraintSystemFlags::IgnoreAsyncSyncMismatch);
2154+
ConstraintLocator *locator =
2155+
CS.getConstraintLocator({}, ConstraintLocator::Member);
21552156
// Allowed main function types
21562157
// `() -> Void`
21572158
// `() async -> Void`
@@ -2196,31 +2197,35 @@ SynthesizeMainFunctionRequest::evaluate(Evaluator &evaluator,
21962197
.withGlobalActor(mainActor)
21972198
.build()));
21982199
}
2199-
2200-
llvm::SmallVector<constraints::Constraint *, 4> mainTypeConstraints;
2201-
for (const Type &mainType : mainTypes) {
2202-
constraints::Constraint *fnConstraint =
2203-
constraints::Constraint::createMember(
2204-
CS, constraints::ConstraintKind::ValueMember,
2205-
nominal->getInterfaceType(), mainType,
2206-
DeclNameRef(context.Id_main), declContext,
2207-
FunctionRefKind::SingleApply, locator);
2208-
mainTypeConstraints.push_back(fnConstraint);
2200+
TypeVariableType *mainType =
2201+
CS.createTypeVariable(locator, /*options=*/0);
2202+
llvm::SmallVector<Constraint *, 4> typeEqualityConstraints;
2203+
typeEqualityConstraints.reserve(mainTypes.size());
2204+
for (const Type &candidateMainType : mainTypes) {
2205+
typeEqualityConstraints.push_back(
2206+
Constraint::create(CS, ConstraintKind::Equal, Type(mainType),
2207+
candidateMainType, locator));
22092208
}
22102209

2211-
CS.addDisjunctionConstraint(mainTypeConstraints, locator);
2210+
CS.addDisjunctionConstraint(typeEqualityConstraints, locator);
2211+
CS.addValueMemberConstraint(
2212+
nominal->getInterfaceType(), DeclNameRef(context.Id_main),
2213+
Type(mainType), declContext, FunctionRefKind::SingleApply, {}, locator);
22122214
}
22132215

22142216
FuncDecl *mainFunction = nullptr;
2215-
llvm::SmallVector<constraints::Solution, 4> candidates;
2217+
llvm::SmallVector<Solution, 4> candidates;
22162218

22172219
if (!CS.solve(candidates, FreeTypeVariableBinding::Disallow)) {
2220+
// We can't use CS.diagnoseAmbiguity directly since the locator is empty
2221+
// Sticking the main type decl `D` in results in an assert due to a
2222+
// unsimplifiable locator anchor since it appears to be looking for an
2223+
// expression, which we don't have.
2224+
// (locator could not be simplified to anchor)
2225+
// TODO: emit notes for each of the ambiguous candidates
22182226
if (candidates.size() != 1) {
22192227
context.Diags.diagnose(nominal->getLoc(), diag::ambiguous_decl_ref,
22202228
DeclNameRef(context.Id_main));
2221-
// TODO: CS.diagnoseAmbiguity doesn't report anything because the types
2222-
// are different. It would be good to get notes on the decls causing the
2223-
// ambiguity.
22242229
attr->setInvalid();
22252230
return nullptr;
22262231
}

0 commit comments

Comments
 (0)