Skip to content

Commit 4fc9f59

Browse files
authored
Merge pull request #1173 from swiftwasm/master
[pull] swiftwasm from master
2 parents 4a1fe52 + 62b2570 commit 4fc9f59

24 files changed

+385
-45
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,10 @@ namespace swift {
549549
/// Enable constraint solver support for experimental
550550
/// operator protocol designator feature.
551551
bool SolverEnableOperatorDesignatedTypes = false;
552-
552+
553+
/// Enable experimental support for one-way constraints for the
554+
/// parameters of closures.
555+
bool EnableOneWayClosureParameters = false;
553556
};
554557
} // end namespace swift
555558

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ def experimental_print_full_convention :
642642
HelpText<"When emitting a module interface, emit additional @convention "
643643
"arguments, regardless of whether they were written in the source">;
644644

645+
def experimental_one_way_closure_params :
646+
Flag<["-"], "experimental-one-way-closure-params">,
647+
HelpText<"Enable experimental support for one-way closure parameters">;
648+
645649
def prebuilt_module_cache_path :
646650
Separate<["-"], "prebuilt-module-cache-path">,
647651
HelpText<"Directory of prebuilt modules for loading module interfaces">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,8 @@ static bool ParseTypeCheckerArgs(TypeCheckerOptions &Opts, ArgList &Args,
711711

712712
Opts.SolverEnableOperatorDesignatedTypes |=
713713
Args.hasArg(OPT_solver_enable_operator_designated_types);
714+
Opts.EnableOneWayClosureParameters |=
715+
Args.hasArg(OPT_experimental_one_way_closure_params);
714716

715717
Opts.DebugConstraintSolver |= Args.hasArg(OPT_debug_constraints);
716718
Opts.DebugGenericSignatures |= Args.hasArg(OPT_debug_generic_signatures);

lib/Sema/BuilderTransform.cpp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -269,26 +269,12 @@ class BuilderClosureVisitor
269269
return;
270270
}
271271

272-
// If we aren't generating constraints, there's nothing to do.
273-
if (!cs)
274-
return;
275-
276-
/// Generate constraints for each pattern binding entry
277-
for (unsigned index : range(patternBinding->getNumPatternEntries())) {
278-
// Type check the pattern.
279-
auto pattern = patternBinding->getPattern(index);
280-
auto contextualPattern = ContextualPattern::forRawPattern(pattern, dc);
281-
Type patternType = TypeChecker::typeCheckPattern(contextualPattern);
282-
283-
// Generate constraints for the initialization.
284-
auto target = SolutionApplicationTarget::forInitialization(
285-
patternBinding->getInit(index), dc, patternType, pattern,
286-
/*bindPatternVarsOneWay=*/true);
272+
// If there is a constraint system, generate constraints for the pattern
273+
// binding.
274+
if (cs) {
275+
SolutionApplicationTarget target(patternBinding);
287276
if (cs->generateConstraints(target, FreeTypeVariableBinding::Disallow))
288-
continue;
289-
290-
// Keep track of this binding entry.
291-
applied.patternBindingEntries.insert({{patternBinding, index}, target});
277+
hadError = true;
292278
}
293279
}
294280

@@ -1035,11 +1021,11 @@ class BuilderClosureRewriter
10351021
for (unsigned index : range(patternBinding->getNumPatternEntries())) {
10361022
// Find the solution application target for this.
10371023
auto knownTarget =
1038-
builderTransform.patternBindingEntries.find({patternBinding, index});
1039-
assert(knownTarget != builderTransform.patternBindingEntries.end());
1024+
*solution.getConstraintSystem().getSolutionApplicationTarget(
1025+
{patternBinding, index});
10401026

10411027
// Rewrite the target.
1042-
auto resultTarget = rewriteTarget(knownTarget->second);
1028+
auto resultTarget = rewriteTarget(knownTarget);
10431029
if (!resultTarget)
10441030
continue;
10451031

lib/Sema/CSApply.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8103,6 +8103,25 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
81038103
solution.setExprTypes(guardExpr);
81048104
}
81058105

8106+
return target;
8107+
} else if (auto patternBinding = target.getAsPatternBinding()) {
8108+
ConstraintSystem &cs = solution.getConstraintSystem();
8109+
for (unsigned index : range(patternBinding->getNumPatternEntries())) {
8110+
// Find the solution application target for this.
8111+
auto knownTarget = *cs.getSolutionApplicationTarget(
8112+
{patternBinding, index});
8113+
8114+
// Rewrite the target.
8115+
auto resultTarget = rewriteTarget(knownTarget);
8116+
if (!resultTarget)
8117+
return None;
8118+
8119+
patternBinding->setPattern(
8120+
index, resultTarget->getInitializationPattern(),
8121+
resultTarget->getDeclContext());
8122+
patternBinding->setInit(index, resultTarget->getAsExpr());
8123+
}
8124+
81068125
return target;
81078126
} else {
81088127
auto fn = *target.getAsFunction();
@@ -8380,6 +8399,10 @@ SolutionApplicationTarget SolutionApplicationTarget::walk(ASTWalker &walker) {
83808399
}
83818400

83828401
return *this;
8402+
8403+
case Kind::patternBinding:
8404+
return *this;
83838405
}
8406+
83848407
llvm_unreachable("invalid target kind");
83858408
}

lib/Sema/CSBindings.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,8 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
710710
}
711711
break;
712712

713-
case ConstraintKind::OneWayEqual: {
713+
case ConstraintKind::OneWayEqual:
714+
case ConstraintKind::OneWayBindParam: {
714715
// Don't produce any bindings if this type variable is on the left-hand
715716
// side of a one-way binding.
716717
auto firstType = constraint->getFirstType();

lib/Sema/CSGen.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4428,7 +4428,48 @@ bool ConstraintSystem::generateConstraints(
44284428
return false;
44294429
}
44304430

4431-
llvm_unreachable("BOOM");
4431+
switch (target.kind) {
4432+
case SolutionApplicationTarget::Kind::expression:
4433+
llvm_unreachable("Handled above");
4434+
4435+
case SolutionApplicationTarget::Kind::caseLabelItem:
4436+
case SolutionApplicationTarget::Kind::function:
4437+
case SolutionApplicationTarget::Kind::stmtCondition:
4438+
llvm_unreachable("Handled separately");
4439+
4440+
case SolutionApplicationTarget::Kind::patternBinding: {
4441+
auto patternBinding = target.getAsPatternBinding();
4442+
auto dc = target.getDeclContext();
4443+
bool hadError = false;
4444+
4445+
/// Generate constraints for each pattern binding entry
4446+
for (unsigned index : range(patternBinding->getNumPatternEntries())) {
4447+
// Type check the pattern.
4448+
auto pattern = patternBinding->getPattern(index);
4449+
auto contextualPattern = ContextualPattern::forRawPattern(pattern, dc);
4450+
Type patternType = TypeChecker::typeCheckPattern(contextualPattern);
4451+
4452+
auto init = patternBinding->getInit(index);
4453+
if (!init) {
4454+
llvm_unreachable("Unsupported pattern binding entry");
4455+
}
4456+
4457+
// Generate constraints for the initialization.
4458+
auto target = SolutionApplicationTarget::forInitialization(
4459+
init, dc, patternType, pattern,
4460+
/*bindPatternVarsOneWay=*/true);
4461+
if (generateConstraints(target, FreeTypeVariableBinding::Disallow)) {
4462+
hadError = true;
4463+
continue;
4464+
}
4465+
4466+
// Keep track of this binding entry.
4467+
setSolutionApplicationTarget({patternBinding, index}, target);
4468+
}
4469+
4470+
return hadError;
4471+
}
4472+
}
44324473
}
44334474

44344475
Expr *ConstraintSystem::generateConstraints(

lib/Sema/CSSimplify.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
13221322
case ConstraintKind::FunctionInput:
13231323
case ConstraintKind::FunctionResult:
13241324
case ConstraintKind::OneWayEqual:
1325+
case ConstraintKind::OneWayBindParam:
13251326
case ConstraintKind::DefaultClosureType:
13261327
llvm_unreachable("Not a conversion");
13271328
}
@@ -1387,6 +1388,7 @@ static bool matchFunctionRepresentations(FunctionTypeRepresentation rep1,
13871388
case ConstraintKind::FunctionInput:
13881389
case ConstraintKind::FunctionResult:
13891390
case ConstraintKind::OneWayEqual:
1391+
case ConstraintKind::OneWayBindParam:
13901392
case ConstraintKind::DefaultClosureType:
13911393
return false;
13921394
}
@@ -1699,6 +1701,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
16991701
case ConstraintKind::FunctionInput:
17001702
case ConstraintKind::FunctionResult:
17011703
case ConstraintKind::OneWayEqual:
1704+
case ConstraintKind::OneWayBindParam:
17021705
case ConstraintKind::DefaultClosureType:
17031706
llvm_unreachable("Not a relational constraint");
17041707
}
@@ -4406,6 +4409,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
44064409
case ConstraintKind::FunctionInput:
44074410
case ConstraintKind::FunctionResult:
44084411
case ConstraintKind::OneWayEqual:
4412+
case ConstraintKind::OneWayBindParam:
44094413
case ConstraintKind::DefaultClosureType:
44104414
llvm_unreachable("Not a relational constraint");
44114415
}
@@ -7121,9 +7125,16 @@ ConstraintSystem::simplifyOneWayConstraint(
71217125
return SolutionKind::Solved;
71227126
}
71237127

7124-
// Translate this constraint into a one-way binding constraint.
7125-
return matchTypes(first, secondSimplified, ConstraintKind::Equal, flags,
7126-
locator);
7128+
// Translate this constraint into an equality or bind-parameter constraint,
7129+
// as appropriate.
7130+
if (kind == ConstraintKind::OneWayEqual) {
7131+
return matchTypes(first, secondSimplified, ConstraintKind::Equal, flags,
7132+
locator);
7133+
}
7134+
7135+
assert(kind == ConstraintKind::OneWayBindParam);
7136+
return matchTypes(
7137+
secondSimplified, first, ConstraintKind::BindParam, flags, locator);
71277138
}
71287139

71297140
static Type getFunctionBuilderTypeFor(ConstraintSystem &cs, unsigned paramIdx,
@@ -7175,12 +7186,27 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71757186

71767187
Type internalType;
71777188

7189+
bool oneWayConstraints =
7190+
getASTContext().TypeCheckerOpts.EnableOneWayClosureParameters;
71787191
if (paramList->get(i)->getTypeRepr()) {
71797192
// Internal type is the type used in the body of the closure,
71807193
// so "external" type translates to it as follows:
71817194
// - `Int...` -> `[Int]`,
71827195
// - `inout Int` -> `@lvalue Int`.
71837196
internalType = param.getParameterType();
7197+
7198+
// When there are type variables in the type and we have enabled
7199+
// one-way constraints, create a fresh type variable to handle the
7200+
// binding.
7201+
if (oneWayConstraints && internalType->hasTypeVariable()) {
7202+
auto *paramLoc =
7203+
getConstraintLocator(closure, LocatorPathElt::TupleElement(i));
7204+
auto *typeVar = createTypeVariable(paramLoc, TVO_CanBindToLValue |
7205+
TVO_CanBindToNoEscape);
7206+
addConstraint(
7207+
ConstraintKind::OneWayBindParam, typeVar, internalType, paramLoc);
7208+
internalType = typeVar;
7209+
}
71847210
} else {
71857211
auto *paramLoc =
71867212
getConstraintLocator(closure, LocatorPathElt::TupleElement(i));
@@ -7194,7 +7220,13 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
71947220
param.isVariadic() ? ArraySliceType::get(typeVar) : Type(typeVar);
71957221

71967222
auto externalType = param.getOldType();
7197-
addConstraint(ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7223+
if (oneWayConstraints) {
7224+
addConstraint(
7225+
ConstraintKind::OneWayBindParam, typeVar, externalType, paramLoc);
7226+
} else {
7227+
addConstraint(
7228+
ConstraintKind::BindParam, externalType, typeVar, paramLoc);
7229+
}
71987230
}
71997231

72007232
setType(paramList->get(i), internalType);
@@ -9759,6 +9791,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
97599791
subflags, locator);
97609792

97619793
case ConstraintKind::OneWayEqual:
9794+
case ConstraintKind::OneWayBindParam:
97629795
return simplifyOneWayConstraint(kind, first, second, subflags, locator);
97639796

97649797
case ConstraintKind::ValueMember:
@@ -10271,6 +10304,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1027110304
return SolutionKind::Unsolved;
1027210305

1027310306
case ConstraintKind::OneWayEqual:
10307+
case ConstraintKind::OneWayBindParam:
1027410308
return simplifyOneWayConstraint(constraint.getKind(),
1027510309
constraint.getFirstType(),
1027610310
constraint.getSecondType(),

lib/Sema/CSSolver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,6 +1688,7 @@ void ConstraintSystem::ArgumentInfoCollector::walk(Type argType) {
16881688
case ConstraintKind::ConformsTo:
16891689
case ConstraintKind::Defaultable:
16901690
case ConstraintKind::OneWayEqual:
1691+
case ConstraintKind::OneWayBindParam:
16911692
case ConstraintKind::DefaultClosureType:
16921693
break;
16931694
}

lib/Sema/Constraint.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
6666
case ConstraintKind::FunctionResult:
6767
case ConstraintKind::OpaqueUnderlyingType:
6868
case ConstraintKind::OneWayEqual:
69+
case ConstraintKind::OneWayBindParam:
6970
assert(!First.isNull());
7071
assert(!Second.isNull());
7172
break;
@@ -138,6 +139,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third,
138139
case ConstraintKind::FunctionResult:
139140
case ConstraintKind::OpaqueUnderlyingType:
140141
case ConstraintKind::OneWayEqual:
142+
case ConstraintKind::OneWayBindParam:
141143
case ConstraintKind::DefaultClosureType:
142144
llvm_unreachable("Wrong constructor");
143145

@@ -265,6 +267,7 @@ Constraint *Constraint::clone(ConstraintSystem &cs) const {
265267
case ConstraintKind::FunctionResult:
266268
case ConstraintKind::OpaqueUnderlyingType:
267269
case ConstraintKind::OneWayEqual:
270+
case ConstraintKind::OneWayBindParam:
268271
case ConstraintKind::DefaultClosureType:
269272
return create(cs, getKind(), getFirstType(), getSecondType(), getLocator());
270273

@@ -348,6 +351,7 @@ void Constraint::print(llvm::raw_ostream &Out, SourceManager *sm) const {
348351
case ConstraintKind::EscapableFunctionOf: Out << " @escaping type of "; break;
349352
case ConstraintKind::OpenedExistentialOf: Out << " opened archetype of "; break;
350353
case ConstraintKind::OneWayEqual: Out << " one-way bind to "; break;
354+
case ConstraintKind::OneWayBindParam: Out << " one-way bind param to "; break;
351355
case ConstraintKind::DefaultClosureType:
352356
Out << " closure can default to ";
353357
break;
@@ -564,6 +568,7 @@ gatherReferencedTypeVars(Constraint *constraint,
564568
case ConstraintKind::FunctionResult:
565569
case ConstraintKind::OpaqueUnderlyingType:
566570
case ConstraintKind::OneWayEqual:
571+
case ConstraintKind::OneWayBindParam:
567572
case ConstraintKind::DefaultClosureType:
568573
constraint->getFirstType()->getTypeVariables(typeVars);
569574
constraint->getSecondType()->getTypeVariables(typeVars);

0 commit comments

Comments
 (0)