Skip to content
4 changes: 2 additions & 2 deletions lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/CSSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
11 changes: 6 additions & 5 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ Type ConstraintSystem::openUnboundGenericType(UnboundGenericType *unbound,
// pointing at a generic TypeAliasDecl here. If we find a way to
// handle generic TypeAliases elsewhere, this can just become a
// call to BoundGenericType::get().
return TC.applyUnboundGenericArguments(
return TypeChecker::applyUnboundGenericArguments(
unbound, unboundDecl,
SourceLoc(), TypeResolution::forContextual(DC), arguments);
}
Expand Down Expand Up @@ -980,10 +980,11 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
// Unqualified reference to a type.
if (auto typeDecl = dyn_cast<TypeDecl>(value)) {
// Resolve the reference to this type declaration in our current context.
auto type = TC.resolveTypeInContext(typeDecl, nullptr,
TypeResolution::forContextual(useDC),
TypeResolverContext::InExpression,
/*isSpecialized=*/false);
auto type = TypeChecker::resolveTypeInContext(
typeDecl, nullptr,
TypeResolution::forContextual(useDC),
TypeResolverContext::InExpression,
/*isSpecialized=*/false);

// Open the type.
type = openUnboundGenericType(type, locator);
Expand Down
34 changes: 18 additions & 16 deletions lib/Sema/DerivedConformanceEquatableHashable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,23 @@ using namespace swift;
/// \p theEnum The enum whose elements and associated values should be checked.
/// \p protocol The protocol being requested.
/// \return True if all associated values of all elements of the enum conform.
static bool allAssociatedValuesConformToProtocol(TypeChecker &tc,
DeclContext *DC,
static bool allAssociatedValuesConformToProtocol(DeclContext *DC,
EnumDecl *theEnum,
ProtocolDecl *protocol) {
auto lazyResolver = DC->getASTContext().getLazyResolver();
for (auto elt : theEnum->getAllElements()) {
if (!elt->hasInterfaceType())
tc.validateDecl(elt);
lazyResolver->resolveDeclSignature(elt);

auto PL = elt->getParameterList();
if (!PL)
continue;

for (auto param : *PL) {
auto type = param->getType()->mapTypeOutOfContext();
if (!tc.conformsToProtocol(DC->mapTypeIntoContext(type), protocol, DC,
ConformanceCheckFlags::Used)) {
if (!TypeChecker::conformsToProtocol(DC->mapTypeIntoContext(type),
protocol, DC,
ConformanceCheckFlags::Used)) {
return false;
}
}
Expand All @@ -65,41 +66,42 @@ static bool allAssociatedValuesConformToProtocol(TypeChecker &tc,
/// \p theStruct The struct whose stored properties should be checked.
/// \p protocol The protocol being requested.
/// \return True if all stored properties of the struct conform.
static bool allStoredPropertiesConformToProtocol(TypeChecker &tc,
DeclContext *DC,
static bool allStoredPropertiesConformToProtocol(DeclContext *DC,
StructDecl *theStruct,
ProtocolDecl *protocol) {
auto lazyResolver = DC->getASTContext().getLazyResolver();
auto storedProperties =
theStruct->getStoredProperties(/*skipInaccessible=*/true);
for (auto propertyDecl : storedProperties) {
if (!propertyDecl->hasType())
tc.validateDecl(propertyDecl);
lazyResolver->resolveDeclSignature(propertyDecl);
if (!propertyDecl->hasType())
return false;

auto type = propertyDecl->getType()->mapTypeOutOfContext();
if (!tc.conformsToProtocol(DC->mapTypeIntoContext(type), protocol, DC,
ConformanceCheckFlags::Used)) {
if (!TypeChecker::conformsToProtocol(DC->mapTypeIntoContext(type),
protocol, DC,
ConformanceCheckFlags::Used)) {
return false;
}
}
return true;
}

/// Common preconditions for Equatable and Hashable.
static bool canDeriveConformance(TypeChecker &tc, DeclContext *DC,
static bool canDeriveConformance(DeclContext *DC,
NominalTypeDecl *target,
ProtocolDecl *protocol) {
// The type must be an enum or a struct.
if (auto enumDecl = dyn_cast<EnumDecl>(target)) {
// The cases must not have associated values, or all associated values must
// conform to the protocol.
return allAssociatedValuesConformToProtocol(tc, DC, enumDecl, protocol);
return allAssociatedValuesConformToProtocol(DC, enumDecl, protocol);
}

if (auto structDecl = dyn_cast<StructDecl>(target)) {
// All stored properties of the struct must conform to the protocol.
return allStoredPropertiesConformToProtocol(tc, DC, structDecl, protocol);
return allStoredPropertiesConformToProtocol(DC, structDecl, protocol);
}

return false;
Expand Down Expand Up @@ -675,12 +677,12 @@ deriveEquatable_eq(DerivedConformance &derived,
return eqDecl;
}

bool DerivedConformance::canDeriveEquatable(TypeChecker &tc, DeclContext *DC,
bool DerivedConformance::canDeriveEquatable(DeclContext *DC,
NominalTypeDecl *type) {
ASTContext &ctx = DC->getASTContext();
auto equatableProto = ctx.getProtocol(KnownProtocolKind::Equatable);
if (!equatableProto) return false;
return canDeriveConformance(tc, DC, type, equatableProto);
return canDeriveConformance(DC, type, equatableProto);
}

ValueDecl *DerivedConformance::deriveEquatable(ValueDecl *requirement) {
Expand Down Expand Up @@ -1187,7 +1189,7 @@ ValueDecl *DerivedConformance::deriveHashable(ValueDecl *requirement) {
// Refuse to synthesize Hashable if type isn't a struct or enum, or if it
// has non-Hashable stored properties/associated values.
auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable);
if (!canDeriveConformance(TC, getConformanceContext(), Nominal,
if (!canDeriveConformance(getConformanceContext(), Nominal,
hashableProto)) {
TC.diagnose(ConformanceDecl->getLoc(), diag::type_does_not_conform,
Nominal->getDeclaredType(),
Expand Down
10 changes: 4 additions & 6 deletions lib/Sema/DerivedConformances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ Type DerivedConformance::getProtocolType() const {
return Protocol->getDeclaredType();
}

bool DerivedConformance::derivesProtocolConformance(TypeChecker &TC,
DeclContext *DC,
bool DerivedConformance::derivesProtocolConformance(DeclContext *DC,
NominalTypeDecl *Nominal,
ProtocolDecl *Protocol) {
// Only known protocols can be derived.
Expand All @@ -73,7 +72,7 @@ bool DerivedConformance::derivesProtocolConformance(TypeChecker &TC,
// Enums without associated values can implicitly derive Equatable
// conformance.
case KnownProtocolKind::Equatable:
return canDeriveEquatable(TC, DC, Nominal);
return canDeriveEquatable(DC, Nominal);

// "Simple" enums without availability attributes can explicitly derive
// a CaseIterable conformance.
Expand Down Expand Up @@ -129,7 +128,7 @@ bool DerivedConformance::derivesProtocolConformance(TypeChecker &TC,
if (auto structDecl = dyn_cast<StructDecl>(Nominal)) {
switch (*knownProtocol) {
case KnownProtocolKind::Equatable:
return canDeriveEquatable(TC, DC, Nominal);
return canDeriveEquatable(DC, Nominal);
default:
return false;
}
Expand Down Expand Up @@ -158,8 +157,7 @@ ValueDecl *DerivedConformance::getDerivableRequirement(TypeChecker &tc,
ConformanceCheckFlags::SkipConditionalRequirements)) {
auto DC = conformance->getConcrete()->getDeclContext();
// Check whether this nominal type derives conformances to the protocol.
if (!DerivedConformance::derivesProtocolConformance(tc, DC, nominal,
proto))
if (!DerivedConformance::derivesProtocolConformance(DC, nominal, proto))
return nullptr;
}

Expand Down
7 changes: 2 additions & 5 deletions lib/Sema/DerivedConformances.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,14 @@ class DerivedConformance {
/// declarations for requirements of the protocol that are not satisfied by
/// the type's explicit members.
///
/// \param tc The type checker.
///
/// \param nominal The nominal type for which we are determining whether to
/// derive a witness.
///
/// \param protocol The protocol whose requirements are being derived.
///
/// \return True if the type can implicitly derive a conformance for the
/// given protocol.
static bool derivesProtocolConformance(TypeChecker &tc, DeclContext *DC,
static bool derivesProtocolConformance(DeclContext *DC,
NominalTypeDecl *nominal,
ProtocolDecl *protocol);

Expand Down Expand Up @@ -120,8 +118,7 @@ class DerivedConformance {
/// associated values, and for structs with all-Equatable stored properties.
///
/// \returns True if the requirement can be derived.
static bool canDeriveEquatable(TypeChecker &tc, DeclContext *DC,
NominalTypeDecl *type);
static bool canDeriveEquatable(DeclContext *DC, NominalTypeDecl *type);

/// Derive an Equatable requirement for a type.
///
Expand Down
26 changes: 11 additions & 15 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1777,12 +1777,13 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) {
SmallPtrSet<TypeBase *, 4> 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;

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/TypeCheckConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ namespace {
if (auto PlaceholderE = dyn_cast<EditorPlaceholderExpr>(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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
6 changes: 4 additions & 2 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1068,14 +1068,17 @@ RequirementCheckResult TypeChecker::checkGenericArguments(
}
break;

case RequirementKind::Superclass:
case RequirementKind::Superclass: {
// Superclass requirements.
if (!isSubclassOf(firstType, secondType, dc)) {
// FIXME: Don't use the type checker instance here?
TypeChecker &tc = static_cast<TypeChecker &>(*ctx.getLazyResolver());
if (!tc.isSubclassOf(firstType, secondType, dc)) {
diagnostic = diag::type_does_not_inherit;
diagnosticNote = diag::type_does_not_inherit_or_conform_requirement;
requirementFailure = true;
}
break;
}

case RequirementKind::SameType:
if (!firstType->isEqual(secondType)) {
Expand Down
14 changes: 9 additions & 5 deletions lib/Sema/TypeCheckNameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
if (options.contains(NameLookupFlags::IgnoreAccessControl))
subOptions |= NL_IgnoreAccessControl;

if (!dc->lookupQualified(type, name, subOptions, this, decls))
if (!dc->lookupQualified(type, name, subOptions, nullptr, decls))
return result;

// Look through the declarations, keeping only the unique type declarations.
Expand All @@ -457,9 +457,11 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
auto *typeDecl = cast<TypeDecl>(decl);

// FIXME: This should happen before we attempt shadowing checks.
validateDecl(typeDecl);
if (!typeDecl->hasInterfaceType()) // FIXME: recursion-breaking hack
continue;
if (!typeDecl->hasInterfaceType()) {
dc->getASTContext().getLazyResolver()->resolveDeclSignature(typeDecl);
if (!typeDecl->hasInterfaceType()) // FIXME: recursion-breaking hack
continue;
}

auto memberType = typeDecl->getDeclaredInterfaceType();

Expand Down Expand Up @@ -548,7 +550,9 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
ProtocolConformanceState::CheckingTypeWitnesses)
continue;

auto typeDecl = concrete->getTypeWitnessAndDecl(assocType, this).second;
auto lazyResolver = dc->getASTContext().getLazyResolver();
auto typeDecl =
concrete->getTypeWitnessAndDecl(assocType, lazyResolver).second;

assert(typeDecl && "Missing type witness?");

Expand Down
Loading