diff --git a/include/swift/Sema/Constraint.h b/include/swift/Sema/Constraint.h index 40b538f2c8fb9..f58d53f514f48 100644 --- a/include/swift/Sema/Constraint.h +++ b/include/swift/Sema/Constraint.h @@ -336,6 +336,8 @@ class Constraint final : public llvm::ilist_node, private llvm::TrailingObjects { friend TrailingObjects; @@ -345,9 +347,17 @@ class Constraint final : public llvm::ilist_node, /// The kind of restriction placed on this constraint. ConversionRestrictionKind Restriction : 8; - /// Whether we have a fix. + /// The number of type variables referenced by this constraint. + /// + /// The type variables themselves are tail-allocated. + unsigned NumTypeVariables : 11; + + /// Whether we have a tail-allocated fix. unsigned HasFix : 1; + /// Whether we have a tail-allocated DeclContext. + unsigned HasDeclContext : 1; + /// Whether the \c Restriction field is valid. unsigned HasRestriction : 1; @@ -375,14 +385,19 @@ class Constraint final : public llvm::ilist_node, /// the rest of the constraint system. Currently only applies to conjunctions. unsigned IsIsolated : 1; - /// The number of type variables referenced by this constraint. - /// - /// The type variables themselves are tail-allocated. - unsigned NumTypeVariables : 11; - /// The kind of function reference, for member references. unsigned TheFunctionRefInfo : 3; + /// The trailing closure matching for an applicable function constraint, + /// if any. 0 = None, 1 = Forward, 2 = Backward. + unsigned trailingClosureMatching : 2; + + /// For a SyntacticElement constraint, identify whether the result of this + /// node is unused. + unsigned isDiscarded : 1; + + // 22 bits remaining + union { struct { /// The first type. @@ -414,29 +429,19 @@ class Constraint final : public llvm::ilist_node, /// Used for ValueWitness constraints. ValueDecl *Ref; } Member; - - /// The DC in which the use appears. - DeclContext *UseDC; } Member; /// The set of constraints for a disjunction. ArrayRef Nested; struct { - /// The first type + /// The first type. Type First; - - /// The DC in which the use appears. - DeclContext *UseDC; } Overload; struct { /// The node itself. ASTNode Element; - /// Contextual information associated with the element (if any). - ContextualTypeInfo Context; - /// Identifies whether result of this node is unused. - bool IsDiscarded; } SyntacticElement; struct { @@ -447,11 +452,6 @@ class Constraint final : public llvm::ilist_node, /// The type being called, primarily a function type, but could /// be a metatype, a tuple or a nominal type. Type Callee; - /// The trailing closure matching for an applicable function constraint, - /// if any. 0 = None, 1 = Forward, 2 = Backward. - unsigned TrailingClosureMatching : 2; - /// The declaration context in which the application appears. - DeclContext *UseDC; } Apply; }; @@ -527,6 +527,14 @@ class Constraint final : public llvm::ilist_node, return HasFix ? 1 : 0; } + size_t numTrailingObjects(OverloadToken) const { + return HasDeclContext ? 1 : 0; + } + + size_t numTrailingObjects(OverloadToken) const { + return Kind == ConstraintKind::SyntacticElement ? 1 : 0; + } + size_t numTrailingObjects(OverloadToken) const { return Kind == ConstraintKind::BindOverload ? 1 : 0; } @@ -604,15 +612,15 @@ class Constraint final : public llvm::ilist_node, DeclContext *useDC, ConstraintLocator *locator); static Constraint *createSyntacticElement(ConstraintSystem &cs, - ASTNode node, - ConstraintLocator *locator, - bool isDiscarded = false); + ASTNode node, + ConstraintLocator *locator, + bool isDiscarded = false); static Constraint *createSyntacticElement(ConstraintSystem &cs, - ASTNode node, - ContextualTypeInfo context, - ConstraintLocator *locator, - bool isDiscarded = false); + ASTNode node, + ContextualTypeInfo context, + ConstraintLocator *locator, + bool isDiscarded = false); /// Determine the kind of constraint. ConstraintKind getKind() const { return Kind; } @@ -864,24 +872,10 @@ class Constraint final : public llvm::ilist_node, /// Retrieve the overload choice for an overload-binding constraint. OverloadChoice getOverloadChoice() const { - assert(Kind == ConstraintKind::BindOverload); + ASSERT(Kind == ConstraintKind::BindOverload); return *getTrailingObjects(); } - /// Retrieve the DC in which the overload was used. - DeclContext *getOverloadUseDC() const { - assert(Kind == ConstraintKind::BindOverload); - return Overload.UseDC; - } - - /// Retrieve the DC in which the member was used. - DeclContext *getMemberUseDC() const { - assert(Kind == ConstraintKind::ValueMember || - Kind == ConstraintKind::UnresolvedValueMember || - Kind == ConstraintKind::ValueWitness); - return Member.UseDC; - } - FunctionType *getAppliedFunctionType() const { assert(Kind == ConstraintKind::ApplicableFunction); return Apply.AppliedFn; @@ -892,24 +886,25 @@ class Constraint final : public llvm::ilist_node, return Apply.Callee; } - DeclContext *getApplicationDC() const { - assert(Kind == ConstraintKind::ApplicableFunction); - return Apply.UseDC; - } - ASTNode getSyntacticElement() const { assert(Kind == ConstraintKind::SyntacticElement); return SyntacticElement.Element; } ContextualTypeInfo getElementContext() const { - assert(Kind == ConstraintKind::SyntacticElement); - return SyntacticElement.Context; + ASSERT(Kind == ConstraintKind::SyntacticElement); + return *getTrailingObjects(); } bool isDiscardedElement() const { assert(Kind == ConstraintKind::SyntacticElement); - return SyntacticElement.IsDiscarded; + return isDiscarded; + } + + /// Retrieve the DC in which the overload was used. + DeclContext *getDeclContext() const { + ASSERT(HasDeclContext); + return *getTrailingObjects(); } /// For an applicable function constraint, retrieve the trailing closure diff --git a/include/swift/Sema/ConstraintSolverStats.def b/include/swift/Sema/ConstraintSolverStats.def index 6e090a1df001d..cc7f2a047e1f8 100644 --- a/include/swift/Sema/ConstraintSolverStats.def +++ b/include/swift/Sema/ConstraintSolverStats.def @@ -18,6 +18,7 @@ # error #define CS_STATISTIC(Name, Description) before including #endif +CS_STATISTIC(ASTBytesAllocated, "bytes allocated in solver arena") CS_STATISTIC(NumTypeVariablesBound, "# of type variables bound") CS_STATISTIC(NumTypeVariableBindings, "# of type variable bindings attempted") CS_STATISTIC(NumDisjunctions, "# of disjunctions explored") diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 686026851328e..9c43e5f05eae2 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -575,12 +575,6 @@ struct ASTContext::Implementation { /// The set of function types. llvm::FoldingSet FunctionTypes; - /// The set of normal protocol conformances. - llvm::FoldingSet NormalConformances; - - // The set of self protocol conformances. - llvm::DenseMap SelfConformances; - /// The set of specialized protocol conformances. llvm::FoldingSet SpecializedConformances; @@ -597,9 +591,6 @@ struct ASTContext::Implementation { /// The set of substitution maps (uniqued by their storage). llvm::FoldingSet SubstitutionMaps; - /// The set of unique AvailabilityContexts (uniqued by their storage). - llvm::FoldingSet AvailabilityContexts; - ~Arena() { for (auto &conformance : SpecializedConformances) conformance.~SpecializedProtocolConformance(); @@ -613,11 +604,6 @@ struct ASTContext::Implementation { #if SWIFT_COMPILER_IS_MSVC #pragma warning (default: 4189) #endif - - // Call the normal conformance destructors last since they could be - // referenced by the other conformance types. - for (auto &conformance : NormalConformances) - conformance.~NormalProtocolConformance(); } size_t getTotalMemory() const; @@ -645,6 +631,11 @@ struct ASTContext::Implementation { AutoDiffDerivativeFunctionIdentifiers; llvm::FoldingSet GenericSignatures; + llvm::FoldingSet NormalConformances; + llvm::DenseMap SelfConformances; + + /// The set of unique AvailabilityContexts (uniqued by their storage). + llvm::FoldingSet AvailabilityContexts; /// A cache of information about whether particular nominal types /// are representable in a foreign language. @@ -720,6 +711,9 @@ ASTContext::Implementation::Implementation() : IdentifierTable(Allocator), IntrinsicScratchContext(new llvm::LLVMContext()) {} ASTContext::Implementation::~Implementation() { + for (auto &conformance : NormalConformances) + conformance.~NormalProtocolConformance(); + for (auto &cleanup : Cleanups) cleanup(); } @@ -889,6 +883,9 @@ void ASTContext::Implementation::dump(llvm::raw_ostream &os) const { SIZE_AND_BYTES(SILMoveOnlyWrappedTypes); SIZE_AND_BYTES(BuiltinIntegerTypes); SIZE_AND_BYTES(OpenedElementEnvironments); + SIZE(NormalConformances); + SIZE(SelfConformances); + SIZE(AvailabilityContexts); SIZE_AND_BYTES(ForeignRepresentableCache); SIZE(SearchPathsSet); @@ -2912,15 +2909,14 @@ ASTContext::getNormalConformance(Type conformingType, // Did we already record the normal conformance? void *insertPos; - auto &normalConformances = - getImpl().getArena(AllocationArena::Permanent).NormalConformances; + auto &normalConformances = getImpl().NormalConformances; if (auto result = normalConformances.FindNodeOrInsertPos(id, insertPos)) return result; // Build a new normal protocol conformance. - auto result = new (*this, AllocationArena::Permanent) - NormalProtocolConformance(conformingType, protocol, loc, dc, state, - options, preconcurrencyLoc); + auto result = new (*this) NormalProtocolConformance( + conformingType, protocol, loc, dc, state, + options, preconcurrencyLoc); normalConformances.InsertNode(result, insertPos); return result; @@ -2929,12 +2925,11 @@ ASTContext::getNormalConformance(Type conformingType, /// Produce a self-conformance for the given protocol. SelfProtocolConformance * ASTContext::getSelfConformance(ProtocolDecl *protocol) { - auto &selfConformances = - getImpl().getArena(AllocationArena::Permanent).SelfConformances; + auto &selfConformances = getImpl().SelfConformances; auto &entry = selfConformances[protocol]; if (!entry) { - entry = new (*this, AllocationArena::Permanent) - SelfProtocolConformance(protocol->getDeclaredExistentialType()); + entry = new (*this) SelfProtocolConformance( + protocol->getDeclaredExistentialType()); } return entry; } @@ -3274,6 +3269,9 @@ size_t ASTContext::getTotalMemory() const { // getImpl().GenericSignatures ? // getImpl().CompoundNames ? // getImpl().IntegerTypes ? + // getImpl().NormalConformances ? + // getImpl().SelfConformances ? + // getImpl().AvailabilityContexts getImpl().Permanent.getTotalMemory(); Size += getSolverMemory(); @@ -3315,7 +3313,6 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const { // FunctionTypes ? // UnboundGenericTypes ? // BoundGenericTypes ? - // NormalConformances ? // SpecializedConformances ? // InheritedConformances ? // BuiltinConformances ? @@ -3360,14 +3357,11 @@ void ASTContext::Implementation::Arena::dump(llvm::raw_ostream &os) const { SIZE_AND_BYTES(OpaqueArchetypeEnvironments); SIZE_AND_BYTES(OpenedExistentialEnvironments); SIZE(FunctionTypes); - SIZE(NormalConformances); - SIZE(SelfConformances); SIZE(SpecializedConformances); SIZE(InheritedConformances); SIZE_AND_BYTES(BuiltinConformances); SIZE(PackConformances); SIZE(SubstitutionMaps); - SIZE(AvailabilityContexts); #undef SIZE #undef SIZE_AND_BYTES @@ -5720,8 +5714,7 @@ const AvailabilityContext::Storage *AvailabilityContext::Storage::get( AvailabilityContext::Storage::Profile(id, platformRange, isDeprecated, domainInfos); - auto &foldingSet = - ctx.getImpl().getArena(AllocationArena::Permanent).AvailabilityContexts; + auto &foldingSet = ctx.getImpl().AvailabilityContexts; void *insertPos; auto *existing = foldingSet.FindNodeOrInsertPos(id, insertPos); if (existing) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 2128e1c4240e6..233df84a30b17 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -13089,7 +13089,7 @@ bool ConstraintSystem::simplifyAppliedOverloadsImpl( // Determine the type that this choice will have. Type choiceType = getEffectiveOverloadType( constraint->getLocator(), choice, /*allowMembers=*/true, - constraint->getOverloadUseDC()); + constraint->getDeclContext()); if (!choiceType) { hasUnhandledConstraints = true; return true; @@ -16335,7 +16335,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) { return simplifyApplicableFnConstraint( constraint.getAppliedFunctionType(), constraint.getCalleeType(), constraint.getTrailingClosureMatching(), - constraint.getApplicationDC(), /*flags=*/std::nullopt, + constraint.getDeclContext(), /*flags=*/std::nullopt, constraint.getLocator()); case ConstraintKind::DynamicCallableApplicableFunction: @@ -16382,7 +16382,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) { resolveOverload(constraint.getLocator(), constraint.getFirstType(), constraint.getOverloadChoice(), - constraint.getOverloadUseDC()); + constraint.getDeclContext()); return SolutionKind::Solved; case ConstraintKind::SubclassOf: @@ -16429,7 +16429,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) { case ConstraintKind::UnresolvedValueMember: return simplifyMemberConstraint( constraint.getKind(), constraint.getFirstType(), constraint.getMember(), - constraint.getSecondType(), constraint.getMemberUseDC(), + constraint.getSecondType(), constraint.getDeclContext(), constraint.getFunctionRefInfo(), /*outerAlternatives=*/{}, /*flags*/ std::nullopt, constraint.getLocator()); @@ -16438,7 +16438,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) { return simplifyValueWitnessConstraint( constraint.getKind(), constraint.getFirstType(), constraint.getRequirement(), constraint.getSecondType(), - constraint.getMemberUseDC(), constraint.getFunctionRefInfo(), + constraint.getDeclContext(), constraint.getFunctionRefInfo(), /*flags*/ std::nullopt, constraint.getLocator()); case ConstraintKind::Defaultable: diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp index 6bb6bd517861f..07aeef0ce1529 100644 --- a/lib/Sema/CSSolver.cpp +++ b/lib/Sema/CSSolver.cpp @@ -669,6 +669,10 @@ ConstraintSystem::SolverState::~SolverState() { CS.Options -= ConstraintSystemFlags::DebugConstraints; } + // This statistic is special because it's not a counter; we just update + // it in one shot at the end. + ASTBytesAllocated = CS.getASTContext().getSolverMemory(); + // Write our local statistics back to the overall statistics. #define CS_STATISTIC(Name, Description) JOIN2(Overall,Name) += Name; #include "swift/Sema/ConstraintSolverStats.def" diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index b699ea56127b6..850f3fc378558 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -30,9 +30,10 @@ using namespace constraints; Constraint::Constraint(ConstraintKind kind, ArrayRef constraints, bool isIsolated, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(kind), HasFix(false), HasRestriction(false), IsActive(false), - IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), - IsFavored(false), IsIsolated(isIsolated), NumTypeVariables(typeVars.size()), + : Kind(kind), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(false), HasRestriction(false), + IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), + RememberChoice(false), IsFavored(false), IsIsolated(isIsolated), Nested(constraints), Locator(locator) { assert(kind == ConstraintKind::Disjunction || kind == ConstraintKind::Conjunction); @@ -54,10 +55,11 @@ static bool isAdmissibleType(Type type) { Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(Kind), HasFix(false), HasRestriction(false), IsActive(false), - IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), - IsFavored(false), IsIsolated(false), - NumTypeVariables(typeVars.size()), Types{First, Second, Type()}, + : Kind(Kind), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(false), HasRestriction(false), + IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), + RememberChoice(false), IsFavored(false), IsIsolated(false), + Types{First, Second, Type()}, Locator(locator) { ASSERT(isAdmissibleType(First)); ASSERT(isAdmissibleType(Second)); @@ -135,10 +137,11 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(Kind), HasFix(false), HasRestriction(false), IsActive(false), - IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), - IsFavored(false), IsIsolated(false), - NumTypeVariables(typeVars.size()), Types{First, Second, Third}, + : Kind(Kind), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(false), HasRestriction(false), + IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), + RememberChoice(false), IsFavored(false), IsIsolated(false), + Types{First, Second, Third}, Locator(locator) { ASSERT(isAdmissibleType(First)); ASSERT(isAdmissibleType(Second)); @@ -201,10 +204,11 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second, FunctionRefInfo functionRefInfo, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(kind), HasFix(false), HasRestriction(false), IsActive(false), - IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), - IsFavored(false), IsIsolated(false), - NumTypeVariables(typeVars.size()), Member{first, second, {member}, useDC}, + : Kind(kind), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(true), HasRestriction(false), + IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), + RememberChoice(false), IsFavored(false), IsIsolated(false), + Member{first, second, {member}}, Locator(locator) { assert(kind == ConstraintKind::ValueMember || kind == ConstraintKind::UnresolvedValueMember); @@ -214,6 +218,7 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second, assert(useDC && "Member constraint has no use DC"); std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); + *getTrailingObjects() = useDC; } Constraint::Constraint(ConstraintKind kind, Type first, Type second, @@ -221,14 +226,14 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second, FunctionRefInfo functionRefInfo, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(kind), HasFix(false), HasRestriction(false), IsActive(false), - IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), - IsFavored(false), IsIsolated(false), NumTypeVariables(typeVars.size()), + : Kind(kind), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(true), HasRestriction(false), + IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), + RememberChoice(false), IsFavored(false), IsIsolated(false), Locator(locator) { Member.First = first; Member.Second = second; Member.Member.Ref = requirement; - Member.UseDC = useDC; TheFunctionRefInfo = functionRefInfo.getOpaqueValue(); assert(kind == ConstraintKind::ValueWitness); @@ -237,19 +242,21 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second, assert(useDC && "Member constraint has no use DC"); std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); + *getTrailingObjects() = useDC; } Constraint::Constraint(Type type, OverloadChoice choice, DeclContext *useDC, ConstraintFix *fix, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(ConstraintKind::BindOverload), HasFix(fix != nullptr), HasRestriction(false), + : Kind(ConstraintKind::BindOverload), NumTypeVariables(typeVars.size()), + HasFix(fix != nullptr), HasDeclContext(true), HasRestriction(false), IsActive(false), IsDisabled(bool(fix)), IsDisabledForPerformance(false), RememberChoice(false), IsFavored(false), IsIsolated(false), - NumTypeVariables(typeVars.size()), Overload{type, useDC}, - Locator(locator) { + Overload{type}, Locator(locator) { std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); if (fix) *getTrailingObjects() = fix; + *getTrailingObjects() = useDC; *getTrailingObjects() = choice; } @@ -257,10 +264,10 @@ Constraint::Constraint(ConstraintKind kind, ConversionRestrictionKind restriction, Type first, Type second, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(kind), Restriction(restriction), HasFix(false), HasRestriction(true), - IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), - RememberChoice(false), IsFavored(false), IsIsolated(false), - NumTypeVariables(typeVars.size()), Types{first, second, Type()}, + : Kind(kind), Restriction(restriction), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(false), HasRestriction(true), IsActive(false), + IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), + IsFavored(false), IsIsolated(false), Types{first, second, Type()}, Locator(locator) { ASSERT(isAdmissibleType(first)); ASSERT(isAdmissibleType(second)); @@ -270,10 +277,11 @@ Constraint::Constraint(ConstraintKind kind, Constraint::Constraint(ConstraintKind kind, ConstraintFix *fix, Type first, Type second, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(kind), HasFix(fix != nullptr), HasRestriction(false), IsActive(false), - IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), - IsFavored(false), IsIsolated(false), - NumTypeVariables(typeVars.size()), Types{first, second, Type()}, + : Kind(kind), NumTypeVariables(typeVars.size()), + HasFix(fix != nullptr), HasDeclContext(false), HasRestriction(false), + IsActive(false), IsDisabled(false), IsDisabledForPerformance(false), + RememberChoice(false), IsFavored(false), IsIsolated(false), + Types{first, second, Type()}, Locator(locator) { ASSERT(isAdmissibleType(first)); ASSERT(isAdmissibleType(second)); @@ -285,24 +293,26 @@ Constraint::Constraint(ConstraintKind kind, ConstraintFix *fix, Type first, Constraint::Constraint(ASTNode node, ContextualTypeInfo context, bool isDiscarded, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(ConstraintKind::SyntacticElement), HasFix(false), - HasRestriction(false), IsActive(false), IsDisabled(false), - IsDisabledForPerformance(false), RememberChoice(false), IsFavored(false), - IsIsolated(false), - NumTypeVariables(typeVars.size()), SyntacticElement{node, context, - isDiscarded}, + : Kind(ConstraintKind::SyntacticElement), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(false), HasRestriction(false), IsActive(false), + IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), + IsFavored(false), IsIsolated(false), isDiscarded(isDiscarded), + SyntacticElement{node}, Locator(locator) { std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); + *getTrailingObjects() = context; } Constraint::Constraint(FunctionType *appliedFn, Type calleeType, unsigned trailingClosureMatching, DeclContext *useDC, ConstraintLocator *locator, SmallPtrSetImpl &typeVars) - : Kind(ConstraintKind::ApplicableFunction), HasFix(false), - HasRestriction(false), IsActive(false), IsDisabled(false), - IsDisabledForPerformance(false), RememberChoice(false), IsFavored(false), - IsIsolated(false), NumTypeVariables(typeVars.size()), Locator(locator) { + : Kind(ConstraintKind::ApplicableFunction), NumTypeVariables(typeVars.size()), + HasFix(false), HasDeclContext(true), HasRestriction(false), IsActive(false), + IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false), + IsFavored(false), IsIsolated(false), + trailingClosureMatching(trailingClosureMatching), + Locator(locator) { ASSERT(isAdmissibleType(appliedFn)); ASSERT(isAdmissibleType(calleeType)); assert(trailingClosureMatching >= 0 && trailingClosureMatching <= 2); @@ -310,10 +320,9 @@ Constraint::Constraint(FunctionType *appliedFn, Type calleeType, Apply.AppliedFn = appliedFn; Apply.Callee = calleeType; - Apply.TrailingClosureMatching = trailingClosureMatching; - Apply.UseDC = useDC; std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); + *getTrailingObjects() = useDC; } ProtocolDecl *Constraint::getProtocol() const { @@ -782,8 +791,10 @@ Constraint *Constraint::create(ConstraintSystem &cs, ConstraintKind kind, // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return ::new (mem) Constraint(kind, first, second, locator, typeVars); } @@ -803,8 +814,10 @@ Constraint *Constraint::create(ConstraintSystem &cs, ConstraintKind kind, third->getTypeVariables(typeVars); auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return ::new (mem) Constraint(kind, first, second, third, @@ -846,8 +859,10 @@ Constraint *Constraint::createMember(ConstraintSystem &cs, ConstraintKind kind, // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/1, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return new (mem) Constraint(kind, first, second, member, useDC, functionRefInfo, locator, typeVars); @@ -868,8 +883,10 @@ Constraint *Constraint::createValueWitness( // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/1, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return new (mem) Constraint(kind, first, second, requirement, useDC, functionRefInfo, locator, typeVars); @@ -890,8 +907,10 @@ Constraint *Constraint::createBindOverload(ConstraintSystem &cs, Type type, // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), fix ? 1 : 0, /*hasOverloadChoice=*/1); + totalSizeToAlloc( + typeVars.size(), fix ? 1 : 0, /*hasDeclContext=*/1, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/1); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return new (mem) Constraint(type, choice, useDC, fix, locator, typeVars); } @@ -910,8 +929,10 @@ Constraint *Constraint::createRestricted(ConstraintSystem &cs, // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return new (mem) Constraint(kind, restriction, first, second, locator, typeVars); @@ -929,8 +950,10 @@ Constraint *Constraint::createFixed(ConstraintSystem &cs, ConstraintKind kind, // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), fix ? 1 : 0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), fix ? 1 : 0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return new (mem) Constraint(kind, fix, first, second, locator, typeVars); } @@ -1001,8 +1024,10 @@ Constraint *Constraint::createDisjunction(ConstraintSystem &cs, // Create the disjunction constraint. auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); auto disjunction = new (mem) Constraint(ConstraintKind::Disjunction, cs.allocateCopy(constraints), @@ -1022,8 +1047,10 @@ Constraint *Constraint::createConjunction( assert(!constraints.empty() && "Empty conjunction constraint"); auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); auto conjunction = new (mem) Constraint(ConstraintKind::Conjunction, cs.allocateCopy(constraints), @@ -1058,8 +1085,10 @@ Constraint *Constraint::createApplicableFunction( // Create the constraint. auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/1, + /*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); auto constraint = new (mem) Constraint(argumentFnType, calleeType, rawTrailingClosureMatching, useDC, @@ -1087,8 +1116,10 @@ Constraint *Constraint::createSyntacticElement(ConstraintSystem &cs, contextTy->getTypeVariables(typeVars); auto size = - totalSizeToAlloc( - typeVars.size(), /*hasFix=*/0, /*hasOverloadChoice=*/0); + totalSizeToAlloc( + typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0, + /*hasContextualTypeInfo=*/1, /*hasOverloadChoice=*/0); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); return new (mem) Constraint(node, context, isDiscarded, locator, typeVars); } @@ -1096,7 +1127,7 @@ Constraint *Constraint::createSyntacticElement(ConstraintSystem &cs, std::optional Constraint::getTrailingClosureMatching() const { assert(Kind == ConstraintKind::ApplicableFunction); - switch (Apply.TrailingClosureMatching) { + switch (trailingClosureMatching) { case 0: return std::nullopt; case 1: return TrailingClosureMatching::Forward; diff --git a/unittests/Sema/ConstraintSimplificationTests.cpp b/unittests/Sema/ConstraintSimplificationTests.cpp index 062644198a37d..43f8d80329b29 100644 --- a/unittests/Sema/ConstraintSimplificationTests.cpp +++ b/unittests/Sema/ConstraintSimplificationTests.cpp @@ -218,7 +218,7 @@ TEST_F(SemaTest, TestInitializerUseDCIsSetCorrectlyInClosure) { ->isLastElement()); for (auto *choice : constraint->getNestedConstraints()) - ASSERT_EQ(choice->getOverloadUseDC(), closure); + ASSERT_EQ(choice->getDeclContext(), closure); } } }