Skip to content
Merged
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
15 changes: 14 additions & 1 deletion include/swift/Sema/Constraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace constraints {
class ConstraintFix;
class ConstraintLocator;
class ConstraintSystem;
class PreparedOverload;
enum class TrailingClosureMatching;

/// Describes the kind of constraint placed on one or more types.
Expand Down Expand Up @@ -437,6 +438,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
struct {
/// The first type.
Type First;

/// The prepared overload, if any.
PreparedOverload *Prepared;
} Overload;

struct {
Expand Down Expand Up @@ -490,7 +494,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
SmallPtrSetImpl<TypeVariableType *> &typeVars);

/// Construct a new overload-binding constraint, which might have a fix.
Constraint(Type type, OverloadChoice choice, DeclContext *useDC,
Constraint(Type type, OverloadChoice choice,
PreparedOverload *preparedOverload,
DeclContext *useDC,
ConstraintFix *fix, ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars);

Expand Down Expand Up @@ -871,6 +877,13 @@ class Constraint final : public llvm::ilist_node<Constraint>,
return *getTrailingObjects<OverloadChoice>();
}

/// Retrieve the prepared overload choice for an overload-binding
/// constraint.
PreparedOverload *getPreparedOverload() const {
ASSERT(Kind == ConstraintKind::BindOverload);
return Overload.Prepared;
}

FunctionType *getAppliedFunctionType() const {
assert(Kind == ConstraintKind::ApplicableFunction);
return Apply.AppliedFn;
Expand Down
108 changes: 52 additions & 56 deletions include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ namespace constraints {

class ConstraintSystem;
class SyntacticElementTarget;
struct PreparedOverload;

// PreparedOverload.h
struct DeclReferenceType;
class PreparedOverload;
struct PreparedOverloadBuilder;

} // end namespace constraints

Expand Down Expand Up @@ -2143,34 +2147,6 @@ struct ClosureIsolatedByPreconcurrency {
bool operator()(const ClosureExpr *expr) const;
};

/// Describes the type produced when referencing a declaration.
struct DeclReferenceType {
/// The "opened" type, which is the type of the declaration where any
/// generic parameters have been replaced with type variables.
///
/// The mapping from generic parameters to type variables will have been
/// recorded by \c recordOpenedTypes when this type is produced.
Type openedType;

/// The opened type, after performing contextual type adjustments such as
/// removing concurrency-related annotations for a `@preconcurrency`
/// operation.
Type adjustedOpenedType;

/// The type of the reference, based on the original opened type. This is the
/// type that the expression used to form the declaration reference would
/// have if no adjustments had been applied.
Type referenceType;

/// The type of the reference, which is the adjusted opened type after
/// (e.g.) applying the base of a member access. This is the type of the
/// expression used to form the declaration reference.
Type adjustedReferenceType;

/// The type that could be thrown by accessing this declaration.
Type thrownErrorTypeOnAccess;
};

/// Describes a system of constraints on type variables, the
/// solution of which assigns concrete types to each of the type variables.
/// Constraint systems are typically generated given an (untyped) expression.
Expand Down Expand Up @@ -2954,7 +2930,7 @@ class ConstraintSystem {
/// Create a new type variable.
TypeVariableType *createTypeVariable(ConstraintLocator *locator,
unsigned options,
PreparedOverload *preparedOverload
PreparedOverloadBuilder *preparedOverload
= nullptr);

/// Retrieve the set of active type variables.
Expand Down Expand Up @@ -3414,7 +3390,8 @@ class ConstraintSystem {
/// Update OpenedExistentials and record a change in the trail.
void recordOpenedExistentialType(ConstraintLocator *locator,
ExistentialArchetypeType *opened,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload
= nullptr);

/// Retrieve the generic environment for the opened element of a given pack
/// expansion, or \c nullptr if no environment was recorded yet.
Expand Down Expand Up @@ -3622,7 +3599,7 @@ class ConstraintSystem {
/// Log and record the application of the fix. Return true iff any
/// subsequent solution would be worse than the best known solution.
bool recordFix(ConstraintFix *fix, unsigned impact = 1,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

void recordPotentialHole(TypeVariableType *typeVar);
void recordAnyTypeVarAsPotentialHole(Type type);
Expand Down Expand Up @@ -3698,13 +3675,13 @@ class ConstraintSystem {
void addConstraint(ConstraintKind kind, Type first, Type second,
ConstraintLocatorBuilder locator,
bool isFavored = false,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

/// Add a requirement as a constraint to the constraint system.
void addConstraint(Requirement req, ConstraintLocatorBuilder locator,
bool isFavored,
bool prohibitNonisolatedConformance,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

void addApplicationConstraint(
FunctionType *appliedFn, Type calleeType,
Expand Down Expand Up @@ -3814,9 +3791,9 @@ class ConstraintSystem {

/// Add a constraint that binds an overload set to a specific choice.
void addBindOverloadConstraint(Type boundTy, OverloadChoice choice,
ConstraintLocator *locator,
DeclContext *useDC) {
resolveOverload(locator, boundTy, choice, useDC);
ConstraintLocator *locator, DeclContext *useDC) {
resolveOverload(locator, boundTy, choice, useDC,
/*preparedOverload=*/nullptr);
}

/// Add a value member constraint to the constraint system.
Expand Down Expand Up @@ -4319,7 +4296,7 @@ class ConstraintSystem {
Type openUnboundGenericType(GenericTypeDecl *decl, Type parentTy,
ConstraintLocatorBuilder locator,
bool isTypeResolution,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

/// Replace placeholder types with fresh type variables, and unbound generic
/// types with bound generic types whose generic args are fresh type
Expand All @@ -4330,7 +4307,7 @@ class ConstraintSystem {
/// \returns The converted type.
Type replaceInferableTypesWithTypeVars(Type type,
ConstraintLocatorBuilder locator,
PreparedOverload *preparedOverload
PreparedOverloadBuilder *preparedOverload
= nullptr);

/// "Open" the given type by replacing any occurrences of generic
Expand All @@ -4343,7 +4320,7 @@ class ConstraintSystem {
/// \returns The opened type, or \c type if there are no archetypes in it.
Type openType(Type type, ArrayRef<OpenedType> replacements,
ConstraintLocatorBuilder locator,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// "Open" an opaque archetype type, similar to \c openType.
Type openOpaqueType(OpaqueTypeArchetypeType *type,
Expand All @@ -4360,12 +4337,12 @@ class ConstraintSystem {
Type openPackExpansionType(PackExpansionType *expansion,
ArrayRef<OpenedType> replacements,
ConstraintLocatorBuilder locator,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Update OpenedPackExpansionTypes and record a change in the trail.
void recordOpenedPackExpansionType(PackExpansionType *expansion,
TypeVariableType *expansionVar,
PreparedOverload *preparedOverload
PreparedOverloadBuilder *preparedOverload
= nullptr);

/// Undo the above change.
Expand All @@ -4392,29 +4369,29 @@ class ConstraintSystem {
ConstraintLocatorBuilder locator,
SmallVectorImpl<OpenedType> &replacements,
DeclContext *outerDC,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Open the generic parameter list and its requirements,
/// creating type variables for each of the type parameters.
void openGeneric(DeclContext *outerDC,
GenericSignature signature,
ConstraintLocatorBuilder locator,
SmallVectorImpl<OpenedType> &replacements,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Open the generic parameter list creating type variables for each of the
/// type parameters.
void openGenericParameters(DeclContext *outerDC,
GenericSignature signature,
SmallVectorImpl<OpenedType> &replacements,
ConstraintLocatorBuilder locator,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Open a generic parameter into a type variable and record
/// it in \c replacements.
TypeVariableType *openGenericParameter(GenericTypeParamType *parameter,
ConstraintLocatorBuilder locator,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Given generic signature open its generic requirements,
/// using substitution function, and record them in the
Expand All @@ -4424,7 +4401,7 @@ class ConstraintSystem {
bool skipProtocolSelfConstraint,
ConstraintLocatorBuilder locator,
llvm::function_ref<Type(Type)> subst,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

// Record the given requirement in the constraint system.
void openGenericRequirement(DeclContext *outerDC,
Expand All @@ -4434,18 +4411,18 @@ class ConstraintSystem {
bool skipProtocolSelfConstraint,
ConstraintLocatorBuilder locator,
llvm::function_ref<Type(Type)> subst,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Update OpenedTypes and record a change in the trail.
void recordOpenedType(
ConstraintLocator *locator, ArrayRef<OpenedType> openedTypes,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

/// Record the set of opened types for the given locator.
void recordOpenedTypes(
ConstraintLocatorBuilder locator,
const SmallVectorImpl<OpenedType> &replacements,
PreparedOverload *preparedOverload = nullptr,
PreparedOverloadBuilder *preparedOverload = nullptr,
bool fixmeAllowDuplicates = false);

/// Check whether the given type conforms to the given protocol and if
Expand All @@ -4458,7 +4435,7 @@ class ConstraintSystem {
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
unsigned numApplies, bool isMainDispatchQueue,
ArrayRef<OpenedType> replacements, ConstraintLocatorBuilder locator,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Retrieve the type of a reference to the given value declaration.
///
Expand All @@ -4474,7 +4451,7 @@ class ConstraintSystem {
FunctionRefInfo functionRefInfo,
ConstraintLocatorBuilder locator,
DeclContext *useDC,
PreparedOverload *preparedOverload);
PreparedOverloadBuilder *preparedOverload);

/// Return the type-of-reference of the given value.
///
Expand Down Expand Up @@ -4516,7 +4493,7 @@ class ConstraintSystem {
Type baseTy, ValueDecl *decl, DeclContext *useDC, bool isDynamicLookup,
FunctionRefInfo functionRefInfo, ConstraintLocator *locator,
SmallVectorImpl<OpenedType> *replacements = nullptr,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

/// Retrieve a list of generic parameter types solver has "opened" (replaced
/// with a type variable) at the given location.
Expand Down Expand Up @@ -4929,9 +4906,28 @@ class ConstraintSystem {
void recordResolvedOverload(ConstraintLocator *locator,
SelectedOverload choice);

/// Build and allocate a prepared overload in the solver arena.
PreparedOverload *prepareOverload(ConstraintLocator *locator,
OverloadChoice choice,
DeclContext *useDC);

/// Populate the prepared overload with all type variables and constraints
/// that are to be introduced into the constraint system when this choice
/// is taken.
DeclReferenceType
prepareOverloadImpl(ConstraintLocator *locator,
OverloadChoice choice,
DeclContext *useDC,
PreparedOverloadBuilder *preparedOverload);

void replayChanges(
ConstraintLocator *locator,
PreparedOverload *preparedOverload);

/// Resolve the given overload set to the given choice.
void resolveOverload(ConstraintLocator *locator, Type boundType,
OverloadChoice choice, DeclContext *useDC);
OverloadChoice choice, DeclContext *useDC,
PreparedOverload *preparedOverload);

/// Simplify a type, by replacing type variables with either their
/// fixed types (if available) or their representatives.
Expand Down Expand Up @@ -5342,13 +5338,13 @@ class ConstraintSystem {
ConstraintKind matchKind,
ConstraintLocator *locator,
ConstraintLocator *calleeLocator,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

/// Used by applyPropertyWrapperToParameter() to update appliedPropertyWrappers
/// and record a change in the trail.
void applyPropertyWrapper(Expr *anchor,
AppliedPropertyWrapper applied,
PreparedOverload *preparedOverload = nullptr);
PreparedOverloadBuilder *preparedOverload = nullptr);

/// Undo the above change.
void removePropertyWrapper(Expr *anchor);
Expand Down
17 changes: 17 additions & 0 deletions include/swift/Sema/OverloadChoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,23 @@ class OverloadChoice {
return (OverloadChoiceKind)kind;
}

bool canBePrepared() const {
switch (getKind()) {
case OverloadChoiceKind::Decl:
case OverloadChoiceKind::DeclViaBridge:
case OverloadChoiceKind::DeclViaDynamic:
case OverloadChoiceKind::DeclViaUnwrappedOptional:
case OverloadChoiceKind::DynamicMemberLookup:
case OverloadChoiceKind::KeyPathDynamicMemberLookup:
return true;
case OverloadChoiceKind::TupleIndex:
case OverloadChoiceKind::MaterializePack:
case OverloadChoiceKind::ExtractFunctionIsolation:
case OverloadChoiceKind::KeyPathApplication:
return false;
}
}

/// Determine whether this choice is for a declaration.
bool isDecl() const {
return DeclOrKind.is<ValueDecl*>();
Expand Down
Loading