diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 209aee919a4..dff169f3599 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1420,8 +1420,8 @@ namespace { Type resolveTypeReferenceInExpression(TypeRepr *rep) { TypeResolutionOptions options(TypeResolverContext::InExpression); options |= TypeResolutionFlags::AllowUnboundGenerics; - return CS.TC.resolveType(rep, TypeResolution::forContextual(CS.DC), - options); + return TypeResolution::forContextual(CS.DC).resolveType(rep, + options); } Type visitTypeExpr(TypeExpr *E) { diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp index 1d410b05f78..4927cce993f 100644 --- a/lib/Sema/CSSolver.cpp +++ b/lib/Sema/CSSolver.cpp @@ -1199,9 +1199,9 @@ void ConstraintSystem::shrink(Expr *expr) { // instead of cloning representative. auto coercionRepr = typeRepr->clone(CS.getASTContext()); // Let's try to resolve coercion type from cloned representative. + auto resolution = TypeResolution::forContextual(CS.DC); auto coercionType = - CS.TC.resolveType(coercionRepr, - TypeResolution::forContextual(CS.DC), None); + resolution.resolveType(coercionRepr, None); // Looks like coercion type is invalid, let's skip this sub-tree. if (coercionType->hasError()) diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp index 5cbeca724f5..a3af603a9e7 100644 --- a/lib/Sema/CodeSynthesis.cpp +++ b/lib/Sema/CodeSynthesis.cpp @@ -1848,8 +1848,8 @@ static void maybeAddAccessorsToBehaviorStorage(TypeChecker &TC, VarDecl *var) { }; // Try to resolve the behavior to a protocol. - auto behaviorType = TC.resolveType(behavior->ProtocolName, - TypeResolution::forContextual(dc), None); + auto resolution = TypeResolution::forContextual(dc); + auto behaviorType = resolution.resolveType(behavior->ProtocolName, None); if (!behaviorType) { return makeBehaviorAccessors(); } diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 0d9a1b85b90..d1883a3a3d5 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -1777,12 +1777,13 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) { SmallPtrSet constrainedGenericParams; // Go over the set of requirements and resolve their types. + auto resolution = TypeResolution::forContextual(FD); for (auto &req : trailingWhereClause->getRequirements()) { if (req.getKind() == RequirementReprKind::SameType) { - auto firstType = TC.resolveType(req.getFirstTypeRepr(), - TypeResolution::forContextual(FD), None); - auto secondType = TC.resolveType(req.getSecondTypeRepr(), - TypeResolution::forContextual(FD), None); + auto firstType = resolution.resolveType(req.getFirstTypeRepr(), + None); + auto secondType = resolution.resolveType(req.getSecondTypeRepr(), + None); Type interfaceFirstType; Type interfaceSecondType; @@ -1832,9 +1833,8 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) { } if (req.getKind() == RequirementReprKind::LayoutConstraint) { - auto subjectType = TC.resolveType(req.getSubjectRepr(), - TypeResolution::forContextual(FD), - None); + auto subjectType = resolution.resolveType(req.getSubjectRepr(), + None); Type interfaceSubjectType; // Map types to their interface types. @@ -1870,12 +1870,8 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) { } if (req.getKind() == RequirementReprKind::TypeConstraint) { - auto subjectType = TC.resolveType(req.getSubjectRepr(), - TypeResolution::forContextual(FD), - None); - auto constraint = TC.resolveType(req.getConstraintLoc().getTypeRepr(), - TypeResolution::forContextual(FD), - None); + auto subjectType = resolution.resolveType(req.getSubjectRepr(), None); + auto constraint = resolution.resolveType(req.getConstraintLoc().getTypeRepr(), None); Type interfaceSubjectType; @@ -2043,8 +2039,8 @@ void AttributeChecker::visitImplementsAttr(ImplementsAttr *attr) { options |= TypeResolutionFlags::AllowUnboundGenerics; DeclContext *DC = D->getDeclContext(); - Type T = TC.resolveType(ProtoTypeLoc.getTypeRepr(), - TypeResolution::forContextual(DC), options); + auto resolution = TypeResolution::forContextual(DC); + Type T = resolution.resolveType(ProtoTypeLoc.getTypeRepr(), options); ProtoTypeLoc.setType(T); // Definite error-types were already diagnosed in resolveType. diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index e1329efd51a..2b2b058fcea 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -1036,7 +1036,7 @@ namespace { if (auto PlaceholderE = dyn_cast(expr)) { if (!PlaceholderE->getTypeLoc().isNull()) { if (!TC.validateType(PlaceholderE->getTypeLoc(), - TypeResolution::forContextual(DC))) + TypeResolution::forContextual(DC), None)) expr->setType(PlaceholderE->getTypeLoc().getType()); } return finish(true, expr); @@ -1347,7 +1347,7 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) { options |= TypeResolutionFlags::AllowUnboundGenerics; options |= TypeResolutionFlags::AllowUnavailable; auto resolution = TypeResolution::forContextual(DC); - auto BaseTy = TC.resolveType(InnerTypeRepr, resolution, options); + auto BaseTy = resolution.resolveType(InnerTypeRepr, options); if (BaseTy && BaseTy->mayHaveMembers()) { auto lookupOptions = defaultMemberLookupOptions; @@ -1864,7 +1864,7 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) { TypeResolutionOptions options(TypeResolverContext::InExpression); options |= TypeResolutionFlags::AllowUnboundGenerics; auto resolution = TypeResolution::forContextual(DC); - type = TC.resolveType(rep, resolution, options); + type = resolution.resolveType(rep, options); typeExpr->getTypeLoc().setType(type); } diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index b0d25df175d..e9ac3ad138e 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -3818,8 +3818,10 @@ void TypeChecker::validateDecl(ValueDecl *D) { TypeLoc &defaultDefinition = assocType->getDefaultDefinitionLoc(); if (!defaultDefinition.isNull()) { if (validateType( - defaultDefinition, - TypeResolution::forContextual(assocType->getDeclContext()))) { + defaultDefinition, + TypeResolution::forContextual( + assocType->getDeclContext()), + None)) { defaultDefinition.setInvalidType(Context); } else { // associatedtype X = X is invalid diff --git a/lib/Sema/TypeCheckRequestFunctions.cpp b/lib/Sema/TypeCheckRequestFunctions.cpp index 15a4667ccd4..2031f27f8cb 100644 --- a/lib/Sema/TypeCheckRequestFunctions.cpp +++ b/lib/Sema/TypeCheckRequestFunctions.cpp @@ -45,17 +45,13 @@ InheritedTypeRequest::evaluate( isa(dc) ? TypeResolution::forStructural(dc) : TypeResolution::forContextual(dc); - auto lazyResolver = dc->getASTContext().getLazyResolver(); - assert(lazyResolver && "Cannot resolve inherited type at this point"); - - TypeChecker &tc = *static_cast(lazyResolver); TypeLoc &typeLoc = getTypeLoc(decl, index); Type inheritedType = - tc.resolveType(typeLoc.getTypeRepr(), resolution, options); + resolution.resolveType(typeLoc.getTypeRepr(), options); if (inheritedType && !isa(dc)) inheritedType = inheritedType->mapTypeOutOfContext(); - return inheritedType ? inheritedType : ErrorType::get(tc.Context); + return inheritedType ? inheritedType : ErrorType::get(dc->getASTContext()); } llvm::Expected diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 8bda7a18f55..6795697712f 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -641,7 +641,7 @@ Type TypeChecker::applyGenericArguments(Type type, if (auto nominal = dyn_cast(decl)) { if (nominal->isOptionalDecl()) { // Validate the generic argument. - Type objectType = resolveType(genericArgs[0], resolution, options); + Type objectType = resolution.resolveType(genericArgs[0], options); if (!objectType || objectType->hasError()) return nullptr; @@ -674,7 +674,7 @@ Type TypeChecker::applyGenericArguments(Type type, SmallVector args; for (auto tyR : genericArgs) { // Propagate failure. - Type substTy = resolveType(tyR, resolution, options); + Type substTy = resolution.resolveType(tyR, options); if (!substTy || substTy->hasError()) return ErrorType::get(ctx); @@ -1576,7 +1576,7 @@ bool TypeChecker::validateType(TypeLoc &Loc, TypeResolution resolution, Type type = Loc.getType(); if (type.isNull()) { - type = resolveType(Loc.getTypeRepr(), resolution, options); + type = resolution.resolveType(Loc.getTypeRepr(), options); if (!type) { type = ErrorType::get(Context); @@ -1685,12 +1685,11 @@ namespace { }; } // end anonymous namespace -Type TypeChecker::resolveType(TypeRepr *TyR, TypeResolution resolution, +Type TypeResolution::resolveType(TypeRepr *TyR, TypeResolutionOptions options) { - PrettyStackTraceTypeRepr stackTrace(resolution.getASTContext(), - "resolving", TyR); + PrettyStackTraceTypeRepr stackTrace(getASTContext(), "resolving", TyR); - TypeResolver typeResolver(resolution); + TypeResolver typeResolver(*this); auto result = typeResolver.resolveType(TyR, options); // If we resolved down to an error, make sure to mark the typeRepr as invalid diff --git a/lib/Sema/TypeCheckType.h b/lib/Sema/TypeCheckType.h index 3ebcd18c4cb..e6310a3e454 100644 --- a/lib/Sema/TypeCheckType.h +++ b/lib/Sema/TypeCheckType.h @@ -18,6 +18,243 @@ namespace swift { +/// Flags that describe the context of type checking a pattern or +/// type. +enum class TypeResolutionFlags : uint16_t { + /// Whether to allow unspecified types within a pattern. + AllowUnspecifiedTypes = 1 << 0, + + /// Whether to allow unbound generic types. + AllowUnboundGenerics = 1 << 1, + + /// Whether an unavailable protocol can be referenced. + AllowUnavailableProtocol = 1 << 2, + + /// Whether we should allow references to unavailable types. + AllowUnavailable = 1 << 3, + + /// Whether the given type can override the type of a typed pattern. + OverrideType = 1 << 4, + + /// Whether we are validating the type for SIL. + // FIXME: Move this flag to TypeResolverContext. + SILType = 1 << 5, + + /// Whether we are parsing a SIL file. Not the same as SILType, + /// because the latter is not set if we're parsing an AST type. + SILMode = 1 << 6, + + /// Whether this is a resolution based on a non-inferred type pattern. + FromNonInferredPattern = 1 << 7, + + /// Whether this type resolution is guaranteed not to affect downstream files. + KnownNonCascadingDependency = 1 << 8, + + /// Whether we are at the direct base of a type expression. + Direct = 1 << 9, + + /// Whether we should not produce diagnostics if the type is invalid. + SilenceErrors = 1 << 10, +}; + +/// Type resolution contexts that require special handling. +enum class TypeResolverContext : uint8_t { + /// No special type handling is required. + None, + + /// Whether we are checking the parameter list of a function. + AbstractFunctionDecl, + + /// Whether we are checking the parameter list of a subscript. + SubscriptDecl, + + /// Whether we are checking the parameter list of a closure. + ClosureExpr, + + /// Whether we are in the input type of a function, or under one level of + /// tuple type. This is not set for multi-level tuple arguments. + /// See also: TypeResolutionFlags::Direct + FunctionInput, + + /// Whether this is a variadic function input. + VariadicFunctionInput, + + /// Whether we are in the result type of a function, including multi-level + /// tuple return values. See also: TypeResolutionFlags::Direct + FunctionResult, + + /// Whether we are in the result type of a function body that is + /// known to produce dynamic Self. + DynamicSelfResult, + + /// Whether we are in a protocol's where clause + ProtocolWhereClause, + + /// Whether this is a pattern binding entry. + PatternBindingDecl, + + /// Whether we are the variable type in a for/in statement. + ForEachStmt, + + /// Whether we are binding an extension declaration, which limits + /// the lookup. + ExtensionBinding, + + /// Whether this type is being used in an expression or local declaration. + /// + /// This affects what sort of dependencies are recorded when resolving the + /// type. + InExpression, + + /// Whether this type is being used in a cast or coercion expression. + ExplicitCastExpr, + + /// Whether this type is the value carried in an enum case. + EnumElementDecl, + + /// Whether this is the payload subpattern of an enum pattern. + EnumPatternPayload, + + /// Whether we are checking the underlying type of a typealias. + TypeAliasDecl, + + /// Whether we are in a requirement of a generic declaration + GenericRequirement, + + /// Whether we are in a type argument for an optional + ImmediateOptionalTypeArgument, + + /// Whether this is the type of an editor placeholder. + EditorPlaceholderExpr, +}; + +/// Options that determine how type resolution should work. +class TypeResolutionOptions { + using Context = TypeResolverContext; + + // The "base" type resolution context. This never changes. + Context base = Context::None; + // The current type resolution context. + Context context = Context::None; + // TypeResolutionFlags + uint16_t flags = 0; + static_assert(sizeof(flags) == sizeof(TypeResolutionFlags), + "Flags size error"); + +public: + ~TypeResolutionOptions() = default; + TypeResolutionOptions(const TypeResolutionOptions &) = default; + TypeResolutionOptions(TypeResolutionOptions &&) = default; + TypeResolutionOptions &operator =(const TypeResolutionOptions &) = default; + TypeResolutionOptions &operator =(TypeResolutionOptions &&) = default; + + // NOTE: Use either setContext() or explicit construction and assignment. + void operator =(const Context &) = delete; + void operator =(Context &&) = delete; + + // NOTE: "None" might be more permissive than one wants, therefore no + // reasonable default context is possible. + TypeResolutionOptions() = delete; + + TypeResolutionOptions(Context context) : base(context), context(context), + flags(unsigned(TypeResolutionFlags::Direct)) {} + // Helper forwarding constructors: + TypeResolutionOptions(llvm::NoneType) : TypeResolutionOptions(Context::None){} + + /// Test the current type resolution base context. + bool hasBase(Context context) const { return base == context; } + + /// Get the base type resolution context. + Context getBaseContext() const { return base; } + + /// Test the current type resolution context. + bool is(Context context) const { return this->context == context; } + + /// Get the current type resolution context. + Context getContext() const { return context; } + /// Set the current type resolution context. + void setContext(Context newContext) { + context = newContext; + flags &= ~unsigned(TypeResolutionFlags::Direct); + } + void setContext(llvm::NoneType) { setContext(Context::None); } + + /// Get the current flags. + TypeResolutionFlags getFlags() const { return TypeResolutionFlags(flags); } + + /// Is this type resolution context an expression. + bool isAnyExpr() const { + switch (base) { + case Context::InExpression: + case Context::ExplicitCastExpr: + case Context::ForEachStmt: + case Context::PatternBindingDecl: + case Context::EditorPlaceholderExpr: + case Context::ClosureExpr: + return true; + case Context::None: + case Context::FunctionInput: + case Context::VariadicFunctionInput: + case Context::FunctionResult: + case Context::DynamicSelfResult: + case Context::ProtocolWhereClause: + case Context::ExtensionBinding: + case Context::SubscriptDecl: + case Context::EnumElementDecl: + case Context::EnumPatternPayload: + case Context::TypeAliasDecl: + case Context::GenericRequirement: + case Context::ImmediateOptionalTypeArgument: + case Context::AbstractFunctionDecl: + return false; + } + } + + /// Determine whether all of the given options are set. + bool contains(TypeResolutionFlags set) const { + return !static_cast(unsigned(set) & ~unsigned(flags)); + } + + /// Produce type resolution options with additional flags. + friend TypeResolutionOptions operator|(TypeResolutionOptions lhs, + TypeResolutionFlags rhs) { + return lhs |= rhs; + } + + /// Merge additional flags into type resolution options. + friend TypeResolutionOptions &operator|=(TypeResolutionOptions &lhs, + TypeResolutionFlags rhs) { + lhs.flags |= unsigned(rhs); + return lhs; + } + + /// Test whether any given flag is set in the type resolution options. + friend bool operator&(TypeResolutionOptions lhs, TypeResolutionFlags rhs) { + return lhs.flags & unsigned(rhs); + } + + /// Produce type resolution options with removed flags. + friend TypeResolutionOptions operator-(TypeResolutionOptions lhs, + TypeResolutionFlags rhs) { + return lhs -= rhs; + } + + /// Remove the flags from the type resolution options. + friend TypeResolutionOptions &operator-=(TypeResolutionOptions &lhs, + TypeResolutionFlags rhs) { + lhs.flags &= ~unsigned(rhs); + return lhs; + } + /// Strip the contextual options from the given type resolution options. + inline TypeResolutionOptions withoutContext(bool preserveSIL = false) const { + auto copy = *this; + copy.setContext(None); + // FIXME: Move SILType to TypeResolverContext. + if (!preserveSIL) copy -= TypeResolutionFlags::SILType; + return copy; + } +}; + /// Handles the resolution of types within a given declaration context, /// which might involve resolving generic parameters to a particular /// stage. @@ -78,16 +315,32 @@ public: /// no generic signature to resolve types. GenericSignature *getGenericSignature() const; + /// \brief Resolves a TypeRepr to a type. + /// + /// Performs name binding, checking of generic arguments, and so on in order + /// to create a well-formed type. + /// + /// \param TyR The type representation to check. + /// + /// \param options Options that alter type resolution. + /// + /// \returns a well-formed type or an ErrorType in case of an error. + Type resolveType(TypeRepr *TyR, TypeResolutionOptions options); + /// Whether this type resolution uses archetypes (vs. generic parameters). bool usesArchetypes() const; /// Map the given type (that involves generic parameters) Type mapTypeIntoContext(Type type) const; + /// Resolve a reference to a member type of the given (dependent) base and + /// name. Type resolveDependentMemberType(Type baseTy, DeclContext *DC, SourceRange baseRange, ComponentIdentTypeRepr *ref) const; + /// Determine whether the given two types are equivalent within this + /// type resolution context. bool areSameType(Type type1, Type type2) const; }; diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index a6f5962f846..d16f394c151 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -41,6 +41,7 @@ class NormalProtocolConformance; class TopLevelContext; class TypeChecker; class TypeResolution; +class TypeResolutionOptions; class TypoCorrectionResults; class ExprPattern; class SynthesizedFunction; @@ -457,243 +458,6 @@ enum class RequirementCheckResult { Success, Failure, SubstitutionFailure }; -/// Flags that describe the context of type checking a pattern or -/// type. -enum class TypeResolutionFlags : uint16_t { - /// Whether to allow unspecified types within a pattern. - AllowUnspecifiedTypes = 1 << 0, - - /// Whether to allow unbound generic types. - AllowUnboundGenerics = 1 << 1, - - /// Whether an unavailable protocol can be referenced. - AllowUnavailableProtocol = 1 << 2, - - /// Whether we should allow references to unavailable types. - AllowUnavailable = 1 << 3, - - /// Whether the given type can override the type of a typed pattern. - OverrideType = 1 << 4, - - /// Whether we are validating the type for SIL. - // FIXME: Move this flag to TypeResolverContext. - SILType = 1 << 5, - - /// Whether we are parsing a SIL file. Not the same as SILType, - /// because the latter is not set if we're parsing an AST type. - SILMode = 1 << 6, - - /// Whether this is a resolution based on a non-inferred type pattern. - FromNonInferredPattern = 1 << 7, - - /// Whether this type resolution is guaranteed not to affect downstream files. - KnownNonCascadingDependency = 1 << 8, - - /// Whether we are at the direct base of a type expression. - Direct = 1 << 9, - - /// Whether we should not produce diagnostics if the type is invalid. - SilenceErrors = 1 << 10, -}; - -/// Type resolution contexts that require special handling. -enum class TypeResolverContext : uint8_t { - /// No special type handling is required. - None, - - /// Whether we are checking the parameter list of a function. - AbstractFunctionDecl, - - /// Whether we are checking the parameter list of a subscript. - SubscriptDecl, - - /// Whether we are checking the parameter list of a closure. - ClosureExpr, - - /// Whether we are in the input type of a function, or under one level of - /// tuple type. This is not set for multi-level tuple arguments. - /// See also: TypeResolutionFlags::Direct - FunctionInput, - - /// Whether this is a variadic function input. - VariadicFunctionInput, - - /// Whether we are in the result type of a function, including multi-level - /// tuple return values. See also: TypeResolutionFlags::Direct - FunctionResult, - - /// Whether we are in the result type of a function body that is - /// known to produce dynamic Self. - DynamicSelfResult, - - /// Whether we are in a protocol's where clause - ProtocolWhereClause, - - /// Whether this is a pattern binding entry. - PatternBindingDecl, - - /// Whether we are the variable type in a for/in statement. - ForEachStmt, - - /// Whether we are binding an extension declaration, which limits - /// the lookup. - ExtensionBinding, - - /// Whether this type is being used in an expression or local declaration. - /// - /// This affects what sort of dependencies are recorded when resolving the - /// type. - InExpression, - - /// Whether this type is being used in a cast or coercion expression. - ExplicitCastExpr, - - /// Whether this type is the value carried in an enum case. - EnumElementDecl, - - /// Whether this is the payload subpattern of an enum pattern. - EnumPatternPayload, - - /// Whether we are checking the underlying type of a typealias. - TypeAliasDecl, - - /// Whether we are in a requirement of a generic declaration - GenericRequirement, - - /// Whether we are in a type argument for an optional - ImmediateOptionalTypeArgument, - - /// Whether this is the type of an editor placeholder. - EditorPlaceholderExpr, -}; - -/// Options that determine how type resolution should work. -class TypeResolutionOptions { - using Context = TypeResolverContext; - - // The "base" type resolution context. This never changes. - Context base = Context::None; - // The current type resolution context. - Context context = Context::None; - // TypeResolutionFlags - uint16_t flags = 0; - static_assert(sizeof(flags) == sizeof(TypeResolutionFlags), - "Flags size error"); - -public: - ~TypeResolutionOptions() = default; - TypeResolutionOptions(const TypeResolutionOptions &) = default; - TypeResolutionOptions(TypeResolutionOptions &&) = default; - TypeResolutionOptions &operator =(const TypeResolutionOptions &) = default; - TypeResolutionOptions &operator =(TypeResolutionOptions &&) = default; - - // NOTE: Use either setContext() or explicit construction and assignment. - void operator =(const Context &) = delete; - void operator =(Context &&) = delete; - - // NOTE: "None" might be more permissive than one wants, therefore no - // reasonable default context is possible. - TypeResolutionOptions() = delete; - - TypeResolutionOptions(Context context) : base(context), context(context), - flags(unsigned(TypeResolutionFlags::Direct)) {} - // Helper forwarding constructors: - TypeResolutionOptions(llvm::NoneType) : TypeResolutionOptions(Context::None){} - - /// Test the current type resolution base context. - bool hasBase(Context context) const { return base == context; } - - /// Get the base type resolution context. - Context getBaseContext() const { return base; } - - /// Test the current type resolution context. - bool is(Context context) const { return this->context == context; } - - /// Get the current type resolution context. - Context getContext() const { return context; } - /// Set the current type resolution context. - void setContext(Context newContext) { - context = newContext; - flags &= ~unsigned(TypeResolutionFlags::Direct); - } - void setContext(llvm::NoneType) { setContext(Context::None); } - - /// Get the current flags. - TypeResolutionFlags getFlags() const { return TypeResolutionFlags(flags); } - - /// Is this type resolution context an expression. - bool isAnyExpr() const { - switch (base) { - case Context::InExpression: - case Context::ExplicitCastExpr: - case Context::ForEachStmt: - case Context::PatternBindingDecl: - case Context::EditorPlaceholderExpr: - case Context::ClosureExpr: - return true; - case Context::None: - case Context::FunctionInput: - case Context::VariadicFunctionInput: - case Context::FunctionResult: - case Context::DynamicSelfResult: - case Context::ProtocolWhereClause: - case Context::ExtensionBinding: - case Context::SubscriptDecl: - case Context::EnumElementDecl: - case Context::EnumPatternPayload: - case Context::TypeAliasDecl: - case Context::GenericRequirement: - case Context::ImmediateOptionalTypeArgument: - case Context::AbstractFunctionDecl: - return false; - } - } - - /// Determine whether all of the given options are set. - bool contains(TypeResolutionFlags set) const { - return !static_cast(unsigned(set) & ~unsigned(flags)); - } - - /// Produce type resolution options with additional flags. - friend TypeResolutionOptions operator|(TypeResolutionOptions lhs, - TypeResolutionFlags rhs) { - return lhs |= rhs; - } - - /// Merge additional flags into type resolution options. - friend TypeResolutionOptions &operator|=(TypeResolutionOptions &lhs, - TypeResolutionFlags rhs) { - lhs.flags |= unsigned(rhs); - return lhs; - } - - /// Test whether any given flag is set in the type resolution options. - friend bool operator&(TypeResolutionOptions lhs, TypeResolutionFlags rhs) { - return lhs.flags & unsigned(rhs); - } - - /// Produce type resolution options with removed flags. - friend TypeResolutionOptions operator-(TypeResolutionOptions lhs, - TypeResolutionFlags rhs) { - return lhs -= rhs; - } - - /// Remove the flags from the type resolution options. - friend TypeResolutionOptions &operator-=(TypeResolutionOptions &lhs, - TypeResolutionFlags rhs) { - lhs.flags &= ~unsigned(rhs); - return lhs; - } - /// Strip the contextual options from the given type resolution options. - inline TypeResolutionOptions withoutContext(bool preserveSIL = false) const { - auto copy = *this; - copy.setContext(None); - // FIXME: Move SILType to TypeResolverContext. - if (!preserveSIL) copy -= TypeResolutionFlags::SILType; - return copy; - } -}; - /// Flags that control protocol conformance checking. enum class ConformanceCheckFlags { /// Whether we're performing the check from within an expression. @@ -1088,7 +852,7 @@ public: /// /// \returns true if type validation failed, or false otherwise. bool validateType(TypeLoc &Loc, TypeResolution resolution, - TypeResolutionOptions options = None); + TypeResolutionOptions options); /// Check for unsupported protocol types in the given declaration. void checkUnsupportedProtocolType(Decl *decl); @@ -1100,21 +864,6 @@ public: GenericEnvironment *handleSILGenericParams(GenericParamList *genericParams, DeclContext *DC); - /// \brief Resolves a TypeRepr to a type. - /// - /// Performs name binding, checking of generic arguments, and so on in order - /// to create a well-formed type. - /// - /// \param TyR The type representation to check. - /// - /// \param resolution The type resolution to perform. - /// - /// \param options Options that alter type resolution. - /// - /// \returns a well-formed type or an ErrorType in case of an error. - static Type resolveType(TypeRepr *TyR, TypeResolution resolution, - TypeResolutionOptions options); - void validateDecl(ValueDecl *D); void validateDecl(OperatorDecl *decl); void validateDecl(PrecedenceGroupDecl *decl); @@ -1456,7 +1205,7 @@ public: bool validateRequirement(SourceLoc whereLoc, RequirementRepr &req, TypeResolution resolution, - TypeResolutionOptions options = None); + TypeResolutionOptions options); /// Validate the given requirements. void validateRequirements(SourceLoc whereLoc,