Skip to content

Commit f8bf365

Browse files
committed
Rebrand TR_NominalInheritanceClause as TR_GenericSignature, and support functions.
It’s real intent is to check only the generic signature of the DeclContext provided to name lookup, then enclosing contexts. Use it for functions and initializers as well, so we have uniform lookup behavior for entities that can have generic parameters. A follow-up commit contains some minor, semi-related tweaks along with a pile of updates to the compiler crash testsuite. Swift SVN r26654
1 parent 09d665d commit f8bf365

File tree

4 files changed

+50
-46
lines changed

4 files changed

+50
-46
lines changed

lib/Sema/TypeCheckDecl.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,10 @@ void TypeChecker::resolveRawType(EnumDecl *enumDecl) {
265265
}
266266

267267
void TypeChecker::resolveInheritanceClause(DeclContext *dc) {
268-
TypeResolutionOptions options;
269-
270268
// FIXME: Add a cached bit so this isn't O(n) in repeated calls.
271269
MutableArrayRef<TypeLoc> inheritanceClause;
272270
if (auto nominal = dyn_cast<NominalTypeDecl>(dc)) {
273271
inheritanceClause = nominal->getInherited();
274-
options |= TR_NominalInheritanceClause;
275272
} else {
276273
auto ext = cast<ExtensionDecl>(dc);
277274
inheritanceClause = ext->getInherited();
@@ -281,7 +278,7 @@ void TypeChecker::resolveInheritanceClause(DeclContext *dc) {
281278
PartialGenericTypeToArchetypeResolver resolver(*this);
282279

283280
for (auto &inherited : inheritanceClause) {
284-
if (validateType(inherited, dc, options, &resolver)) {
281+
if (validateType(inherited, dc, TR_GenericSignature, &resolver)) {
285282
inherited.setInvalidType(Context);
286283
continue;
287284
}
@@ -299,20 +296,23 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
299296
DeclContext *DC;
300297
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
301298
DC = nominal;
302-
options |= TR_NominalInheritanceClause;
299+
options |= TR_GenericSignature;
303300
} else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
304301
DC = ext;
305-
options |= TR_NominalInheritanceClause;
302+
options |= TR_GenericSignature;
306303
} else if (isa<GenericTypeParamDecl>(decl)) {
307304
// For generic parameters, we want name lookup to look at just the
308305
// signature of the enclosing entity.
309306
DC = decl->getDeclContext();
310307
if (auto nominal = dyn_cast<NominalTypeDecl>(DC)) {
311308
DC = nominal;
312-
options |= TR_NominalInheritanceClause;
309+
options |= TR_GenericSignature;
313310
} else if (auto ext = dyn_cast<ExtensionDecl>(DC)) {
314311
DC = ext;
315-
options |= TR_NominalInheritanceClause;
312+
options |= TR_GenericSignature;
313+
} else if (auto func = dyn_cast<AbstractFunctionDecl>(DC)) {
314+
DC = func;
315+
options |= TR_GenericSignature;
316316
} else if (!DC->isModuleScopeContext()) {
317317
// Skip the generic parameter's context entirely.
318318
DC = DC->getParent();

lib/Sema/TypeCheckType.cpp

+33-29
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ Type TypeChecker::applyGenericArguments(Type type,
297297
SourceLoc loc,
298298
DeclContext *dc,
299299
MutableArrayRef<TypeLoc> genericArgs,
300-
bool isNominalInheritanceClause,
300+
bool isGenericSignature,
301301
GenericTypeResolver *resolver) {
302302
// Make sure we always have a resolver to use.
303303
PartialGenericTypeToArchetypeResolver defaultResolver(*this);
@@ -330,8 +330,8 @@ Type TypeChecker::applyGenericArguments(Type type,
330330
}
331331

332332
TypeResolutionOptions options;
333-
if (isNominalInheritanceClause)
334-
options |= TR_NominalInheritanceClause;
333+
if (isGenericSignature)
334+
options |= TR_GenericSignature;
335335

336336
// Validate the generic arguments and capture just the types.
337337
SmallVector<Type, 4> genericArgTypes;
@@ -370,13 +370,13 @@ Type TypeChecker::applyGenericArguments(Type type,
370370
static Type applyGenericTypeReprArgs(TypeChecker &TC, Type type, SourceLoc loc,
371371
DeclContext *dc,
372372
ArrayRef<TypeRepr *> genericArgs,
373-
bool isNominalInheritanceClause,
373+
bool isGenericSignature,
374374
GenericTypeResolver *resolver) {
375375
SmallVector<TypeLoc, 8> args;
376376
for (auto tyR : genericArgs)
377377
args.push_back(tyR);
378378
Type ty = TC.applyGenericArguments(type, loc, dc, args,
379-
isNominalInheritanceClause, resolver);
379+
isGenericSignature, resolver);
380380
if (!ty)
381381
return ErrorType::get(TC.Context);
382382
return ty;
@@ -396,7 +396,7 @@ static Type resolveTypeDecl(TypeChecker &TC, TypeDecl *typeDecl, SourceLoc loc,
396396
DeclContext *dc,
397397
ArrayRef<TypeRepr *> genericArgs,
398398
bool allowUnboundGenerics,
399-
bool isNominalInheritanceClause,
399+
bool isGenericSignature,
400400
GenericTypeResolver *resolver) {
401401
TC.validateDecl(typeDecl);
402402

@@ -432,7 +432,7 @@ static Type resolveTypeDecl(TypeChecker &TC, TypeDecl *typeDecl, SourceLoc loc,
432432
if (!genericArgs.empty()) {
433433
// Apply the generic arguments to the type.
434434
type = applyGenericTypeReprArgs(TC, type, loc, dc, genericArgs,
435-
isNominalInheritanceClause, resolver);
435+
isGenericSignature, resolver);
436436
}
437437

438438
assert(type);
@@ -459,15 +459,15 @@ static NominalTypeDecl *getEnclosingNominalContext(DeclContext *dc) {
459459
/// \param dc The context in which name lookup occurred.
460460
/// \param components The components that refer to the type, where the last
461461
/// component refers to the type that could not be found.
462-
/// \param isNominalInheritanceClause True if this type is in a nominal's
463-
/// inheritance clause.
462+
/// \param isGenericSignature True if we're only looking into the generic
463+
/// signature of the given context.
464464
///
465465
/// \returns true if we could not fix the type reference, false if
466466
/// typo correction (or some other mechanism) was able to fix the
467467
/// reference.
468468
static bool diagnoseUnknownType(TypeChecker &tc, DeclContext *dc,
469469
ArrayRef<ComponentIdentTypeRepr *> components,
470-
bool isNominalInheritanceClause,
470+
bool isGenericSignature,
471471
GenericTypeResolver *resolver) {
472472
auto comp = components.back();
473473

@@ -483,7 +483,7 @@ static bool diagnoseUnknownType(TypeChecker &tc, DeclContext *dc,
483483
assert(!isa<ProtocolDecl>(nominal) && "Cannot be a protocol");
484484
auto type = resolveTypeDecl(tc, nominal, comp->getIdLoc(), dc, { },
485485
/*allowUnboundGenerics=*/false,
486-
isNominalInheritanceClause, resolver);
486+
isGenericSignature, resolver);
487487
if (type->is<ErrorType>())
488488
return true;
489489

@@ -561,7 +561,7 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
561561
// Resolve the first component, which is the only one that requires
562562
// unqualified name lookup.
563563
DeclContext *lookupDC = DC;
564-
if (options.contains(TR_NominalInheritanceClause))
564+
if (options.contains(TR_GenericSignature))
565565
lookupDC = DC->getParent();
566566
UnqualifiedLookup Globals(comp->getIdentifier(), lookupDC, &TC,
567567
options.contains(TR_KnownNonCascadingDependency),
@@ -601,7 +601,7 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
601601
Type type = resolveTypeDecl(TC, typeDecl, comp->getIdLoc(),
602602
DC, genericArgs,
603603
options.contains(TR_AllowUnboundGenerics),
604-
options.contains(TR_NominalInheritanceClause),
604+
options.contains(TR_GenericSignature),
605605
resolver);
606606
if (type->is<ErrorType>()) {
607607
comp->setValue(type);
@@ -650,7 +650,7 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
650650
// source, bail out.
651651
if (!diagnoseErrors ||
652652
diagnoseUnknownType(TC, DC, comp,
653-
options.contains(TR_NominalInheritanceClause),
653+
options.contains(TR_GenericSignature),
654654
resolver)) {
655655
Type ty = ErrorType::get(TC.Context);
656656
comp->setValue(ty);
@@ -671,15 +671,17 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
671671
if (parentComps.empty()) {
672672
TypeResolutionOptions lookupOptions = options;
673673

674-
// For inheritance clause lookups, don't actually look into the type.
675-
// Just look at the generic parameters, and then move up to the enclosing
676-
// context.
677-
if (options.contains(TR_NominalInheritanceClause)) {
674+
// For lookups within the generic signature, look at the generic
675+
// parameters (only), then move up to the enclosing context.
676+
if (options.contains(TR_GenericSignature)) {
678677
GenericParamList *genericParams;
679-
if (auto *nominal = dyn_cast<NominalTypeDecl>(DC))
678+
if (auto *nominal = dyn_cast<NominalTypeDecl>(DC)) {
680679
genericParams = nominal->getGenericParams();
681-
else
682-
genericParams = cast<ExtensionDecl>(DC)->getGenericParams();
680+
} else if (auto *ext = dyn_cast<ExtensionDecl>(DC)) {
681+
genericParams = ext->getGenericParams();
682+
} else {
683+
genericParams = cast<AbstractFunctionDecl>(DC)->getGenericParams();
684+
}
683685

684686
if (!isa<GenericIdentTypeRepr>(comp)) {
685687
if (genericParams) {
@@ -773,13 +775,14 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
773775
}
774776

775777
// If we didn't find anything, complain.
776-
bool isNominal = options.contains(TR_NominalInheritanceClause);
778+
bool isGenericSignature = options.contains(TR_GenericSignature);
777779
bool recovered = false;
778780
if (!memberTypes) {
779781
// If we're not allowed to complain or we couldn't fix the
780782
// source, bail out.
781783
if (!diagnoseErrors ||
782-
diagnoseUnknownType(TC, DC, components, isNominal, resolver)) {
784+
diagnoseUnknownType(TC, DC, components, isGenericSignature,
785+
resolver)) {
783786
Type ty = ErrorType::get(TC.Context);
784787
comp->setValue(ty);
785788
return ty;
@@ -804,7 +807,7 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
804807
memberType = applyGenericTypeReprArgs(TC, memberType,
805808
genComp->getIdLoc(),
806809
DC, genComp->getGenericArgs(),
807-
isNominal, resolver);
810+
isGenericSignature, resolver);
808811

809812
comp->setValue(memberType);
810813
return memberType;
@@ -836,11 +839,12 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
836839
}
837840

838841
// If we didn't find a type, complain.
839-
bool isNominal = options.contains(TR_NominalInheritanceClause);
842+
bool isGenericSignature = options.contains(TR_GenericSignature);
840843
bool recovered = false;
841844
if (!foundModuleTypes) {
842845
if (!diagnoseErrors ||
843-
diagnoseUnknownType(TC, DC, components, isNominal, resolver)) {
846+
diagnoseUnknownType(TC, DC, components, isGenericSignature,
847+
resolver)) {
844848
Type ty = ErrorType::get(TC.Context);
845849
comp->setValue(ty);
846850
return ty;
@@ -856,7 +860,7 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
856860
if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
857861
foundType = applyGenericTypeReprArgs(TC, foundType, genComp->getIdLoc(),
858862
DC, genComp->getGenericArgs(),
859-
isNominal, resolver);
863+
isGenericSignature, resolver);
860864
}
861865

862866
comp->setValue(foundType);
@@ -888,7 +892,7 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
888892
Type type = resolveTypeDecl(TC, typeDecl, comp->getIdLoc(), DC,
889893
genericArgs,
890894
options.contains(TR_AllowUnboundGenerics),
891-
options.contains(TR_NominalInheritanceClause),
895+
options.contains(TR_GenericSignature),
892896
resolver);
893897
comp->setValue(type);
894898
return type;
@@ -1739,7 +1743,7 @@ Type TypeResolver::resolveDictionaryType(DictionaryTypeRepr *repr,
17391743
TypeLoc args[2] = { TypeLoc(repr->getKey()), TypeLoc(repr->getValue()) };
17401744

17411745
if (!TC.applyGenericArguments(unboundTy, repr->getStartLoc(), DC, args,
1742-
options.contains(TR_NominalInheritanceClause),
1746+
options.contains(TR_GenericSignature),
17431747
Resolver)) {
17441748
return ErrorType::get(TC.Context);
17451749
}

lib/Sema/TypeChecker.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,9 @@ enum TypeResolutionFlags {
209209
/// Whether we are the variable type in a for/in statement.
210210
TR_EnumerationVariable = 0x200,
211211

212-
/// Whether this type is being used in the inheritance clause of a nominal
213-
/// type.
214-
TR_NominalInheritanceClause = 0x800,
212+
/// Whether we are looking only in the generic signature of the context
213+
/// we're searching, rather than the entire context.
214+
TR_GenericSignature = 0x800,
215215

216216
/// Whether this type is the referent of a global type alias.
217217
TR_GlobalTypeAlias = 0x1000,
@@ -507,8 +507,8 @@ class TypeChecker final : public LazyResolver {
507507
/// \param loc The source location for diagnostic reporting.
508508
/// \param dc The context where the arguments are applied.
509509
/// \param genericArgs The list of generic arguments to apply to the type.
510-
/// \param isNominalInheritanceClause True if these generic arguments appear
511-
/// in the inheritance clause of a nominal type.
510+
/// \param isGenericSignature True if we are looking only in the generic
511+
/// signature of the context.
512512
/// \param resolver The generic type resolver.
513513
///
514514
/// \returns A BoundGenericType bound to the given arguments, or null on
@@ -517,7 +517,7 @@ class TypeChecker final : public LazyResolver {
517517
SourceLoc loc,
518518
DeclContext *dc,
519519
MutableArrayRef<TypeLoc> genericArgs,
520-
bool isNominalInheritanceClause,
520+
bool isGenericSignature,
521521
GenericTypeResolver *resolver);
522522

523523
/// \brief Substitute the given base type into the type of the given member,

test/Sema/circular_decl_checking.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ class HasFunc {
1515
}
1616

1717
class HasGenericFunc {
18-
func HasGenericFunc<HasGenericFunc : HasGenericFunc>(x: HasGenericFunc) -> HasGenericFunc { // expected-error {{use of undeclared type 'HasGenericFunc'}}
18+
func HasGenericFunc<HasGenericFunc : HasGenericFunc>(x: HasGenericFunc) -> HasGenericFunc { // expected-error {{inheritance from non-protocol, non-class type 'HasGenericFunc'}}
1919
return x
2020
}
21-
func SomethingElse<SomethingElse : SomethingElse>(_: SomethingElse) -> SomethingElse? { // expected-error {{use of undeclared type 'SomethingElse'}}
21+
func SomethingElse<SomethingElse : SomethingElse>(_: SomethingElse) -> SomethingElse? { // expected-error {{inheritance from non-protocol, non-class type 'SomethingElse'}}
2222
return nil
2323
}
2424
}
@@ -38,6 +38,6 @@ protocol ReferenceSomeProtocol {
3838
}
3939

4040
func TopLevelFunc(x: TopLevelFunc) -> TopLevelFunc { return x } // expected-error {{use of undeclared type 'TopLevelFunc'}}'
41-
func TopLevelGenericFunc<TopLevelGenericFunc : TopLevelGenericFunc>(x: TopLevelGenericFunc) -> TopLevelGenericFunc { return x } // expected-error {{use of undeclared type 'TopLevelGenericFunc'}}'
41+
func TopLevelGenericFunc<TopLevelGenericFunc : TopLevelGenericFunc>(x: TopLevelGenericFunc) -> TopLevelGenericFunc { return x } // expected-error {{inheritance from non-protocol, non-class type 'TopLevelGenericFunc'}}
4242
func TopLevelGenericFunc2<T : TopLevelGenericFunc2>(x: T) -> T { return x} // expected-error {{use of undeclared type 'TopLevelGenericFunc2'}}
4343
var TopLevelVar: TopLevelVar? { return nil } // expected-error 2 {{use of undeclared type 'TopLevelVar'}}

0 commit comments

Comments
 (0)