Skip to content

Remove almost all remaining uses of DeclChecker::IsFirstPass #15703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
4 changes: 0 additions & 4 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -666,10 +666,6 @@ NOTE(note_typo_candidate_implicit_member,none,
"did you mean the implicitly-synthesized %1 '%0'?", (StringRef, StringRef))
NOTE(note_remapped_type,none,
"did you mean to use '%0'?", (StringRef))
ERROR(identifier_init_failure,none,
"could not infer type for %0", (Identifier))
ERROR(pattern_used_in_type,none,
"%0 used within its own type", (Identifier))
NOTE(note_module_as_type,none,
"cannot use module %0 as a type", (Identifier))

Expand Down
65 changes: 0 additions & 65 deletions include/swift/AST/LazyResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,71 +101,6 @@ class LazyResolver {
DeclContext *dc) = 0;
};

/// An implementation of LazyResolver that delegates to another.
class DelegatingLazyResolver : public LazyResolver {
protected:
LazyResolver &Principal;
public:
DelegatingLazyResolver(LazyResolver &principal) : Principal(principal) {}
~DelegatingLazyResolver(); // v-table anchor

void resolveTypeWitness(const NormalProtocolConformance *conformance,
AssociatedTypeDecl *assocType) override {
Principal.resolveTypeWitness(conformance, assocType);
}

void resolveWitness(const NormalProtocolConformance *conformance,
ValueDecl *requirement) override {
Principal.resolveWitness(conformance, requirement);
}

void resolveAccessControl(ValueDecl *VD) override {
Principal.resolveAccessControl(VD);
}

void resolveDeclSignature(ValueDecl *VD) override {
Principal.resolveDeclSignature(VD);
}

void resolveInheritanceClause(
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl) override {
Principal.resolveInheritanceClause(decl);
}

void resolveSuperclass(ClassDecl *classDecl) override {
Principal.resolveSuperclass(classDecl);
}

void resolveRawType(EnumDecl *enumDecl) override {
Principal.resolveRawType(enumDecl);
}

void resolveInheritedProtocols(ProtocolDecl *protocol) override {
Principal.resolveInheritedProtocols(protocol);
}

void bindExtension(ExtensionDecl *ext) override {
Principal.bindExtension(ext);
}

void resolveExtension(ExtensionDecl *ext) override {
Principal.resolveExtension(ext);
}

void resolveImplicitConstructors(NominalTypeDecl *nominal) override {
Principal.resolveImplicitConstructors(nominal);
}

void resolveImplicitMember(NominalTypeDecl *nominal, DeclName member) override {
Principal.resolveImplicitMember(nominal, member);
}

void markConformanceUsed(ProtocolConformanceRef conformance,
DeclContext *dc) override {
return Principal.markConformanceUsed(conformance, dc);
}
};

class LazyMemberLoader;

/// Context data for lazy deserialization.
Expand Down
1 change: 0 additions & 1 deletion lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ STATISTIC(NumCollapsedSpecializedProtocolConformances,
#define SWIFT_GSB_EXPENSIVE_ASSERTIONS 0

LazyResolver::~LazyResolver() = default;
DelegatingLazyResolver::~DelegatingLazyResolver() = default;
void ModuleLoader::anchor() {}
void ClangModuleLoader::anchor() {}

Expand Down
151 changes: 74 additions & 77 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3974,6 +3974,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

DeclVisitor<DeclChecker>::visit(decl);

if (IsFirstPass)
TC.checkUnsupportedProtocolType(decl);

if (auto VD = dyn_cast<ValueDecl>(decl)) {
checkRedeclaration(TC, VD);

Expand All @@ -3995,17 +3998,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
"`" + VD->getBaseName().userFacingName().str() + "`");
}
}

if (!IsFirstPass) {
TC.checkUnsupportedProtocolType(decl);
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
TC.checkDeclCircularity(nominal);
}
if (auto protocol = dyn_cast<ProtocolDecl>(decl)) {
if (protocol->isResilient())
TC.inferDefaultWitnesses(protocol);
}
}
}

//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -4143,66 +4135,59 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
}

void visitPatternBindingDecl(PatternBindingDecl *PBD) {
// Check all the pattern/init pairs in the PBD.
validatePatternBindingEntries(TC, PBD);
if (!IsFirstPass)
return;

if (PBD->isBeingValidated())
return;

// If the initializers in the PBD aren't checked yet, do so now.
if (!IsFirstPass) {
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
if (!PBD->isInitializerChecked(i) && PBD->getInit(i))
TC.typeCheckPatternBinding(PBD, i, /*skipApplyingSolution*/false);
}
}
// Check all the pattern/init pairs in the PBD.
validatePatternBindingEntries(TC, PBD);

TC.checkDeclAttributesEarly(PBD);

if (IsFirstPass) {
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
// Type check each VarDecl that this PatternBinding handles.
visitBoundVars(PBD->getPattern(i));
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
// Type check each VarDecl that this PatternBinding handles.
visitBoundVars(PBD->getPattern(i));

// If we have a type but no initializer, check whether the type is
// default-initializable. If so, do it.
if (PBD->getPattern(i)->hasType() &&
!PBD->getInit(i) &&
PBD->getPattern(i)->hasStorage() &&
!PBD->getPattern(i)->getType()->hasError()) {
// If we have a type but no initializer, check whether the type is
// default-initializable. If so, do it.
if (PBD->getPattern(i)->hasType() &&
!PBD->getInit(i) &&
PBD->getPattern(i)->hasStorage() &&
!PBD->getPattern(i)->getType()->hasError()) {

// If we have a type-adjusting attribute (like ownership), apply it now.
if (auto var = PBD->getSingleVar())
TC.checkTypeModifyingDeclAttributes(var);
// If we have a type-adjusting attribute (like ownership), apply it now.
if (auto var = PBD->getSingleVar())
TC.checkTypeModifyingDeclAttributes(var);

// Decide whether we should suppress default initialization.
//
// Note: Swift 4 had a bug where properties with a desugared optional
// type like Optional<Int> had a half-way behavior where sometimes
// they behave like they are default initialized, and sometimes not.
//
// In Swift 5 mode, use the right condition here, and only default
// initialize properties with a sugared Optional type.
//
// (The restriction to sugared types only comes because we don't have
// the iterative declaration checker yet; so in general, we cannot
// look at the type of a property at all, and can only look at the
// TypeRepr, because we haven't validated the property yet.)
if (TC.Context.isSwiftVersionAtLeast(5)) {
if (!PBD->isDefaultInitializable(i))
continue;
} else {
if (PBD->getPattern(i)->isNeverDefaultInitializable())
continue;
}
// Decide whether we should suppress default initialization.
//
// Note: Swift 4 had a bug where properties with a desugared optional
// type like Optional<Int> had a half-way behavior where sometimes
// they behave like they are default initialized, and sometimes not.
//
// In Swift 5 mode, use the right condition here, and only default
// initialize properties with a sugared Optional type.
//
// (The restriction to sugared types only comes because we don't have
// the iterative declaration checker yet; so in general, we cannot
// look at the type of a property at all, and can only look at the
// TypeRepr, because we haven't validated the property yet.)
if (TC.Context.isSwiftVersionAtLeast(5)) {
if (!PBD->isDefaultInitializable(i))
continue;
} else {
if (PBD->getPattern(i)->isNeverDefaultInitializable())
continue;
}

auto type = PBD->getPattern(i)->getType();
if (auto defaultInit = buildDefaultInitializer(TC, type)) {
// If we got a default initializer, install it and re-type-check it
// to make sure it is properly coerced to the pattern type.
PBD->setInit(i, defaultInit);
TC.typeCheckPatternBinding(PBD, i, /*skipApplyingSolution*/false);
}
auto type = PBD->getPattern(i)->getType();
if (auto defaultInit = buildDefaultInitializer(TC, type)) {
// If we got a default initializer, install it and re-type-check it
// to make sure it is properly coerced to the pattern type.
PBD->setInit(i, defaultInit);
TC.typeCheckPatternBinding(PBD, i, /*skipApplyingSolution*/false);
}
}
}
Expand Down Expand Up @@ -4269,9 +4254,13 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
}

TC.checkDeclAttributes(PBD);
checkAccessControl(TC, PBD);

if (IsFirstPass)
checkAccessControl(TC, PBD);
// If the initializers in the PBD aren't checked yet, do so now.
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
if (!PBD->isInitializerChecked(i) && PBD->getInit(i))
TC.typeCheckPatternBinding(PBD, i, /*skipApplyingSolution*/false);
}
}

void visitSubscriptDecl(SubscriptDecl *SD) {
Expand Down Expand Up @@ -4396,6 +4385,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
// enums haven't.
checkEnumRawValues(TC, ED);
}

TC.checkDeclCircularity(ED);
}

void visitStructDecl(StructDecl *SD) {
Expand All @@ -4422,6 +4413,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

TC.checkDeclAttributes(SD);
checkAccessControl(TC, SD);

TC.checkDeclCircularity(SD);
}

/// Check whether the given properties can be @NSManaged in this class.
Expand Down Expand Up @@ -4654,6 +4647,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

TC.checkDeclAttributes(CD);
checkAccessControl(TC, CD);

TC.checkDeclCircularity(CD);
}

void visitProtocolDecl(ProtocolDecl *PD) {
Expand Down Expand Up @@ -4710,6 +4705,10 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
GenericTypeToArchetypeResolver resolver(PD);
TC.validateWhereClauses(PD, &resolver);

TC.checkDeclCircularity(PD);
if (PD->isResilient())
TC.inferDefaultWitnesses(PD);

if (TC.Context.LangOpts.DebugGenericSignatures) {
auto requirementsSig =
GenericSignature::get({PD->getProtocolSelfType()},
Expand Down Expand Up @@ -7039,6 +7038,10 @@ void TypeChecker::validateDecl(ValueDecl *D) {
case DeclKind::Param: {
auto VD = cast<VarDecl>(D);

if (PatternBindingDecl *PBD = VD->getParentPatternBinding())
if (PBD->isBeingValidated())
return;

D->setIsBeingValidated();

if (!VD->hasInterfaceType()) {
Expand All @@ -7049,25 +7052,12 @@ void TypeChecker::validateDecl(ValueDecl *D) {
}
recordSelfContextType(cast<AbstractFunctionDecl>(VD->getDeclContext()));
} else if (PatternBindingDecl *PBD = VD->getParentPatternBinding()) {
if (PBD->isBeingValidated()) {
diagnose(VD, diag::pattern_used_in_type, VD->getName());

} else {
validatePatternBindingEntries(*this, PBD);
}
validatePatternBindingEntries(*this, PBD);

auto parentPattern = VD->getParentPattern();
if (PBD->isInvalid() || !parentPattern->hasType()) {
parentPattern->setType(ErrorType::get(Context));
setBoundVarsTypeError(parentPattern, Context);

// If no type has been set for the initializer, we need to diagnose
// the failure.
if (VD->getParentInitializer() &&
!VD->getParentInitializer()->getType()) {
diagnose(parentPattern->getLoc(), diag::identifier_init_failure,
parentPattern->getBoundName());
}
}
} else {
// FIXME: This case is hit when code completion occurs in a function
Expand Down Expand Up @@ -7175,6 +7165,14 @@ void TypeChecker::validateDecl(ValueDecl *D) {
auto *FD = cast<FuncDecl>(D);
assert(!FD->hasInterfaceType());

// Bail out if we're in a recursive validation situation.
if (auto accessor = dyn_cast<AccessorDecl>(FD)) {
auto *storage = accessor->getStorage();
validateDecl(storage);
if (!storage->hasValidSignature())
return;
}

checkDeclAttributesEarly(FD);
computeAccessLevel(FD);

Expand Down Expand Up @@ -7211,7 +7209,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
// FIXME: should this include the generic signature?
if (auto accessor = dyn_cast<AccessorDecl>(FD)) {
auto storage = accessor->getStorage();
validateDecl(storage);

// Note that it's important for correctness that we're filling in
// empty TypeLocs, because otherwise revertGenericFuncSignature might
Expand Down
27 changes: 2 additions & 25 deletions lib/Sema/TypeCheckNameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,28 +539,6 @@ static bool isLocInVarInit(TypeChecker &TC, VarDecl *var, SourceLoc loc) {
return TC.Context.SourceMgr.rangeContainsTokenLoc(initRange, loc);
}

namespace {
class TypoCorrectionResolver : public DelegatingLazyResolver {
TypeChecker &TC() { return static_cast<TypeChecker&>(Principal); }
SourceLoc NameLoc;
public:
TypoCorrectionResolver(TypeChecker &TC, SourceLoc nameLoc)
: DelegatingLazyResolver(TC), NameLoc(nameLoc) {}

void resolveDeclSignature(ValueDecl *VD) override {
if (VD->isInvalid() || VD->hasInterfaceType()) return;

// Don't process a variable if we're within its initializer.
if (auto var = dyn_cast<VarDecl>(VD)) {
if (isLocInVarInit(TC(), var, NameLoc))
return;
}

DelegatingLazyResolver::resolveDeclSignature(VD);
}
};
} // end anonymous namespace

void TypeChecker::performTypoCorrection(DeclContext *DC, DeclRefKind refKind,
Type baseTypeOrNull,
DeclName targetDeclName,
Expand Down Expand Up @@ -608,12 +586,11 @@ void TypeChecker::performTypoCorrection(DeclContext *DC, DeclRefKind refKind,
entries.insert(distance, std::move(decl));
});

TypoCorrectionResolver resolver(*this, nameLoc);
if (baseTypeOrNull) {
lookupVisibleMemberDecls(consumer, baseTypeOrNull, DC, &resolver,
lookupVisibleMemberDecls(consumer, baseTypeOrNull, DC, this,
/*include instance members*/ true, gsb);
} else {
lookupVisibleDecls(consumer, DC, &resolver, /*top level*/ true, nameLoc);
lookupVisibleDecls(consumer, DC, this, /*top level*/ true, nameLoc);
}

// Impose a maximum distance from the best score.
Expand Down
Loading