Skip to content

Commit 6f8a0c1

Browse files
committed
Revert "[ConstraintSystem] NFC: Remove obsolete ValueWitness constraint"
This reverts commit ef0523f.
1 parent e7f6dc8 commit 6f8a0c1

File tree

5 files changed

+194
-9
lines changed

5 files changed

+194
-9
lines changed

include/swift/Sema/Constraint.h

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ enum class ConstraintKind : char {
137137
/// name, and the type of that member, when referenced as a value, is the
138138
/// second type.
139139
UnresolvedValueMember,
140+
/// The first type conforms to the protocol in which the member requirement
141+
/// resides. Once the conformance is resolved, the value witness will be
142+
/// determined, and the type of that witness, when referenced as a value,
143+
/// will be bound to the second type.
144+
ValueWitness,
140145
/// The first type can be defaulted to the second (which currently
141146
/// cannot be dependent). This is more like a type property than a
142147
/// relational constraint.
@@ -406,11 +411,18 @@ class Constraint final : public llvm::ilist_node<Constraint>,
406411
/// The type of the member.
407412
Type Second;
408413

409-
/// If non-null, the name of a member of the first type is that
410-
/// being related to the second type.
411-
///
412-
/// Used for ValueMember an UnresolvedValueMember constraints.
413-
DeclNameRef Name;
414+
union {
415+
/// If non-null, the name of a member of the first type is that
416+
/// being related to the second type.
417+
///
418+
/// Used for ValueMember an UnresolvedValueMember constraints.
419+
DeclNameRef Name;
420+
421+
/// If non-null, the member being referenced.
422+
///
423+
/// Used for ValueWitness constraints.
424+
ValueDecl *Ref;
425+
} Member;
414426

415427
/// The DC in which the use appears.
416428
DeclContext *UseDC;
@@ -525,6 +537,12 @@ class Constraint final : public llvm::ilist_node<Constraint>,
525537
FunctionRefKind functionRefKind,
526538
ConstraintLocator *locator);
527539

540+
/// Create a new value witness constraint.
541+
static Constraint *createValueWitness(
542+
ConstraintSystem &cs, ConstraintKind kind, Type first, Type second,
543+
ValueDecl *requirement, DeclContext *useDC,
544+
FunctionRefKind functionRefKind, ConstraintLocator *locator);
545+
528546
/// Create an overload-binding constraint.
529547
static Constraint *createBindOverload(ConstraintSystem &cs, Type type,
530548
OverloadChoice choice,
@@ -672,6 +690,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
672690

673691
case ConstraintKind::ValueMember:
674692
case ConstraintKind::UnresolvedValueMember:
693+
case ConstraintKind::ValueWitness:
675694
case ConstraintKind::PropertyWrapper:
676695
return ConstraintClassification::Member;
677696

@@ -711,6 +730,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
711730

712731
case ConstraintKind::ValueMember:
713732
case ConstraintKind::UnresolvedValueMember:
733+
case ConstraintKind::ValueWitness:
714734
return Member.First;
715735

716736
case ConstraintKind::SyntacticElement:
@@ -732,6 +752,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
732752

733753
case ConstraintKind::ValueMember:
734754
case ConstraintKind::UnresolvedValueMember:
755+
case ConstraintKind::ValueWitness:
735756
return Member.Second;
736757

737758
default:
@@ -757,13 +778,20 @@ class Constraint final : public llvm::ilist_node<Constraint>,
757778
DeclNameRef getMember() const {
758779
assert(Kind == ConstraintKind::ValueMember ||
759780
Kind == ConstraintKind::UnresolvedValueMember);
760-
return Member.Name;
781+
return Member.Member.Name;
782+
}
783+
784+
/// Retrieve the requirement being referenced by a value witness constraint.
785+
ValueDecl *getRequirement() const {
786+
assert(Kind == ConstraintKind::ValueWitness);
787+
return Member.Member.Ref;
761788
}
762789

763790
/// Determine the kind of function reference we have for a member reference.
764791
FunctionRefKind getFunctionRefKind() const {
765792
if (Kind == ConstraintKind::ValueMember ||
766-
Kind == ConstraintKind::UnresolvedValueMember)
793+
Kind == ConstraintKind::UnresolvedValueMember ||
794+
Kind == ConstraintKind::ValueWitness)
767795
return static_cast<FunctionRefKind>(TheFunctionRefKind);
768796

769797
// Conservative answer: drop all of the labels.
@@ -823,7 +851,8 @@ class Constraint final : public llvm::ilist_node<Constraint>,
823851
/// Retrieve the DC in which the member was used.
824852
DeclContext *getMemberUseDC() const {
825853
assert(Kind == ConstraintKind::ValueMember ||
826-
Kind == ConstraintKind::UnresolvedValueMember);
854+
Kind == ConstraintKind::UnresolvedValueMember ||
855+
Kind == ConstraintKind::ValueWitness);
827856
return Member.UseDC;
828857
}
829858

include/swift/Sema/ConstraintSystem.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4083,6 +4083,26 @@ class ConstraintSystem {
40834083
}
40844084
}
40854085

4086+
/// Add a value witness constraint to the constraint system.
4087+
void addValueWitnessConstraint(
4088+
Type baseTy, ValueDecl *requirement, Type memberTy, DeclContext *useDC,
4089+
FunctionRefKind functionRefKind, ConstraintLocatorBuilder locator) {
4090+
assert(baseTy);
4091+
assert(memberTy);
4092+
assert(requirement);
4093+
assert(useDC);
4094+
switch (simplifyValueWitnessConstraint(
4095+
ConstraintKind::ValueWitness, baseTy, requirement, memberTy, useDC,
4096+
functionRefKind, TMF_GenerateConstraints, locator)) {
4097+
case SolutionKind::Unsolved:
4098+
llvm_unreachable("Unsolved result when generating constraints!");
4099+
4100+
case SolutionKind::Solved:
4101+
case SolutionKind::Error:
4102+
break;
4103+
}
4104+
}
4105+
40864106
/// Add an explicit conversion constraint (e.g., \c 'x as T').
40874107
///
40884108
/// \param fromType The type of the expression being converted.

lib/Sema/CSBindings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,7 @@ void PotentialBindings::infer(Constraint *constraint) {
14671467

14681468
case ConstraintKind::ValueMember:
14691469
case ConstraintKind::UnresolvedValueMember:
1470+
case ConstraintKind::ValueWitness:
14701471
case ConstraintKind::PropertyWrapper: {
14711472
// If current type variable represents a member type of some reference,
14721473
// it would be bound once member is resolved either to a actual member

lib/Sema/CSSimplify.cpp

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
22432243
case ConstraintKind::SelfObjectOfProtocol:
22442244
case ConstraintKind::UnresolvedValueMember:
22452245
case ConstraintKind::ValueMember:
2246+
case ConstraintKind::ValueWitness:
22462247
case ConstraintKind::BridgingConversion:
22472248
case ConstraintKind::OneWayEqual:
22482249
case ConstraintKind::OneWayBindParam:
@@ -2406,6 +2407,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
24062407
case ConstraintKind::SelfObjectOfProtocol:
24072408
case ConstraintKind::UnresolvedValueMember:
24082409
case ConstraintKind::ValueMember:
2410+
case ConstraintKind::ValueWitness:
24092411
case ConstraintKind::OneWayEqual:
24102412
case ConstraintKind::OneWayBindParam:
24112413
case ConstraintKind::DefaultClosureType:
@@ -2863,6 +2865,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
28632865
case ConstraintKind::SelfObjectOfProtocol:
28642866
case ConstraintKind::UnresolvedValueMember:
28652867
case ConstraintKind::ValueMember:
2868+
case ConstraintKind::ValueWitness:
28662869
case ConstraintKind::BridgingConversion:
28672870
case ConstraintKind::OneWayEqual:
28682871
case ConstraintKind::OneWayBindParam:
@@ -6150,6 +6153,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
61506153
case ConstraintKind::SelfObjectOfProtocol:
61516154
case ConstraintKind::UnresolvedValueMember:
61526155
case ConstraintKind::ValueMember:
6156+
case ConstraintKind::ValueWitness:
61536157
case ConstraintKind::OneWayEqual:
61546158
case ConstraintKind::OneWayBindParam:
61556159
case ConstraintKind::DefaultClosureType:
@@ -9246,7 +9250,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
92469250
markMemberTypeAsPotentialHole(memberTy);
92479251
return SolutionKind::Solved;
92489252
}
9249-
} else if (kind == ConstraintKind::ValueMember &&
9253+
} else if ((kind == ConstraintKind::ValueMember ||
9254+
kind == ConstraintKind::ValueWitness) &&
92509255
baseObjTy->getMetatypeInstanceType()->isPlaceholder()) {
92519256
// If base type is a "hole" there is no reason to record any
92529257
// more "member not found" fixes for chained member references.
@@ -9668,6 +9673,67 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
96689673
return SolutionKind::Error;
96699674
}
96709675

9676+
ConstraintSystem::SolutionKind
9677+
ConstraintSystem::simplifyValueWitnessConstraint(
9678+
ConstraintKind kind, Type baseType, ValueDecl *requirement, Type memberType,
9679+
DeclContext *useDC, FunctionRefKind functionRefKind,
9680+
TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
9681+
// We'd need to record original base type because it might be a type
9682+
// variable representing another missing member.
9683+
auto origBaseType = baseType;
9684+
9685+
auto formUnsolved = [&] {
9686+
// If requested, generate a constraint.
9687+
if (flags.contains(TMF_GenerateConstraints)) {
9688+
auto *witnessConstraint = Constraint::createValueWitness(
9689+
*this, kind, origBaseType, memberType, requirement, useDC,
9690+
functionRefKind, getConstraintLocator(locator));
9691+
9692+
addUnsolvedConstraint(witnessConstraint);
9693+
return SolutionKind::Solved;
9694+
}
9695+
9696+
return SolutionKind::Unsolved;
9697+
};
9698+
9699+
// Resolve the base type, if we can. If we can't resolve the base type,
9700+
// then we can't solve this constraint.
9701+
Type baseObjectType = getFixedTypeRecursive(
9702+
baseType, flags, /*wantRValue=*/true);
9703+
if (baseObjectType->isTypeVariableOrMember()) {
9704+
return formUnsolved();
9705+
}
9706+
9707+
// Check conformance to the protocol. If it doesn't conform, this constraint
9708+
// fails. Don't attempt to fix it.
9709+
// FIXME: Look in the constraint system to see if we've resolved the
9710+
// conformance already?
9711+
auto proto = requirement->getDeclContext()->getSelfProtocolDecl();
9712+
assert(proto && "Value witness constraint for a non-requirement");
9713+
auto conformance = useDC->getParentModule()->lookupConformance(
9714+
baseObjectType, proto);
9715+
if (!conformance) {
9716+
// The conformance failed, so mark the member type as a "hole". We cannot
9717+
// do anything further here.
9718+
if (!shouldAttemptFixes())
9719+
return SolutionKind::Error;
9720+
9721+
recordAnyTypeVarAsPotentialHole(memberType);
9722+
9723+
return SolutionKind::Solved;
9724+
}
9725+
9726+
// Reference the requirement.
9727+
Type resolvedBaseType = simplifyType(baseType, flags);
9728+
if (resolvedBaseType->isTypeVariableOrMember())
9729+
return formUnsolved();
9730+
9731+
auto choice = OverloadChoice(resolvedBaseType, requirement, functionRefKind);
9732+
resolveOverload(getConstraintLocator(locator), memberType, choice,
9733+
useDC);
9734+
return SolutionKind::Solved;
9735+
}
9736+
96719737
ConstraintSystem::SolutionKind ConstraintSystem::simplifyDefaultableConstraint(
96729738
Type first, Type second, TypeMatchOptions flags,
96739739
ConstraintLocatorBuilder locator) {
@@ -13334,6 +13400,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1333413400

1333513401
case ConstraintKind::ValueMember:
1333613402
case ConstraintKind::UnresolvedValueMember:
13403+
case ConstraintKind::ValueWitness:
1333713404
case ConstraintKind::BindOverload:
1333813405
case ConstraintKind::Disjunction:
1333913406
case ConstraintKind::Conjunction:
@@ -13824,6 +13891,16 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1382413891
/*outerAlternatives=*/{},
1382513892
/*flags*/ None, constraint.getLocator());
1382613893

13894+
case ConstraintKind::ValueWitness:
13895+
return simplifyValueWitnessConstraint(constraint.getKind(),
13896+
constraint.getFirstType(),
13897+
constraint.getRequirement(),
13898+
constraint.getSecondType(),
13899+
constraint.getMemberUseDC(),
13900+
constraint.getFunctionRefKind(),
13901+
/*flags*/ None,
13902+
constraint.getLocator());
13903+
1382713904
case ConstraintKind::Defaultable:
1382813905
return simplifyDefaultableConstraint(constraint.getFirstType(),
1382913906
constraint.getSecondType(),

lib/Sema/Constraint.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
9090

9191
case ConstraintKind::ValueMember:
9292
case ConstraintKind::UnresolvedValueMember:
93+
case ConstraintKind::ValueWitness:
9394
llvm_unreachable("Wrong constructor for member constraint");
9495

9596
case ConstraintKind::Defaultable:
@@ -149,6 +150,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third,
149150
case ConstraintKind::ApplicableFunction:
150151
case ConstraintKind::DynamicCallableApplicableFunction:
151152
case ConstraintKind::ValueMember:
153+
case ConstraintKind::ValueWitness:
152154
case ConstraintKind::UnresolvedValueMember:
153155
case ConstraintKind::Defaultable:
154156
case ConstraintKind::BindOverload:
@@ -195,6 +197,28 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second,
195197
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
196198
}
197199

200+
Constraint::Constraint(ConstraintKind kind, Type first, Type second,
201+
ValueDecl *requirement, DeclContext *useDC,
202+
FunctionRefKind functionRefKind,
203+
ConstraintLocator *locator,
204+
SmallPtrSetImpl<TypeVariableType *> &typeVars)
205+
: Kind(kind), HasRestriction(false), IsActive(false), IsDisabled(false),
206+
IsDisabledForPerformance(false), RememberChoice(false), IsFavored(false),
207+
IsIsolated(false), NumTypeVariables(typeVars.size()), Locator(locator) {
208+
Member.First = first;
209+
Member.Second = second;
210+
Member.Member.Ref = requirement;
211+
Member.UseDC = useDC;
212+
TheFunctionRefKind = static_cast<unsigned>(functionRefKind);
213+
214+
assert(kind == ConstraintKind::ValueWitness);
215+
assert(getFunctionRefKind() == functionRefKind);
216+
assert(requirement && "Value witness constraint has no requirement");
217+
assert(useDC && "Member constraint has no use DC");
218+
219+
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
220+
}
221+
198222
Constraint::Constraint(Type type, OverloadChoice choice, DeclContext *useDC,
199223
ConstraintFix *fix, ConstraintLocator *locator,
200224
SmallPtrSetImpl<TypeVariableType *> &typeVars)
@@ -300,6 +324,11 @@ Constraint *Constraint::clone(ConstraintSystem &cs) const {
300324
getMember(), getMemberUseDC(), getFunctionRefKind(),
301325
getLocator());
302326

327+
case ConstraintKind::ValueWitness:
328+
return createValueWitness(
329+
cs, getKind(), getFirstType(), getSecondType(), getRequirement(),
330+
getMemberUseDC(), getFunctionRefKind(), getLocator());
331+
303332
case ConstraintKind::Disjunction:
304333
return createDisjunction(
305334
cs, getNestedConstraints(), getLocator(),
@@ -480,6 +509,14 @@ void Constraint::print(llvm::raw_ostream &Out, SourceManager *sm) const {
480509
Out << "[(implicit) ." << getMember() << ": value] == ";
481510
break;
482511

512+
case ConstraintKind::ValueWitness: {
513+
auto requirement = getRequirement();
514+
auto selfNominal = requirement->getDeclContext()->getSelfNominalTypeDecl();
515+
Out << "[." << selfNominal->getName() << "::" << requirement->getName()
516+
<< ": witness] == ";
517+
break;
518+
}
519+
483520
case ConstraintKind::Defaultable:
484521
Out << " can default to ";
485522
break;
@@ -637,6 +674,7 @@ gatherReferencedTypeVars(Constraint *constraint,
637674
case ConstraintKind::Subtype:
638675
case ConstraintKind::UnresolvedValueMember:
639676
case ConstraintKind::ValueMember:
677+
case ConstraintKind::ValueWitness:
640678
case ConstraintKind::DynamicTypeOf:
641679
case ConstraintKind::EscapableFunctionOf:
642680
case ConstraintKind::OpenedExistentialOf:
@@ -782,6 +820,26 @@ Constraint *Constraint::createMember(ConstraintSystem &cs, ConstraintKind kind,
782820
functionRefKind, locator, typeVars);
783821
}
784822

823+
Constraint *Constraint::createValueWitness(
824+
ConstraintSystem &cs, ConstraintKind kind, Type first, Type second,
825+
ValueDecl *requirement, DeclContext *useDC,
826+
FunctionRefKind functionRefKind, ConstraintLocator *locator) {
827+
assert(kind == ConstraintKind::ValueWitness);
828+
829+
// Collect type variables.
830+
SmallPtrSet<TypeVariableType *, 4> typeVars;
831+
if (first->hasTypeVariable())
832+
first->getTypeVariables(typeVars);
833+
if (second->hasTypeVariable())
834+
second->getTypeVariables(typeVars);
835+
836+
// Create the constraint.
837+
unsigned size = totalSizeToAlloc<TypeVariableType*>(typeVars.size());
838+
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
839+
return new (mem) Constraint(kind, first, second, requirement, useDC,
840+
functionRefKind, locator, typeVars);
841+
}
842+
785843
Constraint *Constraint::createBindOverload(ConstraintSystem &cs, Type type,
786844
OverloadChoice choice,
787845
DeclContext *useDC,

0 commit comments

Comments
 (0)