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: 6 additions & 9 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
friend struct ::llvm::cast_convert_val;

static DeclContext *castDeclToDeclContext(const Decl *D);


/// If this DeclContext is a GenericType declaration or an
/// extension thereof, return the GenericTypeDecl.
GenericTypeDecl *getAsTypeOrTypeExtensionContext() const;

public:
DeclContext(DeclContextKind Kind, DeclContext *Parent)
: ParentAndKind(Parent, Kind) {
Expand Down Expand Up @@ -232,20 +236,13 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {

/// \returns true if this is a type context, e.g., a struct, a class, an
/// enum, a protocol, or an extension.
bool isTypeContext() const {
return getContextKind() == DeclContextKind::GenericTypeDecl ||
getContextKind() == DeclContextKind::ExtensionDecl;
}
bool isTypeContext() const;

/// \brief Determine whether this is an extension context.
bool isExtensionContext() const {
return getContextKind() == DeclContextKind::ExtensionDecl;
}

/// If this DeclContext is a GenericType declaration or an
/// extension thereof, return the GenericTypeDecl.
GenericTypeDecl *getAsGenericTypeOrGenericTypeExtensionContext() const;

/// If this DeclContext is a NominalType declaration or an
/// extension thereof, return the NominalTypeDecl.
NominalTypeDecl *getAsNominalTypeOrNominalTypeExtensionContext() const;
Expand Down
3 changes: 1 addition & 2 deletions lib/AST/ConformanceLookupTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,8 +801,7 @@ ProtocolConformance *ConformanceLookupTable::getConformance(
return nullptr;

auto *conformingNominal =
cast<NominalTypeDecl>(conformingDC->
getAsGenericTypeOrGenericTypeExtensionContext());
conformingDC->getAsNominalTypeOrNominalTypeExtensionContext();

// Form the conformance.
Type type = entry->getDeclContext()->getDeclaredTypeInContext();
Expand Down
29 changes: 18 additions & 11 deletions lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ASTContext &DeclContext::getASTContext() const {
}

GenericTypeDecl *
DeclContext::getAsGenericTypeOrGenericTypeExtensionContext() const {
DeclContext::getAsTypeOrTypeExtensionContext() const {
switch (getContextKind()) {
case DeclContextKind::Module:
case DeclContextKind::FileUnit:
Expand Down Expand Up @@ -78,32 +78,28 @@ DeclContext::getAsGenericTypeOrGenericTypeExtensionContext() const {
/// extension thereof, return the NominalTypeDecl.
NominalTypeDecl *DeclContext::
getAsNominalTypeOrNominalTypeExtensionContext() const {
auto decl = getAsGenericTypeOrGenericTypeExtensionContext();
auto decl = getAsTypeOrTypeExtensionContext();
return dyn_cast_or_null<NominalTypeDecl>(decl);
}


ClassDecl *DeclContext::getAsClassOrClassExtensionContext() const {
return dyn_cast_or_null<ClassDecl>(
getAsGenericTypeOrGenericTypeExtensionContext());
return dyn_cast_or_null<ClassDecl>(getAsTypeOrTypeExtensionContext());
}

EnumDecl *DeclContext::getAsEnumOrEnumExtensionContext() const {
return dyn_cast_or_null<EnumDecl>(
getAsGenericTypeOrGenericTypeExtensionContext());
return dyn_cast_or_null<EnumDecl>(getAsTypeOrTypeExtensionContext());
}

ProtocolDecl *DeclContext::getAsProtocolOrProtocolExtensionContext() const {
return dyn_cast_or_null<ProtocolDecl>(
getAsGenericTypeOrGenericTypeExtensionContext());
return dyn_cast_or_null<ProtocolDecl>(getAsTypeOrTypeExtensionContext());
}

ProtocolDecl *DeclContext::getAsProtocolExtensionContext() const {
if (getContextKind() != DeclContextKind::ExtensionDecl)
return nullptr;

return dyn_cast_or_null<ProtocolDecl>(
getAsGenericTypeOrGenericTypeExtensionContext());
return dyn_cast_or_null<ProtocolDecl>(getAsTypeOrTypeExtensionContext());
}

GenericTypeParamType *DeclContext::getProtocolSelfType() const {
Expand Down Expand Up @@ -357,6 +353,11 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() {
}
}

bool DeclContext::isTypeContext() const {
return isa<NominalTypeDecl>(this) ||
getContextKind() == DeclContextKind::ExtensionDecl;
}

DeclContext *DeclContext::getInnermostTypeContext() {
DeclContext *Result = this;
while (true) {
Expand All @@ -374,8 +375,14 @@ DeclContext *DeclContext::getInnermostTypeContext() {
case DeclContextKind::FileUnit:
return nullptr;

case DeclContextKind::ExtensionDecl:
case DeclContextKind::GenericTypeDecl:
if (isa<TypeAliasDecl>(Result)) {
Result = Result->getParent();
continue;
}
return Result;

case DeclContextKind::ExtensionDecl:
return Result;
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/AST/NameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,8 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
DC = I->getParent()->getParent();
continue;
} else {
assert(isa<TopLevelCodeDecl>(DC) || isa<Initializer>(DC));
assert(isa<TopLevelCodeDecl>(DC) || isa<Initializer>(DC) ||
isa<TypeAliasDecl>(DC));
if (!isCascadingUse.hasValue())
isCascadingUse = DC->isCascadingContextForLookup(false);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4069,9 +4069,9 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {

void addAccessControl(const ValueDecl *VD,
CodeCompletionResultBuilder &Builder) {
assert(CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext());
assert(CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext());
auto AccessibilityOfContext =
CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext()
CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext()
->getFormalAccess();
auto Access = std::min(VD->getFormalAccess(), AccessibilityOfContext);
// Only emit 'public', not needed otherwise.
Expand Down Expand Up @@ -4309,7 +4309,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
}

void getOverrideCompletions(SourceLoc Loc) {
if (!CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext())
if (!CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext())
return;

Type CurrTy = CurrDeclContext->getDeclaredTypeInContext();
Expand Down
1 change: 0 additions & 1 deletion lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3827,7 +3827,6 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage,
SmallVectorImpl<Decl *> &decls) {
auto flagInvalidAccessor = [&](FuncDecl *&func) {
if (func) {
func->setInterfaceType(ErrorType::get(P.Context));
func->setInvalid();
}
};
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ namespace {
if (!isa<ConstructorDecl>(fn))
return false;
auto *parent =
fn->getParent()->getAsGenericTypeOrGenericTypeExtensionContext();
fn->getParent()->getAsNominalTypeOrNominalTypeExtensionContext();
return parent && (isa<ClassDecl>(parent) || isa<ProtocolDecl>(parent));
}

Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/CSDiag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4671,8 +4671,8 @@ static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
};

auto getBaseName = [](DeclContext *context) -> DeclName {
if (context->isTypeContext()) {
auto generic = context->getAsGenericTypeOrGenericTypeExtensionContext();
if (auto generic =
context->getAsNominalTypeOrNominalTypeExtensionContext()) {
return generic->getName();
} else if (context->isModuleScopeContext())
return context->getParentModule()->getName();
Expand Down
29 changes: 0 additions & 29 deletions lib/Sema/GenericTypeResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,35 +159,6 @@ class GenericTypeToArchetypeResolver : public GenericTypeResolver {
virtual void recordParamType(ParamDecl *decl, Type ty);
};

/// Generic type resolver that maps any generic type parameter type that
/// has an underlying archetype to its corresponding archetype.
///
/// This generic type resolver replaces generic type parameter types that
/// have archetypes with their archetypes, and leaves all other generic
/// type parameter types unchanged. It is used for the initial type-checks of
/// generic functions (and other generic declarations).
///
/// FIXME: This is not a long-term solution.
class PartialGenericTypeToArchetypeResolver : public GenericTypeResolver {
public:
virtual Type resolveGenericTypeParamType(GenericTypeParamType *gp);

virtual Type resolveDependentMemberType(Type baseTy,
DeclContext *DC,
SourceRange baseRange,
ComponentIdentTypeRepr *ref);

virtual Type resolveSelfAssociatedType(Type selfTy,
DeclContext *DC,
AssociatedTypeDecl *assocType);

virtual Type resolveTypeOfContext(DeclContext *dc, bool wantSelf=false);

virtual Type resolveTypeOfDecl(TypeDecl *decl);

virtual void recordParamType(ParamDecl *decl, Type ty);
};

/// Generic type resolver that performs complete resolution of dependent
/// types based on a given archetype builder.
///
Expand Down
5 changes: 3 additions & 2 deletions lib/Sema/ITCDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void IterativeTypeChecker::processResolveInheritedClauseEntry(

// Validate the type of this inherited clause entry.
// FIXME: Recursion into existing type checker.
PartialGenericTypeToArchetypeResolver resolver;
GenericTypeToArchetypeResolver resolver(dc);
if (TC.validateType(*inherited, dc, options, &resolver)) {
inherited->setInvalidType(getASTContext());
}
Expand Down Expand Up @@ -314,9 +314,10 @@ void IterativeTypeChecker::processResolveTypeDecl(

// Note: recursion into old type checker is okay when passing in an
// unsatisfied-dependency callback.
GenericTypeToArchetypeResolver resolver(typeAliasDecl);
if (TC.validateType(typeAliasDecl->getUnderlyingTypeLoc(),
typeAliasDecl->getDeclContext(),
options, nullptr, &unsatisfiedDependency)) {
options, &resolver, &unsatisfiedDependency)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the parameter is always non-null, it could be a reference

typeAliasDecl->setInvalid();
typeAliasDecl->setInterfaceType(ErrorType::get(getASTContext()));
typeAliasDecl->getUnderlyingTypeLoc().setInvalidType(getASTContext());
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/TypeCheckConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,8 +937,7 @@ bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) {
options |= TR_InExpression;
bool hadParameterError = false;

GenericTypeToArchetypeResolver resolver(
closure->getGenericEnvironmentOfContext());
GenericTypeToArchetypeResolver resolver(closure);

if (TC.typeCheckParameterList(PL, DC, options, resolver)) {
closure->setType(ErrorType::get(TC.Context));
Expand Down
Loading